From ead7803d60177f3a1880b4365dd7404a178a3880 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 8 Jan 2026 16:16:27 -0800 Subject: [PATCH] Simplify importing of C++ global variables. (#6565) Remove the unnecessary two-phase creation of variables in C++ import. We don't need to create a placeholder and overwrite it here, so stop doing so. Also, add the patterns to the imports table and don't create a NameBindingDecl. The NameBindingDecl would never be used for anything. This matches what we do when importing a Carbon variable, and improves the formatted SemIR output. --- toolchain/check/cpp/import.cpp | 44 +++++++-------- .../basics/raw_sem_ir/cpp_interop.carbon | 55 +++++++++---------- .../testdata/interop/cpp/class/access.carbon | 6 ++ .../testdata/interop/cpp/class/class.carbon | 2 + .../testdata/interop/cpp/class/union.carbon | 2 + .../interop/cpp/function/extern_c.carbon | 3 + .../check/testdata/interop/cpp/globals.carbon | 9 +++ .../check/testdata/interop/cpp/macros.carbon | 2 + .../interop/cpp/template/var_template.carbon | 10 ++++ 9 files changed, 82 insertions(+), 51 deletions(-) diff --git a/toolchain/check/cpp/import.cpp b/toolchain/check/cpp/import.cpp index 45cd5d51b921..fc7ec9a2264e 100644 --- a/toolchain/check/cpp/import.cpp +++ b/toolchain/check/cpp/import.cpp @@ -1622,40 +1622,40 @@ static auto ImportVarDecl(Context& context, SemIR::LocId loc_id, } SemIR::NameId var_name_id = AddIdentifierName(context, var_decl->getName()); - SemIR::VarStorage var_storage{.type_id = var_type_id, - .pattern_id = SemIR::InstId::None}; - // We can't use the convenience for `AddPlaceholderInstInNoBlock()` with typed - // nodes because it doesn't support insts with cleanup. - SemIR::InstId var_storage_inst_id = - AddPlaceholderImportedInstInNoBlock(context, {loc_id, var_storage}); - - auto clang_decl_id = context.clang_decls().Add( - {.key = SemIR::ClangDeclKey(var_decl), .inst_id = var_storage_inst_id}); - - // Entity name referring to a Clang decl for mangling. + // Create an entity name to identify this variable. SemIR::EntityNameId entity_name_id = context.entity_names().AddSymbolicBindingName( var_name_id, GetParentNameScopeId(context, var_decl), SemIR::CompileTimeBindIndex::None, false); - context.cpp_global_names().Add({.key = {.entity_name_id = entity_name_id}, - .clang_decl_id = clang_decl_id}); - // Create `RefBindingPattern` and `VarPattern` in a `NameBindingDecl`. - context.pattern_block_stack().Push(); + // Create `RefBindingPattern` and `VarPattern`. Mirror the behavior of + // import_ref and don't create a `NameBindingDecl` here; we'd never use it for + // anything. SemIR::TypeId pattern_type_id = GetPatternType(context, var_type_id); SemIR::InstId binding_pattern_inst_id = - AddPatternInst( + AddInstInNoBlock( context, loc_id, {.type_id = pattern_type_id, .entity_name_id = entity_name_id}); - var_storage.pattern_id = AddPatternInst( + context.imports().push_back(binding_pattern_inst_id); + auto pattern_id = AddInstInNoBlock( context, Parse::VariablePatternId::None, {.type_id = pattern_type_id, .subpattern_id = binding_pattern_inst_id}); - context.imports().push_back(AddInstInNoBlock( - context, loc_id, - {.pattern_block_id = context.pattern_block_stack().Pop()})); + context.imports().push_back(pattern_id); - // Finalize the `VarStorage` instruction. - ReplaceInstBeforeConstantUse(context, var_storage_inst_id, var_storage); + // Create the imported storage for the global. We intentionally use the + // untyped form of `AddInstInNoBlock` to bypass the check on adding an + // instruction that requires a cleanup, because we don't want a cleanup here! + SemIR::InstId var_storage_inst_id = AddInstInNoBlock( + context, {loc_id, SemIR::VarStorage{.type_id = var_type_id, + .pattern_id = pattern_id}}); + context.imports().push_back(var_storage_inst_id); + + // Register the variable so we don't create it again, and track the + // corresponding declaration to use for mangling. + auto clang_decl_id = context.clang_decls().Add( + {.key = SemIR::ClangDeclKey(var_decl), .inst_id = var_storage_inst_id}); + context.cpp_global_names().Add({.key = {.entity_name_id = entity_name_id}, + .clang_decl_id = clang_decl_id}); // Inform Clang that the variable has been referenced. context.clang_sema().MarkVariableReferenced(GetCppLocation(context, loc_id), diff --git a/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon b/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon index f40195333dda..f507f5b71f4e 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon @@ -50,10 +50,10 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: clang_decl_id60000004: {key: {decl: "extern void f__carbon_thunk()", num_params: 0}, inst_id: inst60000030} // CHECK:STDOUT: clang_decl_id60000005: {key: {decl: "void f(X x = {})", num_params: 1}, inst_id: inst6000003B} // CHECK:STDOUT: clang_decl_id60000006: {key: {decl: "extern void f__carbon_thunk(X * _Nonnull x)", num_params: 1}, inst_id: inst60000043} -// CHECK:STDOUT: clang_decl_id60000007: {key: "X * _Nonnull global", inst_id: inst6000004C} +// CHECK:STDOUT: clang_decl_id60000007: {key: "X * _Nonnull global", inst_id: inst6000004E} // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name(Cpp): inst60000011, name0: inst6000001D}} -// CHECK:STDOUT: name_scope60000001: {inst: inst60000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name2: inst60000014, name3: inst6000002A, name4: inst6000004C}} +// CHECK:STDOUT: name_scope60000001: {inst: inst60000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name2: inst60000014, name3: inst6000002A, name4: inst6000004E}} // CHECK:STDOUT: name_scope60000002: {inst: inst60000014, parent_scope: name_scope60000001, has_error: false, extended_scopes: [], names: {}} // CHECK:STDOUT: entity_names: // CHECK:STDOUT: entity_name60000000: {name: name1, parent_scope: name_scope, index: -1, is_template: 0} @@ -190,18 +190,17 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: inst60000049: {kind: NameRef, arg0: name(Cpp), arg1: inst60000011, type: type(inst(NamespaceType))} // CHECK:STDOUT: inst6000004A: {kind: NameRef, arg0: name3, arg1: inst6000002A, type: type(inst60000029)} // CHECK:STDOUT: inst6000004B: {kind: NameRef, arg0: name(Cpp), arg1: inst60000011, type: type(inst(NamespaceType))} -// CHECK:STDOUT: inst6000004C: {kind: VarStorage, arg0: inst6000004E, type: type(inst60000020)} -// CHECK:STDOUT: inst6000004D: {kind: RefBindingPattern, arg0: entity_name60000003, type: type(inst6000003F)} -// CHECK:STDOUT: inst6000004E: {kind: VarPattern, arg0: inst6000004D, type: type(inst6000003F)} -// CHECK:STDOUT: inst6000004F: {kind: NameBindingDecl, arg0: inst_block60000017} -// CHECK:STDOUT: inst60000050: {kind: NameRef, arg0: name4, arg1: inst6000004C, type: type(inst60000020)} -// CHECK:STDOUT: inst60000051: {kind: AcquireValue, arg0: inst60000050, type: type(inst60000020)} -// CHECK:STDOUT: inst60000052: {kind: Deref, arg0: inst60000051, type: type(inst60000015)} -// CHECK:STDOUT: inst60000053: {kind: AcquireValue, arg0: inst60000052, type: type(inst60000015)} -// CHECK:STDOUT: inst60000054: {kind: ValueAsRef, arg0: inst60000053, type: type(inst60000015)} -// CHECK:STDOUT: inst60000055: {kind: AddrOf, arg0: inst60000054, type: type(inst60000020)} -// CHECK:STDOUT: inst60000056: {kind: Call, arg0: inst60000043, arg1: inst_block60000019, type: type(inst60000013)} -// CHECK:STDOUT: inst60000057: {kind: Return} +// CHECK:STDOUT: inst6000004C: {kind: RefBindingPattern, arg0: entity_name60000003, type: type(inst6000003F)} +// CHECK:STDOUT: inst6000004D: {kind: VarPattern, arg0: inst6000004C, type: type(inst6000003F)} +// CHECK:STDOUT: inst6000004E: {kind: VarStorage, arg0: inst6000004D, type: type(inst60000020)} +// CHECK:STDOUT: inst6000004F: {kind: NameRef, arg0: name4, arg1: inst6000004E, type: type(inst60000020)} +// CHECK:STDOUT: inst60000050: {kind: AcquireValue, arg0: inst6000004F, type: type(inst60000020)} +// CHECK:STDOUT: inst60000051: {kind: Deref, arg0: inst60000050, type: type(inst60000015)} +// CHECK:STDOUT: inst60000052: {kind: AcquireValue, arg0: inst60000051, type: type(inst60000015)} +// CHECK:STDOUT: inst60000053: {kind: ValueAsRef, arg0: inst60000052, type: type(inst60000015)} +// CHECK:STDOUT: inst60000054: {kind: AddrOf, arg0: inst60000053, type: type(inst60000020)} +// CHECK:STDOUT: inst60000055: {kind: Call, arg0: inst60000043, arg1: inst_block60000018, type: type(inst60000013)} +// CHECK:STDOUT: inst60000056: {kind: Return} // CHECK:STDOUT: constant_values: // CHECK:STDOUT: values: // CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType)) @@ -271,7 +270,7 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: inst6000004C: concrete_constant(inst6000004C) // CHECK:STDOUT: inst6000004D: concrete_constant(inst6000004D) // CHECK:STDOUT: inst6000004E: concrete_constant(inst6000004E) -// CHECK:STDOUT: inst60000050: concrete_constant(inst6000004C) +// CHECK:STDOUT: inst6000004F: concrete_constant(inst6000004E) // CHECK:STDOUT: symbolic_constants: {} // CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: inst_block_empty: {} @@ -286,7 +285,8 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: 5: inst6000003B // CHECK:STDOUT: 6: inst60000043 // CHECK:STDOUT: 7: inst6000004C -// CHECK:STDOUT: 8: inst6000004F +// CHECK:STDOUT: 8: inst6000004D +// CHECK:STDOUT: 9: inst6000004E // CHECK:STDOUT: global_init: {} // CHECK:STDOUT: inst_block60000004: // CHECK:STDOUT: 0: inst60000012 @@ -315,14 +315,14 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: 9: inst60000049 // CHECK:STDOUT: 10: inst6000004A // CHECK:STDOUT: 11: inst6000004B -// CHECK:STDOUT: 12: inst60000050 -// CHECK:STDOUT: 13: inst60000051 -// CHECK:STDOUT: 14: inst60000052 -// CHECK:STDOUT: 15: inst60000053 -// CHECK:STDOUT: 16: inst60000054 -// CHECK:STDOUT: 17: inst60000055 -// CHECK:STDOUT: 18: inst60000056 -// CHECK:STDOUT: 19: inst60000057 +// CHECK:STDOUT: 12: inst6000004F +// CHECK:STDOUT: 13: inst60000050 +// CHECK:STDOUT: 14: inst60000051 +// CHECK:STDOUT: 15: inst60000052 +// CHECK:STDOUT: 16: inst60000053 +// CHECK:STDOUT: 17: inst60000054 +// CHECK:STDOUT: 18: inst60000055 +// CHECK:STDOUT: 19: inst60000056 // CHECK:STDOUT: inst_block6000000A: // CHECK:STDOUT: 0: inst60000022 // CHECK:STDOUT: 1: inst60000023 @@ -354,13 +354,10 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: inst_block60000016: // CHECK:STDOUT: 0: inst60000047 // CHECK:STDOUT: inst_block60000017: -// CHECK:STDOUT: 0: inst6000004D -// CHECK:STDOUT: 1: inst6000004E +// CHECK:STDOUT: 0: inst60000052 // CHECK:STDOUT: inst_block60000018: -// CHECK:STDOUT: 0: inst60000053 +// CHECK:STDOUT: 0: inst60000054 // CHECK:STDOUT: inst_block60000019: -// CHECK:STDOUT: 0: inst60000055 -// CHECK:STDOUT: inst_block6000001A: // CHECK:STDOUT: 0: instF // CHECK:STDOUT: 1: inst60000010 // CHECK:STDOUT: 2: inst6000001D diff --git a/toolchain/check/testdata/interop/cpp/class/access.carbon b/toolchain/check/testdata/interop/cpp/class/access.carbon index 54d5419fdf7e..8dbdc91a885b 100644 --- a/toolchain/check/testdata/interop/cpp/class/access.carbon +++ b/toolchain/check/testdata/interop/cpp/class/access.carbon @@ -1597,6 +1597,8 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %static_data.patt: %pattern_type.7ce = ref_binding_pattern static_data [concrete] +// CHECK:STDOUT: %static_data.var_patt: %pattern_type.7ce = var_pattern %static_data.patt [concrete] // CHECK:STDOUT: %static_data.var: ref %i32 = var %static_data.var_patt // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1642,6 +1644,8 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { +// CHECK:STDOUT: %static_data.patt: %pattern_type.7ce = ref_binding_pattern static_data [concrete] +// CHECK:STDOUT: %static_data.var_patt: %pattern_type.7ce = var_pattern %static_data.patt [concrete] // CHECK:STDOUT: %static_data.var: ref %i32 = var %static_data.var_patt // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1693,6 +1697,8 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %static_data.patt: %pattern_type.7ce = ref_binding_pattern static_data [concrete] +// CHECK:STDOUT: %static_data.var_patt: %pattern_type.7ce = var_pattern %static_data.patt [concrete] // CHECK:STDOUT: %static_data.var: ref %i32 = var %static_data.var_patt // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/class/class.carbon b/toolchain/check/testdata/interop/cpp/class/class.carbon index 34ba95819c9a..8cd02c03933b 100644 --- a/toolchain/check/testdata/interop/cpp/class/class.carbon +++ b/toolchain/check/testdata/interop/cpp/class/class.carbon @@ -373,6 +373,8 @@ fn MyF(bar: Cpp.Bar(Cpp.X)*); // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {} +// CHECK:STDOUT: %foo.patt: %pattern_type = ref_binding_pattern foo [concrete] +// CHECK:STDOUT: %foo.var_patt: %pattern_type = var_pattern %foo.patt [concrete] // CHECK:STDOUT: %foo.var: ref %ptr.f68 = var %foo.var_patt // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/class/union.carbon b/toolchain/check/testdata/interop/cpp/class/union.carbon index 4aa97ff0e086..28504f4709f4 100644 --- a/toolchain/check/testdata/interop/cpp/class/union.carbon +++ b/toolchain/check/testdata/interop/cpp/class/union.carbon @@ -322,6 +322,8 @@ fn MyF(bar: Cpp.Bar(Cpp.X)*); // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {} +// CHECK:STDOUT: %foo.patt: %pattern_type = ref_binding_pattern foo [concrete] +// CHECK:STDOUT: %foo.var_patt: %pattern_type = var_pattern %foo.patt [concrete] // CHECK:STDOUT: %foo.var: ref %ptr.f68 = var %foo.var_patt // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/function/extern_c.carbon b/toolchain/check/testdata/interop/cpp/function/extern_c.carbon index d72ddf47e24d..6c171b568b28 100644 --- a/toolchain/check/testdata/interop/cpp/function/extern_c.carbon +++ b/toolchain/check/testdata/interop/cpp/function/extern_c.carbon @@ -166,6 +166,7 @@ fn MyF(a: Cpp.X, b: Cpp.X) -> Cpp.X { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] // CHECK:STDOUT: %Int.as.Copy.impl.Op.type.824: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic] @@ -183,6 +184,8 @@ fn MyF(a: Cpp.X, b: Cpp.X) -> Cpp.X { // CHECK:STDOUT: .foo = %foo.var // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } +// CHECK:STDOUT: %foo.patt: %pattern_type.7ce = ref_binding_pattern foo [concrete] +// CHECK:STDOUT: %foo.var_patt: %pattern_type.7ce = var_pattern %foo.patt [concrete] // CHECK:STDOUT: %foo.var: ref %i32 = var %foo.var_patt [concrete] // CHECK:STDOUT: %Core.import_ref.18d: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.824) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.9b9)] // CHECK:STDOUT: %Copy.impl_witness_table.e76 = impl_witness_table (%Core.import_ref.18d), @Int.as.Copy.impl [concrete] diff --git a/toolchain/check/testdata/interop/cpp/globals.carbon b/toolchain/check/testdata/interop/cpp/globals.carbon index 8c6cb4b2d73d..2704cb9bafc6 100644 --- a/toolchain/check/testdata/interop/cpp/globals.carbon +++ b/toolchain/check/testdata/interop/cpp/globals.carbon @@ -102,6 +102,7 @@ fn MyF() { // CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete] // CHECK:STDOUT: %pattern_type.a31: type = pattern_type %ptr.d9e [concrete] // CHECK:STDOUT: %const: type = const_type %ptr.d9e [concrete] +// CHECK:STDOUT: %pattern_type.8ca: type = pattern_type %const [concrete] // CHECK:STDOUT: %global_ref.var: ref %ptr.d9e = var imports.%global_ref.var_patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -118,8 +119,14 @@ fn MyF() { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %global.patt: %pattern_type.217 = ref_binding_pattern global [concrete] +// CHECK:STDOUT: %global.var_patt: %pattern_type.217 = var_pattern %global.patt [concrete] // CHECK:STDOUT: %global.var: ref %C = var %global.var_patt [concrete] +// CHECK:STDOUT: %global_ptr.patt: %pattern_type.a31 = ref_binding_pattern global_ptr [concrete] +// CHECK:STDOUT: %global_ptr.var_patt: %pattern_type.a31 = var_pattern %global_ptr.patt [concrete] // CHECK:STDOUT: %global_ptr.var: ref %ptr.d9e = var %global_ptr.var_patt [concrete] +// CHECK:STDOUT: %global_ref.patt: %pattern_type.8ca = ref_binding_pattern global_ref [concrete] +// CHECK:STDOUT: %global_ref.var_patt: %pattern_type.8ca = var_pattern %global_ref.patt [concrete] // CHECK:STDOUT: %global_ref.var: ref %const = var %global_ref.var_patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -213,6 +220,8 @@ fn MyF() { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %global.patt: %pattern_type = ref_binding_pattern global [concrete] +// CHECK:STDOUT: %global.var_patt: %pattern_type = var_pattern %global.patt [concrete] // CHECK:STDOUT: %global.var: ref %C = var %global.var_patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/macros.carbon b/toolchain/check/testdata/interop/cpp/macros.carbon index 2e36f390ad01..2fbd2c590ca1 100644 --- a/toolchain/check/testdata/interop/cpp/macros.carbon +++ b/toolchain/check/testdata/interop/cpp/macros.carbon @@ -1023,6 +1023,8 @@ fn F() { // CHECK:STDOUT: .n = %n.var // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } +// CHECK:STDOUT: %n.patt: %pattern_type.201 = ref_binding_pattern n [concrete] +// CHECK:STDOUT: %n.var_patt: %pattern_type.201 = var_pattern %n.patt [concrete] // CHECK:STDOUT: %n.var: ref %f32.97e = var %n.var_patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/template/var_template.carbon b/toolchain/check/testdata/interop/cpp/template/var_template.carbon index f0cdf45ed99b..1d8180656166 100644 --- a/toolchain/check/testdata/interop/cpp/template/var_template.carbon +++ b/toolchain/check/testdata/interop/cpp/template/var_template.carbon @@ -42,10 +42,12 @@ let pwb: Cpp.B* = &Cpp.Wrap.r#var(Cpp.B); // CHECK:STDOUT: %pattern_type.bcf: type = pattern_type %ptr.270 [concrete] // CHECK:STDOUT: %var.type.230: type = cpp_type_template_type r#var [concrete] // CHECK:STDOUT: %var.template.326: %var.type.230 = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.9de: type = pattern_type %A [concrete] // CHECK:STDOUT: %addr.0b0: %ptr.270 = addr_of imports.%var.var.2f7 [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %ptr.a04: type = ptr_type %B [concrete] // CHECK:STDOUT: %pattern_type.837: type = pattern_type %ptr.a04 [concrete] +// CHECK:STDOUT: %pattern_type.d0f: type = pattern_type %B [concrete] // CHECK:STDOUT: %addr.324: %ptr.a04 = addr_of imports.%var.var.a15 [concrete] // CHECK:STDOUT: %Wrap: type = class_type @Wrap [concrete] // CHECK:STDOUT: %var.type.17b: type = cpp_type_template_type r#var [concrete] @@ -62,12 +64,20 @@ let pwb: Cpp.B* = &Cpp.Wrap.r#var(Cpp.B); // CHECK:STDOUT: } // CHECK:STDOUT: %A.decl: type = class_decl @A [concrete = constants.%A] {} {} // CHECK:STDOUT: %var.template.326: %var.type.230 = struct_value () [concrete = constants.%var.template.326] +// CHECK:STDOUT: %var.patt.5a2: %pattern_type.9de = ref_binding_pattern r#var [concrete] +// CHECK:STDOUT: %var.var_patt.093: %pattern_type.9de = var_pattern %var.patt.5a2 [concrete] // CHECK:STDOUT: %var.var.2f7: ref %A = var %var.var_patt.093 [concrete] // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: %var.patt.7db: %pattern_type.d0f = ref_binding_pattern r#var [concrete] +// CHECK:STDOUT: %var.var_patt.56c: %pattern_type.d0f = var_pattern %var.patt.7db [concrete] // CHECK:STDOUT: %var.var.a15: ref %B = var %var.var_patt.56c [concrete] // CHECK:STDOUT: %Wrap.decl: type = class_decl @Wrap [concrete = constants.%Wrap] {} {} // CHECK:STDOUT: %var.template.df3: %var.type.17b = struct_value () [concrete = constants.%var.template.df3] +// CHECK:STDOUT: %var.patt.022: %pattern_type.9de = ref_binding_pattern r#var [concrete] +// CHECK:STDOUT: %var.var_patt.0cb: %pattern_type.9de = var_pattern %var.patt.022 [concrete] // CHECK:STDOUT: %var.var.2e6: ref %A = var %var.var_patt.0cb +// CHECK:STDOUT: %var.patt.605: %pattern_type.d0f = ref_binding_pattern r#var [concrete] +// CHECK:STDOUT: %var.var_patt.efb: %pattern_type.d0f = var_pattern %var.patt.605 [concrete] // CHECK:STDOUT: %var.var.bab: ref %B = var %var.var_patt.efb // CHECK:STDOUT: } // CHECK:STDOUT: