From ffefa7711c16eaba4a99d6a237d838ce2eca700e Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Wed, 15 Oct 2025 15:33:32 +0200 Subject: [PATCH] Move the mapping from entity name to an imported C++ global variable declaration outside of `EntityName` (#6211) This would save space for every `EntityName` that is not an imported C++ global variable. C++ global variables include static data members. Created `CppGlobalVarId`, `CppGlobalVarKey` and `CppGlobalVar` to allow having `CanonicalValueStore` that maps `EntityNameId` (which is in `CppGlobalVarKey` and `CppGlobalVar`) to `ClangDeclId` (which is also in `CppGlobalVar`). This is similar to `ClangDeclId`, `ClangDeclKey` and `ClangDecl` . --- toolchain/check/context.h | 3 + toolchain/check/cpp/import.cpp | 4 +- .../basics/raw_sem_ir/builtins.carbon | 1 + .../basics/raw_sem_ir/cpp_interop.carbon | 283 +++++++++++------- .../basics/raw_sem_ir/multifile.carbon | 4 +- .../multifile_with_textual_ir.carbon | 4 +- .../basics/raw_sem_ir/one_file.carbon | 125 ++++---- .../one_file_with_textual_ir.carbon | 3 +- toolchain/driver/testdata/stdin.carbon | 1 + toolchain/lower/BUILD | 1 + toolchain/lower/mangler.cpp | 13 +- toolchain/sem_ir/BUILD | 1 + toolchain/sem_ir/cpp_global_var.h | 71 +++++ toolchain/sem_ir/entity_name.h | 12 +- toolchain/sem_ir/file.cpp | 3 + toolchain/sem_ir/file.h | 8 + toolchain/sem_ir/ids.h | 7 + toolchain/sem_ir/yaml_test.cpp | 1 + 18 files changed, 354 insertions(+), 191 deletions(-) create mode 100644 toolchain/sem_ir/cpp_global_var.h diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 07e4ae427f57..9e7640cce83c 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -255,6 +255,9 @@ class Context { auto entity_names() -> SemIR::EntityNameStore& { return sem_ir().entity_names(); } + auto cpp_global_names() -> SemIR::CppGlobalVarStore& { + return sem_ir().cpp_global_vars(); + } auto cpp_overload_sets() -> SemIR::CppOverloadSetStore& { return sem_ir().cpp_overload_sets(); } diff --git a/toolchain/check/cpp/import.cpp b/toolchain/check/cpp/import.cpp index e6d461f07969..91220eacac1c 100644 --- a/toolchain/check/cpp/import.cpp +++ b/toolchain/check/cpp/import.cpp @@ -1853,7 +1853,9 @@ static auto ImportVarDecl(Context& context, SemIR::LocId loc_id, SemIR::EntityNameId entity_name_id = context.entity_names().AddSymbolicBindingName( var_name_id, GetParentNameScopeId(context, var_decl), - SemIR::CompileTimeBindIndex::None, false, clang_decl_id); + SemIR::CompileTimeBindIndex::None, false); + context.cpp_global_names().Add({.key = {.entity_name_id = entity_name_id}, + .clang_decl_id = clang_decl_id}); // Create `BindingPattern` and `VarPattern` in a `NameBindingDecl`. context.pattern_block_stack().Push(); diff --git a/toolchain/check/testdata/basics/raw_sem_ir/builtins.carbon b/toolchain/check/testdata/basics/raw_sem_ir/builtins.carbon index eb7fa2706edb..d27ad7630119 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/builtins.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/builtins.carbon @@ -22,6 +22,7 @@ // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {}} // CHECK:STDOUT: entity_names: {} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: {} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} 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 b57be69db2f8..14973de22009 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon @@ -14,12 +14,14 @@ // --- header.h struct X { - X *p; + X* _Nonnull p; }; void f(X x = {}) { } +X* _Nonnull global; + // --- import.carbon import Cpp library "header.h"; @@ -27,6 +29,7 @@ import Cpp library "header.h"; fn G(x: Cpp.X) { Cpp.f(); Cpp.f(x); + Cpp.f(*Cpp.global); } // CHECK:STDOUT: --- @@ -42,30 +45,39 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: clang_decls: // CHECK:STDOUT: clang_decl_id0: {key: "", inst_id: inst60000010} // CHECK:STDOUT: clang_decl_id1: {key: "struct X {}", inst_id: inst60000012} -// CHECK:STDOUT: clang_decl_id2: {key: {decl: "void f(X x = {})", num_params: 0}, inst_id: inst60000029} -// CHECK:STDOUT: clang_decl_id3: {key: {decl: "extern void f__carbon_thunk()", num_params: 0}, inst_id: inst6000002C} -// CHECK:STDOUT: clang_decl_id4: {key: {decl: "void f(X x = {})", num_params: 1}, inst_id: inst60000037} -// CHECK:STDOUT: clang_decl_id5: {key: {decl: "extern void f__carbon_thunk(X * _Nonnull x)", num_params: 1}, inst_id: inst60000040} +// CHECK:STDOUT: clang_decl_id2: {key: "X * _Nonnull p", inst_id: inst60000021} +// CHECK:STDOUT: clang_decl_id3: {key: {decl: "void f(X x = {})", num_params: 0}, inst_id: inst6000002C} +// CHECK:STDOUT: clang_decl_id4: {key: {decl: "extern void f__carbon_thunk()", num_params: 0}, inst_id: inst6000002F} +// CHECK:STDOUT: clang_decl_id5: {key: {decl: "void f(X x = {})", num_params: 1}, inst_id: inst6000003A} +// CHECK:STDOUT: clang_decl_id6: {key: {decl: "extern void f__carbon_thunk(X * _Nonnull x)", num_params: 1}, inst_id: inst60000042} +// CHECK:STDOUT: clang_decl_id7: {key: "X * _Nonnull global", inst_id: inst6000004B} // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name0: inst60000010, name1: inst6000001B}} -// CHECK:STDOUT: name_scope1: {inst: inst60000010, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name3: inst60000012, name4: inst60000026}} +// CHECK:STDOUT: name_scope1: {inst: inst60000010, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name3: inst60000012, name4: inst60000029, name5: inst6000004B}} // CHECK:STDOUT: name_scope2: {inst: inst60000012, parent_scope: name_scope1, has_error: false, extended_scopes: [], names: {}} // CHECK:STDOUT: entity_names: -// CHECK:STDOUT: entity_name0: {name: name2, parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name1: {name: name2, parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name2: {name: name2, parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} +// CHECK:STDOUT: entity_name0: {name: name2, parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name1: {name: name2, parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name2: {name: name2, parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name3: {name: name5, parent_scope: name_scope1, index: -1, is_template: 0} +// CHECK:STDOUT: cpp_global_vars: +// CHECK:STDOUT: cpp_global_var0: {key: {entity_name_id: entity_name3}, clang_decl_id: clang_decl_id7} // CHECK:STDOUT: functions: // CHECK:STDOUT: function60000000: {name: name1, parent_scope: name_scope0, call_params_id: inst_block6, body: [inst_block9]} // CHECK:STDOUT: function60000001: {name: name4, parent_scope: name_scope1, call_params_id: inst_block_empty} -// CHECK:STDOUT: function60000002: {name: name6, parent_scope: name_scope1, call_params_id: inst_block_empty} +// CHECK:STDOUT: function60000002: {name: name7, parent_scope: name_scope1, call_params_id: inst_block_empty} // CHECK:STDOUT: function60000003: {name: name4, parent_scope: name_scope1, call_params_id: inst_block13} -// CHECK:STDOUT: function60000004: {name: name6, parent_scope: name_scope1, call_params_id: inst_block18} +// CHECK:STDOUT: function60000004: {name: name7, parent_scope: name_scope1, call_params_id: inst_block18} // CHECK:STDOUT: classes: -// CHECK:STDOUT: class60000000: {name: name3, parent_scope: name_scope1, self_type_id: type(inst60000013), inheritance_kind: Base, is_dynamic: 0, scope_id: name_scope2, body_block_id: inst_block10, adapt_id: inst, base_id: inst, complete_type_witness_id: inst60000021, vtable_decl_id: inst}} +// CHECK:STDOUT: class60000000: {name: name3, parent_scope: name_scope1, self_type_id: type(inst60000013), inheritance_kind: Base, is_dynamic: 0, scope_id: name_scope2, body_block_id: inst_block10, adapt_id: inst, base_id: inst, complete_type_witness_id: inst60000024, vtable_decl_id: inst}} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} +// CHECK:STDOUT: struct_type_fields1: +// CHECK:STDOUT: 0: {name_id: name6, type_inst_id: inst6000001F} +// CHECK:STDOUT: struct_type_fields2: +// CHECK:STDOUT: 0: {name_id: name6, type_inst_id: inst6000001F} // CHECK:STDOUT: types: // CHECK:STDOUT: 'type(TypeType)': // CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} @@ -79,24 +91,24 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} // CHECK:STDOUT: 'type(inst(WitnessType))': // CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(WitnessType))} -// CHECK:STDOUT: 'type(inst60000020)': -// CHECK:STDOUT: value_repr: {kind: pointer, type: type(inst60000023)} +// CHECK:STDOUT: 'type(inst6000001F)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst6000001F)} // CHECK:STDOUT: 'type(inst60000023)': -// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst60000023)} +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(inst60000026)} +// CHECK:STDOUT: 'type(inst60000026)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst60000026)} // CHECK:STDOUT: 'type(inst60000013)': -// CHECK:STDOUT: value_repr: {kind: pointer, type: type(inst60000023)} -// CHECK:STDOUT: 'type(inst60000025)': -// CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} -// CHECK:STDOUT: 'type(inst6000002A)': +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(inst60000026)} +// CHECK:STDOUT: 'type(inst60000028)': // CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} // CHECK:STDOUT: 'type(inst6000002D)': // CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} -// CHECK:STDOUT: 'type(inst60000038)': +// CHECK:STDOUT: 'type(inst60000030)': // CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} -// CHECK:STDOUT: 'type(inst60000041)': +// CHECK:STDOUT: 'type(inst6000003B)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} +// CHECK:STDOUT: 'type(inst60000043)': // CHECK:STDOUT: value_repr: {kind: none, type: type(inst6000001D)} -// CHECK:STDOUT: 'type(inst6000003A)': -// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst6000003A)} // CHECK:STDOUT: insts: // CHECK:STDOUT: 'inst(TypeType)': {kind: TypeType, type: type(TypeType)} // CHECK:STDOUT: 'inst(AutoType)': {kind: AutoType, type: type(TypeType)} @@ -129,46 +141,62 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: inst6000001C: {kind: FunctionType, arg0: function60000000, arg1: specific, type: type(TypeType)} // CHECK:STDOUT: inst6000001D: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)} // CHECK:STDOUT: inst6000001E: {kind: StructValue, arg0: inst_block_empty, type: type(inst6000001C)} -// CHECK:STDOUT: inst6000001F: {kind: CustomLayoutType, arg0: struct_type_fields0, arg1: custom_layout1, type: type(TypeType)} -// CHECK:STDOUT: inst60000020: {kind: CustomLayoutType, arg0: struct_type_fields0, arg1: custom_layout1, type: type(TypeType)} -// CHECK:STDOUT: inst60000021: {kind: CompleteTypeWitness, arg0: inst6000001F, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst60000022: {kind: CompleteTypeWitness, arg0: inst60000020, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst60000023: {kind: PointerType, arg0: inst60000020, type: type(TypeType)} -// CHECK:STDOUT: inst60000024: {kind: NameRef, arg0: name0, arg1: inst60000010, type: type(inst(NamespaceType))} -// CHECK:STDOUT: inst60000025: {kind: CppOverloadSetType, arg0: cpp_overload_set60000000, arg1: specific, type: type(TypeType)} -// CHECK:STDOUT: inst60000026: {kind: CppOverloadSetValue, arg0: cpp_overload_set60000000, type: type(inst60000025)} -// CHECK:STDOUT: inst60000027: {kind: CppOverloadSetValue, arg0: cpp_overload_set60000000, type: type(inst60000025)} -// CHECK:STDOUT: inst60000028: {kind: NameRef, arg0: name4, arg1: inst60000026, type: type(inst60000025)} -// CHECK:STDOUT: inst60000029: {kind: FunctionDecl, arg0: function60000001, arg1: inst_block_empty, type: type(inst6000002A)} -// CHECK:STDOUT: inst6000002A: {kind: FunctionType, arg0: function60000001, arg1: specific, type: type(TypeType)} -// CHECK:STDOUT: inst6000002B: {kind: StructValue, arg0: inst_block_empty, type: type(inst6000002A)} -// CHECK:STDOUT: inst6000002C: {kind: FunctionDecl, arg0: function60000002, arg1: inst_block_empty, type: type(inst6000002D)} -// CHECK:STDOUT: inst6000002D: {kind: FunctionType, arg0: function60000002, arg1: specific, type: type(TypeType)} +// CHECK:STDOUT: inst6000001F: {kind: PointerType, arg0: inst60000013, type: type(TypeType)} +// CHECK:STDOUT: inst60000020: {kind: UnboundElementType, arg0: inst60000013, arg1: inst6000001F, type: type(TypeType)} +// CHECK:STDOUT: inst60000021: {kind: FieldDecl, arg0: name6, arg1: element0, type: type(inst60000020)} +// CHECK:STDOUT: inst60000022: {kind: CustomLayoutType, arg0: struct_type_fields1, arg1: custom_layout1, type: type(TypeType)} +// CHECK:STDOUT: inst60000023: {kind: CustomLayoutType, arg0: struct_type_fields2, arg1: custom_layout1, type: type(TypeType)} +// CHECK:STDOUT: inst60000024: {kind: CompleteTypeWitness, arg0: inst60000022, type: type(inst(WitnessType))} +// CHECK:STDOUT: inst60000025: {kind: CompleteTypeWitness, arg0: inst60000023, type: type(inst(WitnessType))} +// CHECK:STDOUT: inst60000026: {kind: PointerType, arg0: inst60000023, type: type(TypeType)} +// CHECK:STDOUT: inst60000027: {kind: NameRef, arg0: name0, arg1: inst60000010, type: type(inst(NamespaceType))} +// CHECK:STDOUT: inst60000028: {kind: CppOverloadSetType, arg0: cpp_overload_set60000000, arg1: specific, type: type(TypeType)} +// CHECK:STDOUT: inst60000029: {kind: CppOverloadSetValue, arg0: cpp_overload_set60000000, type: type(inst60000028)} +// CHECK:STDOUT: inst6000002A: {kind: CppOverloadSetValue, arg0: cpp_overload_set60000000, type: type(inst60000028)} +// CHECK:STDOUT: inst6000002B: {kind: NameRef, arg0: name4, arg1: inst60000029, type: type(inst60000028)} +// CHECK:STDOUT: inst6000002C: {kind: FunctionDecl, arg0: function60000001, arg1: inst_block_empty, type: type(inst6000002D)} +// CHECK:STDOUT: inst6000002D: {kind: FunctionType, arg0: function60000001, arg1: specific, type: type(TypeType)} // CHECK:STDOUT: inst6000002E: {kind: StructValue, arg0: inst_block_empty, type: type(inst6000002D)} -// CHECK:STDOUT: inst6000002F: {kind: Call, arg0: inst6000002C, arg1: inst_block_empty, type: type(inst6000001D)} -// CHECK:STDOUT: inst60000030: {kind: NameRef, arg0: name0, arg1: inst60000010, type: type(inst(NamespaceType))} -// CHECK:STDOUT: inst60000031: {kind: NameRef, arg0: name4, arg1: inst60000026, type: type(inst60000025)} -// CHECK:STDOUT: inst60000032: {kind: NameRef, arg0: name2, arg1: inst60000015, type: type(inst60000013)} -// CHECK:STDOUT: inst60000033: {kind: BindName, arg0: entity_name1, arg1: inst60000036, type: type(inst60000013)} -// CHECK:STDOUT: inst60000034: {kind: BindingPattern, arg0: entity_name1, type: type(inst60000016)} -// CHECK:STDOUT: inst60000035: {kind: ValueParamPattern, arg0: inst60000034, arg1: call_param0, type: type(inst60000016)} -// CHECK:STDOUT: inst60000036: {kind: ValueParam, arg0: call_param0, arg1: name2, type: type(inst60000013)} -// CHECK:STDOUT: inst60000037: {kind: FunctionDecl, arg0: function60000003, arg1: inst_block15, type: type(inst60000038)} -// CHECK:STDOUT: inst60000038: {kind: FunctionType, arg0: function60000003, arg1: specific, type: type(TypeType)} -// CHECK:STDOUT: inst60000039: {kind: StructValue, arg0: inst_block_empty, type: type(inst60000038)} -// CHECK:STDOUT: inst6000003A: {kind: PointerType, arg0: inst60000013, type: type(TypeType)} -// CHECK:STDOUT: inst6000003B: {kind: BindName, arg0: entity_name2, arg1: inst6000003F, type: type(inst6000003A)} -// CHECK:STDOUT: inst6000003C: {kind: PatternType, arg0: inst6000003A, type: type(TypeType)} -// CHECK:STDOUT: inst6000003D: {kind: BindingPattern, arg0: entity_name2, type: type(inst6000003C)} -// CHECK:STDOUT: inst6000003E: {kind: ValueParamPattern, arg0: inst6000003D, arg1: call_param0, type: type(inst6000003C)} -// CHECK:STDOUT: inst6000003F: {kind: ValueParam, arg0: call_param0, arg1: name2, type: type(inst6000003A)} -// CHECK:STDOUT: inst60000040: {kind: FunctionDecl, arg0: function60000004, arg1: inst_block20, type: type(inst60000041)} -// CHECK:STDOUT: inst60000041: {kind: FunctionType, arg0: function60000004, arg1: specific, type: type(TypeType)} -// CHECK:STDOUT: inst60000042: {kind: StructValue, arg0: inst_block_empty, type: type(inst60000041)} -// CHECK:STDOUT: inst60000043: {kind: ValueAsRef, arg0: inst60000032, type: type(inst60000013)} -// CHECK:STDOUT: inst60000044: {kind: AddrOf, arg0: inst60000043, type: type(inst6000003A)} -// CHECK:STDOUT: inst60000045: {kind: Call, arg0: inst60000040, arg1: inst_block22, type: type(inst6000001D)} -// CHECK:STDOUT: inst60000046: {kind: Return} +// CHECK:STDOUT: inst6000002F: {kind: FunctionDecl, arg0: function60000002, arg1: inst_block_empty, type: type(inst60000030)} +// CHECK:STDOUT: inst60000030: {kind: FunctionType, arg0: function60000002, arg1: specific, type: type(TypeType)} +// CHECK:STDOUT: inst60000031: {kind: StructValue, arg0: inst_block_empty, type: type(inst60000030)} +// CHECK:STDOUT: inst60000032: {kind: Call, arg0: inst6000002F, arg1: inst_block_empty, type: type(inst6000001D)} +// CHECK:STDOUT: inst60000033: {kind: NameRef, arg0: name0, arg1: inst60000010, type: type(inst(NamespaceType))} +// CHECK:STDOUT: inst60000034: {kind: NameRef, arg0: name4, arg1: inst60000029, type: type(inst60000028)} +// CHECK:STDOUT: inst60000035: {kind: NameRef, arg0: name2, arg1: inst60000015, type: type(inst60000013)} +// CHECK:STDOUT: inst60000036: {kind: BindName, arg0: entity_name1, arg1: inst60000039, type: type(inst60000013)} +// CHECK:STDOUT: inst60000037: {kind: BindingPattern, arg0: entity_name1, type: type(inst60000016)} +// CHECK:STDOUT: inst60000038: {kind: ValueParamPattern, arg0: inst60000037, arg1: call_param0, type: type(inst60000016)} +// CHECK:STDOUT: inst60000039: {kind: ValueParam, arg0: call_param0, arg1: name2, type: type(inst60000013)} +// CHECK:STDOUT: inst6000003A: {kind: FunctionDecl, arg0: function60000003, arg1: inst_block15, type: type(inst6000003B)} +// CHECK:STDOUT: inst6000003B: {kind: FunctionType, arg0: function60000003, arg1: specific, type: type(TypeType)} +// CHECK:STDOUT: inst6000003C: {kind: StructValue, arg0: inst_block_empty, type: type(inst6000003B)} +// CHECK:STDOUT: inst6000003D: {kind: BindName, arg0: entity_name2, arg1: inst60000041, type: type(inst6000001F)} +// CHECK:STDOUT: inst6000003E: {kind: PatternType, arg0: inst6000001F, type: type(TypeType)} +// CHECK:STDOUT: inst6000003F: {kind: BindingPattern, arg0: entity_name2, type: type(inst6000003E)} +// CHECK:STDOUT: inst60000040: {kind: ValueParamPattern, arg0: inst6000003F, arg1: call_param0, type: type(inst6000003E)} +// CHECK:STDOUT: inst60000041: {kind: ValueParam, arg0: call_param0, arg1: name2, type: type(inst6000001F)} +// CHECK:STDOUT: inst60000042: {kind: FunctionDecl, arg0: function60000004, arg1: inst_block20, type: type(inst60000043)} +// CHECK:STDOUT: inst60000043: {kind: FunctionType, arg0: function60000004, arg1: specific, type: type(TypeType)} +// CHECK:STDOUT: inst60000044: {kind: StructValue, arg0: inst_block_empty, type: type(inst60000043)} +// CHECK:STDOUT: inst60000045: {kind: ValueAsRef, arg0: inst60000035, type: type(inst60000013)} +// CHECK:STDOUT: inst60000046: {kind: AddrOf, arg0: inst60000045, type: type(inst6000001F)} +// CHECK:STDOUT: inst60000047: {kind: Call, arg0: inst60000042, arg1: inst_block22, type: type(inst6000001D)} +// CHECK:STDOUT: inst60000048: {kind: NameRef, arg0: name0, arg1: inst60000010, type: type(inst(NamespaceType))} +// CHECK:STDOUT: inst60000049: {kind: NameRef, arg0: name4, arg1: inst60000029, type: type(inst60000028)} +// CHECK:STDOUT: inst6000004A: {kind: NameRef, arg0: name0, arg1: inst60000010, type: type(inst(NamespaceType))} +// CHECK:STDOUT: inst6000004B: {kind: VarStorage, arg0: inst6000004D, type: type(inst6000001F)} +// CHECK:STDOUT: inst6000004C: {kind: BindingPattern, arg0: entity_name3, type: type(inst6000003E)} +// CHECK:STDOUT: inst6000004D: {kind: VarPattern, arg0: inst6000004C, type: type(inst6000003E)} +// CHECK:STDOUT: inst6000004E: {kind: NameBindingDecl, arg0: inst_block23} +// CHECK:STDOUT: inst6000004F: {kind: NameRef, arg0: name5, arg1: inst6000004B, type: type(inst6000001F)} +// CHECK:STDOUT: inst60000050: {kind: BindValue, arg0: inst6000004F, type: type(inst6000001F)} +// CHECK:STDOUT: inst60000051: {kind: Deref, arg0: inst60000050, type: type(inst60000013)} +// CHECK:STDOUT: inst60000052: {kind: BindValue, arg0: inst60000051, type: type(inst60000013)} +// CHECK:STDOUT: inst60000053: {kind: ValueAsRef, arg0: inst60000052, type: type(inst60000013)} +// CHECK:STDOUT: inst60000054: {kind: AddrOf, arg0: inst60000053, type: type(inst6000001F)} +// CHECK:STDOUT: inst60000055: {kind: Call, arg0: inst60000042, arg1: inst_block25, type: type(inst6000001D)} +// CHECK:STDOUT: inst60000056: {kind: Return} // CHECK:STDOUT: constant_values: // CHECK:STDOUT: values: // CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType)) @@ -199,36 +227,45 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: inst6000001C: concrete_constant(inst6000001C) // CHECK:STDOUT: inst6000001D: concrete_constant(inst6000001D) // CHECK:STDOUT: inst6000001E: concrete_constant(inst6000001E) -// CHECK:STDOUT: inst6000001F: concrete_constant(inst60000020) +// CHECK:STDOUT: inst6000001F: concrete_constant(inst6000001F) // CHECK:STDOUT: inst60000020: concrete_constant(inst60000020) -// CHECK:STDOUT: inst60000021: concrete_constant(inst60000022) -// CHECK:STDOUT: inst60000022: concrete_constant(inst60000022) +// CHECK:STDOUT: inst60000021: concrete_constant(inst60000021) +// CHECK:STDOUT: inst60000022: concrete_constant(inst60000023) // CHECK:STDOUT: inst60000023: concrete_constant(inst60000023) -// CHECK:STDOUT: inst60000024: concrete_constant(inst60000010) +// CHECK:STDOUT: inst60000024: concrete_constant(inst60000025) // CHECK:STDOUT: inst60000025: concrete_constant(inst60000025) -// CHECK:STDOUT: inst60000026: concrete_constant(inst60000027) -// CHECK:STDOUT: inst60000027: concrete_constant(inst60000027) -// CHECK:STDOUT: inst60000028: concrete_constant(inst60000027) -// CHECK:STDOUT: inst60000029: concrete_constant(inst6000002B) +// CHECK:STDOUT: inst60000026: concrete_constant(inst60000026) +// CHECK:STDOUT: inst60000027: concrete_constant(inst60000010) +// CHECK:STDOUT: inst60000028: concrete_constant(inst60000028) +// CHECK:STDOUT: inst60000029: concrete_constant(inst6000002A) // CHECK:STDOUT: inst6000002A: concrete_constant(inst6000002A) -// CHECK:STDOUT: inst6000002B: concrete_constant(inst6000002B) +// CHECK:STDOUT: inst6000002B: concrete_constant(inst6000002A) // CHECK:STDOUT: inst6000002C: concrete_constant(inst6000002E) // CHECK:STDOUT: inst6000002D: concrete_constant(inst6000002D) // CHECK:STDOUT: inst6000002E: concrete_constant(inst6000002E) -// CHECK:STDOUT: inst60000030: concrete_constant(inst60000010) -// CHECK:STDOUT: inst60000031: concrete_constant(inst60000027) -// CHECK:STDOUT: inst60000034: concrete_constant(inst60000034) -// CHECK:STDOUT: inst60000035: concrete_constant(inst60000035) -// CHECK:STDOUT: inst60000037: concrete_constant(inst60000039) +// CHECK:STDOUT: inst6000002F: concrete_constant(inst60000031) +// CHECK:STDOUT: inst60000030: concrete_constant(inst60000030) +// CHECK:STDOUT: inst60000031: concrete_constant(inst60000031) +// CHECK:STDOUT: inst60000033: concrete_constant(inst60000010) +// CHECK:STDOUT: inst60000034: concrete_constant(inst6000002A) +// CHECK:STDOUT: inst60000037: concrete_constant(inst60000037) // CHECK:STDOUT: inst60000038: concrete_constant(inst60000038) -// CHECK:STDOUT: inst60000039: concrete_constant(inst60000039) -// CHECK:STDOUT: inst6000003A: concrete_constant(inst6000003A) +// CHECK:STDOUT: inst6000003A: concrete_constant(inst6000003C) +// CHECK:STDOUT: inst6000003B: concrete_constant(inst6000003B) // CHECK:STDOUT: inst6000003C: concrete_constant(inst6000003C) -// CHECK:STDOUT: inst6000003D: concrete_constant(inst6000003D) // CHECK:STDOUT: inst6000003E: concrete_constant(inst6000003E) -// CHECK:STDOUT: inst60000040: concrete_constant(inst60000042) -// CHECK:STDOUT: inst60000041: concrete_constant(inst60000041) -// CHECK:STDOUT: inst60000042: concrete_constant(inst60000042) +// CHECK:STDOUT: inst6000003F: concrete_constant(inst6000003F) +// CHECK:STDOUT: inst60000040: concrete_constant(inst60000040) +// CHECK:STDOUT: inst60000042: concrete_constant(inst60000044) +// CHECK:STDOUT: inst60000043: concrete_constant(inst60000043) +// CHECK:STDOUT: inst60000044: concrete_constant(inst60000044) +// CHECK:STDOUT: inst60000048: concrete_constant(inst60000010) +// CHECK:STDOUT: inst60000049: concrete_constant(inst6000002A) +// CHECK:STDOUT: inst6000004A: concrete_constant(inst60000010) +// CHECK:STDOUT: inst6000004B: concrete_constant(inst6000004B) +// CHECK:STDOUT: inst6000004C: concrete_constant(inst6000004C) +// CHECK:STDOUT: inst6000004D: concrete_constant(inst6000004D) +// CHECK:STDOUT: inst6000004F: concrete_constant(inst6000004B) // CHECK:STDOUT: symbolic_constants: {} // CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: inst_block_empty: {} @@ -237,11 +274,13 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: imports: // CHECK:STDOUT: 0: inst60000010 // CHECK:STDOUT: 1: inst60000012 -// CHECK:STDOUT: 2: inst60000026 -// CHECK:STDOUT: 3: inst60000029 -// CHECK:STDOUT: 4: inst6000002C -// CHECK:STDOUT: 5: inst60000037 -// CHECK:STDOUT: 6: inst60000040 +// CHECK:STDOUT: 2: inst60000029 +// CHECK:STDOUT: 3: inst6000002C +// CHECK:STDOUT: 4: inst6000002F +// CHECK:STDOUT: 5: inst6000003A +// CHECK:STDOUT: 6: inst60000042 +// CHECK:STDOUT: 7: inst6000004E +// CHECK:STDOUT: 8: inst6000004B // CHECK:STDOUT: global_init: {} // CHECK:STDOUT: inst_block4: // CHECK:STDOUT: 0: inst60000011 @@ -258,46 +297,64 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: 1: inst6000001A // CHECK:STDOUT: 2: inst60000015 // CHECK:STDOUT: inst_block9: -// CHECK:STDOUT: 0: inst60000024 -// CHECK:STDOUT: 1: inst60000028 -// CHECK:STDOUT: 2: inst6000002F -// CHECK:STDOUT: 3: inst60000030 -// CHECK:STDOUT: 4: inst60000031 -// CHECK:STDOUT: 5: inst60000032 -// CHECK:STDOUT: 6: inst60000043 -// CHECK:STDOUT: 7: inst60000044 -// CHECK:STDOUT: 8: inst60000045 -// CHECK:STDOUT: 9: inst60000046 +// CHECK:STDOUT: 0: inst60000027 +// CHECK:STDOUT: 1: inst6000002B +// CHECK:STDOUT: 2: inst60000032 +// CHECK:STDOUT: 3: inst60000033 +// CHECK:STDOUT: 4: inst60000034 +// CHECK:STDOUT: 5: inst60000035 +// CHECK:STDOUT: 6: inst60000045 +// CHECK:STDOUT: 7: inst60000046 +// CHECK:STDOUT: 8: inst60000047 +// CHECK:STDOUT: 9: inst60000048 +// CHECK:STDOUT: 10: inst60000049 +// CHECK:STDOUT: 11: inst6000004A +// 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_block10: -// CHECK:STDOUT: 0: inst6000001F -// CHECK:STDOUT: 1: inst60000021 +// CHECK:STDOUT: 0: inst60000021 +// CHECK:STDOUT: 1: inst60000022 +// CHECK:STDOUT: 2: inst60000024 // CHECK:STDOUT: inst_block11: {} // CHECK:STDOUT: inst_block12: -// CHECK:STDOUT: 0: inst60000035 +// CHECK:STDOUT: 0: inst60000038 // CHECK:STDOUT: inst_block13: -// CHECK:STDOUT: 0: inst60000036 +// CHECK:STDOUT: 0: inst60000039 // CHECK:STDOUT: inst_block14: -// CHECK:STDOUT: 0: inst60000034 -// CHECK:STDOUT: 1: inst60000035 +// CHECK:STDOUT: 0: inst60000037 +// CHECK:STDOUT: 1: inst60000038 // CHECK:STDOUT: inst_block15: -// CHECK:STDOUT: 0: inst60000036 -// CHECK:STDOUT: 1: inst60000033 +// CHECK:STDOUT: 0: inst60000039 +// CHECK:STDOUT: 1: inst60000036 // CHECK:STDOUT: inst_block16: {} // CHECK:STDOUT: inst_block17: -// CHECK:STDOUT: 0: inst6000003E +// CHECK:STDOUT: 0: inst60000040 // CHECK:STDOUT: inst_block18: -// CHECK:STDOUT: 0: inst6000003F +// CHECK:STDOUT: 0: inst60000041 // CHECK:STDOUT: inst_block19: -// CHECK:STDOUT: 0: inst6000003D -// CHECK:STDOUT: 1: inst6000003E -// CHECK:STDOUT: inst_block20: // CHECK:STDOUT: 0: inst6000003F -// CHECK:STDOUT: 1: inst6000003B +// CHECK:STDOUT: 1: inst60000040 +// CHECK:STDOUT: inst_block20: +// CHECK:STDOUT: 0: inst60000041 +// CHECK:STDOUT: 1: inst6000003D // CHECK:STDOUT: inst_block21: -// CHECK:STDOUT: 0: inst60000032 +// CHECK:STDOUT: 0: inst60000035 // CHECK:STDOUT: inst_block22: -// CHECK:STDOUT: 0: inst60000044 +// CHECK:STDOUT: 0: inst60000046 // CHECK:STDOUT: inst_block23: +// CHECK:STDOUT: 0: inst6000004C +// CHECK:STDOUT: 1: inst6000004D +// CHECK:STDOUT: inst_block24: +// CHECK:STDOUT: 0: inst60000052 +// CHECK:STDOUT: inst_block25: +// CHECK:STDOUT: 0: inst60000054 +// CHECK:STDOUT: inst_block26: // CHECK:STDOUT: 0: inst0000000E // CHECK:STDOUT: 1: inst6000000F // CHECK:STDOUT: 2: inst6000001B diff --git a/toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon b/toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon index 5d7009f721f5..c6f78c09a960 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon @@ -38,6 +38,7 @@ fn B() { // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name0: inst6000000F}} // CHECK:STDOUT: entity_names: {} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: // CHECK:STDOUT: function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block5]} // CHECK:STDOUT: classes: {} @@ -99,7 +100,8 @@ fn B() { // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name1: inst50000010, name0: inst50000011}} // CHECK:STDOUT: name_scope1: {inst: inst50000010, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst50000016}} // CHECK:STDOUT: entity_names: -// CHECK:STDOUT: entity_name0: {name: name1, parent_scope: name_scope1, index: -1, is_template: 0, clang_decl_id: clang_decl_id} +// CHECK:STDOUT: entity_name0: {name: name1, parent_scope: name_scope1, index: -1, is_template: 0} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: // CHECK:STDOUT: function50000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block5]} // CHECK:STDOUT: function50000001: {name: name1, parent_scope: name_scope1} diff --git a/toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon b/toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon index 144e6b89d1ba..27740202407d 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon @@ -38,6 +38,7 @@ fn B() { // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name0: inst6000000F}} // CHECK:STDOUT: entity_names: {} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: // CHECK:STDOUT: function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block5]} // CHECK:STDOUT: classes: {} @@ -118,7 +119,8 @@ fn B() { // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name1: inst50000010, name0: inst50000011}} // CHECK:STDOUT: name_scope1: {inst: inst50000010, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst50000016}} // CHECK:STDOUT: entity_names: -// CHECK:STDOUT: entity_name0: {name: name1, parent_scope: name_scope1, index: -1, is_template: 0, clang_decl_id: clang_decl_id} +// CHECK:STDOUT: entity_name0: {name: name1, parent_scope: name_scope1, index: -1, is_template: 0} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: // CHECK:STDOUT: function50000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block5]} // CHECK:STDOUT: function50000001: {name: name1, parent_scope: name_scope1} diff --git a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon index 29ba9e888941..27f8e5b161ee 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon @@ -232,68 +232,69 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: name_scope11: {inst: inst600000BD, parent_scope: name_scope1, has_error: false, extended_scopes: [], names: {}} // CHECK:STDOUT: name_scope12: {inst: inst600000F5, parent_scope: name_scope1, has_error: false, extended_scopes: [], names: {}} // CHECK:STDOUT: entity_names: -// CHECK:STDOUT: entity_name0: {name: name(PeriodSelf), parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name1: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name2: {name: name2, parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name3: {name: name3, parent_scope: name_scope1, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name4: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name5: {name: name4, parent_scope: name_scope2, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name6: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name7: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name8: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name9: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name10: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name11: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name12: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name13: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name14: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name15: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name16: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name17: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name18: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name19: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name20: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name21: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name22: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name23: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name24: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name25: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name26: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name27: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name28: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name29: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name30: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name31: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name32: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name33: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name34: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name35: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name36: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name37: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name38: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name39: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name40: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name41: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name42: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name43: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name44: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name45: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name46: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name47: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name48: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name49: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name50: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name51: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name52: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name53: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name54: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name55: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name56: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name57: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name58: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name59: {name: name5, parent_scope: name_scope, index: 1, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name60: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} -// CHECK:STDOUT: entity_name61: {name: name6, parent_scope: name_scope, index: 2, is_template: 0, clang_decl_id: clang_decl_id} +// CHECK:STDOUT: entity_name0: {name: name(PeriodSelf), parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name1: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name2: {name: name2, parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name3: {name: name3, parent_scope: name_scope1, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name4: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name5: {name: name4, parent_scope: name_scope2, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name6: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name7: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name8: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name9: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name10: {name: name(SelfType), parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name11: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name12: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name13: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name14: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name15: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name16: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name17: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name18: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name19: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name20: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name21: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name22: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name23: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name24: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name25: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name26: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name27: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name28: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name29: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name30: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name31: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name32: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name33: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name34: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name35: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name36: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name37: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name38: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name39: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name40: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name41: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name42: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name43: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name44: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name45: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name46: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name47: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name48: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name49: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name50: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name51: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name52: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name53: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name54: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name55: {name: name(SelfValue), parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: entity_name56: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name57: {name: name1, parent_scope: name_scope, index: 0, is_template: 0} +// CHECK:STDOUT: entity_name58: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name59: {name: name5, parent_scope: name_scope, index: 1, is_template: 0} +// CHECK:STDOUT: entity_name60: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: entity_name61: {name: name6, parent_scope: name_scope, index: 2, is_template: 0} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: // CHECK:STDOUT: function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block13, return_slot_pattern: inst60000030, body: [inst_block20]} // CHECK:STDOUT: function60000001: {name: name4, parent_scope: name_scope2, return_slot_pattern: inst60000055} diff --git a/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon b/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon index 6102f2af2ab4..95d922ea7270 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon @@ -28,7 +28,8 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name0: inst60000025}} // CHECK:STDOUT: entity_names: -// CHECK:STDOUT: entity_name0: {name: name1, parent_scope: name_scope, index: -1, is_template: 0, clang_decl_id: clang_decl_id} +// CHECK:STDOUT: entity_name0: {name: name1, parent_scope: name_scope, index: -1, is_template: 0} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: // CHECK:STDOUT: function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block9, return_slot_pattern: inst60000020, body: [inst_block12]} // CHECK:STDOUT: classes: {} diff --git a/toolchain/driver/testdata/stdin.carbon b/toolchain/driver/testdata/stdin.carbon index f9ea552a0d6c..0bb12c8d0515 100644 --- a/toolchain/driver/testdata/stdin.carbon +++ b/toolchain/driver/testdata/stdin.carbon @@ -34,6 +34,7 @@ // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: inst0000000E, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {}} // CHECK:STDOUT: entity_names: {} +// CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: {} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} diff --git a/toolchain/lower/BUILD b/toolchain/lower/BUILD index 75528aa0d15f..ce3e1294fccf 100644 --- a/toolchain/lower/BUILD +++ b/toolchain/lower/BUILD @@ -61,6 +61,7 @@ cc_library( "//toolchain/base:kind_switch", "//toolchain/parse:tree", "//toolchain/sem_ir:absolute_node_id", + "//toolchain/sem_ir:clang_decl", "//toolchain/sem_ir:diagnostic_loc_converter", "//toolchain/sem_ir:entry_point", "//toolchain/sem_ir:expr_info", diff --git a/toolchain/lower/mangler.cpp b/toolchain/lower/mangler.cpp index 572a310031ec..f0d372ddc037 100644 --- a/toolchain/lower/mangler.cpp +++ b/toolchain/lower/mangler.cpp @@ -9,6 +9,7 @@ #include "common/raw_string_ostream.h" #include "toolchain/base/kind_switch.h" #include "toolchain/lower/clang_global_decl.h" +#include "toolchain/sem_ir/clang_decl.h" #include "toolchain/sem_ir/entry_point.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/pattern.h" @@ -208,15 +209,21 @@ auto Mangler::MangleGlobalVariable(SemIR::InstId pattern_id) -> std::string { return std::string(); } - auto var_name = sem_ir().entity_names().Get(var_name_id); - if (var_name.clang_decl_id.has_value()) { + SemIR::CppGlobalVarId cpp_global_var_id = + sem_ir().cpp_global_vars().Lookup({.entity_name_id = var_name_id}); + if (cpp_global_var_id.has_value()) { + SemIR::ClangDeclId clang_decl_id = + sem_ir().cpp_global_vars().Get(cpp_global_var_id).clang_decl_id; + CARBON_CHECK(clang_decl_id.has_value(), + "CppGlobalVar should have a clang_decl_id"); return MangleCppClang(cast( - sem_ir().clang_decls().Get(var_name.clang_decl_id).key.decl)); + sem_ir().clang_decls().Get(clang_decl_id).key.decl)); } RawStringOstream os; os << "_C"; + auto var_name = sem_ir().entity_names().Get(var_name_id); MangleNameId(os, var_name.name_id); // TODO: If the variable is private, also include the library name as part of // the mangling. diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index dd50475e6a8d..2634610ee544 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -87,6 +87,7 @@ cc_library( "class.h", "constant.h", "copy_on_write_block.h", + "cpp_global_var.h", "cpp_overload_set.h", "entity_name.h", "entity_with_params_base.h", diff --git a/toolchain/sem_ir/cpp_global_var.h b/toolchain/sem_ir/cpp_global_var.h new file mode 100644 index 000000000000..e02ca7f8e1b9 --- /dev/null +++ b/toolchain/sem_ir/cpp_global_var.h @@ -0,0 +1,71 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_SEM_IR_CPP_GLOBAL_VAR_H_ +#define CARBON_TOOLCHAIN_SEM_IR_CPP_GLOBAL_VAR_H_ + +#include "common/hashing.h" +#include "common/ostream.h" +#include "toolchain/sem_ir/clang_decl.h" +#include "toolchain/sem_ir/ids.h" + +namespace Carbon::SemIR { + +// A key describing a C++ global variable imported into Carbon, identified by +// its entity name. +struct CppGlobalVarKey : public Printable { + auto Print(llvm::raw_ostream& out) const -> void { + out << "{entity_name_id: " << entity_name_id << "}"; + } + + // TODO: Use default when `Printable` supports it. + friend auto operator==(const CppGlobalVarKey& lhs, const CppGlobalVarKey& rhs) + -> bool { + return lhs.entity_name_id == rhs.entity_name_id; + } + + // The name of the variable. + EntityNameId entity_name_id; +}; + +// A C++ global variable imported into Carbon. This is used to map the entity +// name to the Clang declaration so we can use Clang mangling. +struct CppGlobalVar : public Printable { + auto Print(llvm::raw_ostream& out) const -> void { + out << "{key: " << key << ", clang_decl_id: " << clang_decl_id << "}"; + } + + // Comparison against `CppGlobalVarKey`, required by `CanonicalValueStore`. + friend auto operator==(const CppGlobalVar& lhs, const CppGlobalVarKey& rhs) + -> bool { + return lhs.key == rhs; + } + friend auto operator==(const CppGlobalVar& lhs, const CppGlobalVar& rhs) + -> bool { + return lhs.key == rhs.key; + } + + // Hashing for `CppGlobalVar`. See common/hashing.h. + friend auto CarbonHashValue(const CppGlobalVar& value, uint64_t seed) + -> HashCode { + return HashValue(value.key, seed); + } + + // The key by which this variable can be looked up. + CppGlobalVarKey key; + + // The Clang declaration for this variable, if any. + // This is ignored for equality and hashing, since it's always unique for a + // given key, in order to store it in `CanonicalValueStore` and allow lookup + // by `CppGlobalVarKey`. + ClangDeclId clang_decl_id; +}; + +// Use the name of a C++ global variable when doing `Lookup` to find an ID. +using CppGlobalVarStore = + CanonicalValueStore; + +} // namespace Carbon::SemIR + +#endif // CARBON_TOOLCHAIN_SEM_IR_CPP_GLOBAL_VAR_H_ diff --git a/toolchain/sem_ir/entity_name.h b/toolchain/sem_ir/entity_name.h index d717cf90fb73..e4f71c8cc953 100644 --- a/toolchain/sem_ir/entity_name.h +++ b/toolchain/sem_ir/entity_name.h @@ -17,7 +17,7 @@ struct EntityName : public Printable { auto Print(llvm::raw_ostream& out) const -> void { out << "{name: " << name_id << ", parent_scope: " << parent_scope_id << ", index: " << bind_index_value << ", is_template: " << is_template - << ", clang_decl_id: " << clang_decl_id << "}"; + << "}"; } friend auto CarbonHashtableEq(const EntityName& lhs, const EntityName& rhs) @@ -56,10 +56,6 @@ struct EntityName : public Printable { int32_t bind_index_value : 31 = CompileTimeBindIndex::None.index; // Whether this binding is a template parameter. bool is_template : 1 = false; - // For imported C++ global variable names, the Clang decl to use for mangling. - // TODO: Move the mapping between global variables and the clang decl to avoid - // paying extra memory when the names are not imported from C++. - ClangDeclId clang_decl_id = ClangDeclId::None; }; // Value store for EntityName. In addition to the regular ValueStore @@ -68,14 +64,12 @@ struct EntityNameStore : public ValueStore { public: // Adds an entity name for a symbolic binding. auto AddSymbolicBindingName(NameId name_id, NameScopeId parent_scope_id, - CompileTimeBindIndex bind_index, bool is_template, - ClangDeclId clang_decl_id = ClangDeclId::None) + CompileTimeBindIndex bind_index, bool is_template) -> EntityNameId { return Add({.name_id = name_id, .parent_scope_id = parent_scope_id, .bind_index_value = bind_index.index, - .is_template = is_template, - .clang_decl_id = clang_decl_id}); + .is_template = is_template}); } // Convert an `EntityName` to a canonical ID. All calls to this with diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 7ec9c74e82e2..a13cfa3237f1 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -112,6 +112,7 @@ auto File::OutputYaml(bool include_singletons) const -> Yaml::OutputMapping { map.Add("clang_decls", clang_decls_.OutputYaml()); map.Add("name_scopes", name_scopes_.OutputYaml()); map.Add("entity_names", entity_names_.OutputYaml()); + map.Add("cpp_global_vars", cpp_global_vars_.OutputYaml()); map.Add("functions", functions_.OutputYaml()); map.Add("classes", classes_.OutputYaml()); map.Add("generics", generics_.OutputYaml()); @@ -139,6 +140,8 @@ auto File::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const mem_usage.Collect(MemUsage::ConcatLabel(label, "allocator_"), allocator_); mem_usage.Collect(MemUsage::ConcatLabel(label, "entity_names_"), entity_names_); + mem_usage.Collect(MemUsage::ConcatLabel(label, "cpp_global_vars_"), + cpp_global_vars_); mem_usage.Collect(MemUsage::ConcatLabel(label, "functions_"), functions_); mem_usage.Collect(MemUsage::ConcatLabel(label, "classes_"), classes_); mem_usage.Collect(MemUsage::ConcatLabel(label, "interfaces_"), interfaces_); diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 94450cf24b53..6a6bcf00bf15 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -21,6 +21,7 @@ #include "toolchain/sem_ir/associated_constant.h" #include "toolchain/sem_ir/class.h" #include "toolchain/sem_ir/constant.h" +#include "toolchain/sem_ir/cpp_global_var.h" #include "toolchain/sem_ir/cpp_overload_set.h" #include "toolchain/sem_ir/entity_name.h" #include "toolchain/sem_ir/facet_type_info.h" @@ -154,6 +155,10 @@ class File : public Printable { auto entity_names() -> EntityNameStore& { return entity_names_; } auto entity_names() const -> const EntityNameStore& { return entity_names_; } + auto cpp_global_vars() -> CppGlobalVarStore& { return cpp_global_vars_; } + auto cpp_global_vars() const -> const CppGlobalVarStore& { + return cpp_global_vars_; + } auto functions() -> FunctionStore& { return functions_; } auto functions() const -> const FunctionStore& { return functions_; } auto cpp_overload_sets() -> CppOverloadSetStore& { @@ -301,6 +306,9 @@ class File : public Printable { // Storage for EntityNames. EntityNameStore entity_names_; + // For imported C++ global variables, the Clang decl to use for mangling. + CppGlobalVarStore cpp_global_vars_; + // Storage for callable objects. FunctionStore functions_; diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 9c6512ac2923..786ae413424e 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -251,6 +251,13 @@ struct EntityNameId : public IdBase { using IdBase::IdBase; }; +// The ID of a C++ global variable. +struct CppGlobalVarId : public IdBase { + static constexpr llvm::StringLiteral Label = "cpp_global_var"; + + using IdBase::IdBase; +}; + // The index of a compile-time binding. This is the de Bruijn level for the // binding -- that is, this is the number of other compile time bindings whose // scope encloses this binding. diff --git a/toolchain/sem_ir/yaml_test.cpp b/toolchain/sem_ir/yaml_test.cpp index 27d2fbb9f04a..cbc346fe6eec 100644 --- a/toolchain/sem_ir/yaml_test.cpp +++ b/toolchain/sem_ir/yaml_test.cpp @@ -60,6 +60,7 @@ TEST(SemIRTest, Yaml) { Pair("clang_decls", Yaml::Mapping(SizeIs(0))), Pair("name_scopes", Yaml::Mapping(SizeIs(1))), Pair("entity_names", Yaml::Mapping(SizeIs(1))), + Pair("cpp_global_vars", Yaml::Mapping(SizeIs(0))), Pair("functions", Yaml::Mapping(SizeIs(1))), Pair("classes", Yaml::Mapping(SizeIs(0))), Pair("generics", Yaml::Mapping(SizeIs(0))),