diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index f90cba5cf72b..d005e6e9946d 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -87,6 +87,13 @@ class SemIRDiagnosticConverter : public DiagnosticConverter { while (true) { if (cursor_inst_id.is_valid()) { + auto cursor_inst = cursor_ir->insts().Get(cursor_inst_id); + if (auto bind_ref = cursor_inst.TryAs(); + bind_ref && bind_ref->value_id.is_valid()) { + cursor_inst_id = bind_ref->value_id; + continue; + } + // If the parse node is valid, use it for the location. if (auto loc_id = cursor_ir->insts().GetLocId(cursor_inst_id); loc_id.is_valid()) { @@ -98,8 +105,7 @@ class SemIRDiagnosticConverter : public DiagnosticConverter { // If a namespace has an instruction for an import, switch to looking at // it. - if (auto ns = - cursor_ir->insts().TryGetAs(cursor_inst_id)) { + if (auto ns = cursor_inst.TryAs()) { if (ns->import_id.is_valid()) { cursor_inst_id = ns->import_id; continue; diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index a80bd213498d..8f3444ff6063 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -247,7 +247,8 @@ auto Context::LookupNameInDecl(SemIR::LocId loc_id, SemIR::NameId name_id, // // // Error, no `F` in `B`. // fn B.F() {} - return LookupNameInExactScope(loc_id, name_id, name_scopes().Get(scope_id)); + return LookupNameInExactScope(loc_id, name_id, scope_id, + name_scopes().Get(scope_id)); } } @@ -282,6 +283,7 @@ auto Context::LookupUnqualifiedName(Parse::NodeId node_id, // Handles lookup through the import_ir_scopes for LookupNameInExactScope. static auto LookupInImportIRScopes(Context& context, SemIRLoc loc, SemIR::NameId name_id, + SemIR::NameScopeId scope_id, const SemIR::NameScope& scope) -> SemIR::InstId { auto identifier_id = name_id.AsIdentifierId(); @@ -298,6 +300,7 @@ static auto LookupInImportIRScopes(Context& context, SemIRLoc loc, }); auto result_id = SemIR::InstId::Invalid; + auto bind_name_id = SemIR::BindNameId::Invalid; for (auto [import_ir_id, import_scope_id] : scope.import_ir_scopes) { auto& import_ir = context.import_irs().Get(import_ir_id); @@ -321,8 +324,15 @@ static auto LookupInImportIRScopes(Context& context, SemIRLoc loc, // Name doesn't exist in the import scope. continue; } - auto import_inst_id = - AddImportRef(context, {.ir_id = import_ir_id, .inst_id = it->second}); + + if (!bind_name_id.is_valid()) { + bind_name_id = context.bind_names().Add( + {.name_id = name_id, + .enclosing_scope_id = scope_id, + .bind_index = SemIR::CompileTimeBindIndex::Invalid}); + } + auto import_inst_id = AddImportRef( + context, {.ir_id = import_ir_id, .inst_id = it->second}, bind_name_id); if (result_id.is_valid()) { context.DiagnoseDuplicateName(import_inst_id, result_id); } else { @@ -335,6 +345,7 @@ static auto LookupInImportIRScopes(Context& context, SemIRLoc loc, } auto Context::LookupNameInExactScope(SemIRLoc loc, SemIR::NameId name_id, + SemIR::NameScopeId scope_id, const SemIR::NameScope& scope) -> SemIR::InstId { if (auto it = scope.names.find(name_id); it != scope.names.end()) { @@ -342,7 +353,7 @@ auto Context::LookupNameInExactScope(SemIRLoc loc, SemIR::NameId name_id, return it->second; } if (!scope.import_ir_scopes.empty()) { - return LookupInImportIRScopes(*this, loc, name_id, scope); + return LookupInImportIRScopes(*this, loc, name_id, scope_id, scope); } return SemIR::InstId::Invalid; } @@ -356,10 +367,12 @@ auto Context::LookupQualifiedName(Parse::NodeId node_id, SemIR::NameId name_id, // Walk this scope and, if nothing is found here, the scopes it extends. while (!scope_ids.empty()) { - const auto& scope = name_scopes().Get(scope_ids.pop_back_val()); + auto scope_id = scope_ids.pop_back_val(); + const auto& scope = name_scopes().Get(scope_id); has_error |= scope.has_error; - auto scope_result_id = LookupNameInExactScope(node_id, name_id, scope); + auto scope_result_id = + LookupNameInExactScope(node_id, name_id, scope_id, scope); if (!scope_result_id.is_valid()) { // Nothing found in this scope: also look in its extended scopes. auto extended = llvm::reverse(scope.extended_scopes); @@ -409,7 +422,7 @@ static auto GetCorePackage(Context& context, SemIRLoc loc) // Look up `package.Core`. auto core_inst_id = context.LookupNameInExactScope( - loc, core_name_id, + loc, core_name_id, SemIR::NameScopeId::Package, context.name_scopes().Get(SemIR::NameScopeId::Package)); if (!core_inst_id.is_valid()) { context.DiagnoseNameNotFound(loc, core_name_id); @@ -434,8 +447,8 @@ auto Context::LookupNameInCore(SemIRLoc loc, llvm::StringRef name) } auto name_id = SemIR::NameId::ForIdentifier(identifiers().Add(name)); - auto inst_id = - LookupNameInExactScope(loc, name_id, name_scopes().Get(core_package_id)); + auto inst_id = LookupNameInExactScope(loc, name_id, core_package_id, + name_scopes().Get(core_package_id)); if (!inst_id.is_valid()) { DiagnoseNameNotFound(loc, name_id); return SemIR::InstId::BuiltinError; diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 45d5039c5074..052ed6b8b403 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -109,6 +109,7 @@ class Context { // instruction. Does not look into extended scopes. Returns an invalid // instruction if the name is not found. auto LookupNameInExactScope(SemIRLoc loc, SemIR::NameId name_id, + SemIR::NameScopeId scope_id, const SemIR::NameScope& scope) -> SemIR::InstId; // Performs a qualified name lookup in a specified scope and in scopes that diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 1ccd89c6a036..3bc16e2f04e8 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -1065,6 +1065,9 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst) case CARBON_KIND(SemIR::BindAlias typed_inst): { return context.constant_values().Get(typed_inst.value_id); } + case CARBON_KIND(SemIR::BindExport typed_inst): { + return context.constant_values().Get(typed_inst.value_id); + } case CARBON_KIND(SemIR::NameRef typed_inst): { return context.constant_values().Get(typed_inst.value_id); } diff --git a/toolchain/check/handle_export.cpp b/toolchain/check/handle_export.cpp index ab78fbf2a9da..ef4e5348c7c0 100644 --- a/toolchain/check/handle_export.cpp +++ b/toolchain/check/handle_export.cpp @@ -3,18 +3,56 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "toolchain/check/context.h" +#include "toolchain/check/decl_name_stack.h" #include "toolchain/parse/typed_nodes.h" +#include "toolchain/sem_ir/ids.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { -auto HandleExportIntroducer(Context& /*context*/, +auto HandleExportIntroducer(Context& context, Parse::ExportIntroducerId /*node_id*/) -> bool { + // TODO: Probably need to update DeclNameStack to restrict to only namespaces. + context.decl_name_stack().PushScopeAndStartName(); return true; } auto HandleExportDirective(Context& context, Parse::ExportDirectiveId node_id) -> bool { - return context.TODO(node_id, "ExportDirective"); + auto name_context = context.decl_name_stack().FinishName(); + context.decl_name_stack().PopScope(); + + if (name_context.state == DeclNameStack::NameContext::State::Error) { + // Should already be diagnosed. + return true; + } + + auto inst_id = name_context.prev_inst_id(); + if (!inst_id.is_valid()) { + context.DiagnoseNameNotFound(node_id, name_context.name_id_for_new_inst()); + return true; + } + + auto import_ref = context.insts().TryGetAs(inst_id); + if (!import_ref) { + CARBON_DIAGNOSTIC(ExportNotImportedEntity, Error, + "Only imported entities are valid for `export`."); + CARBON_DIAGNOSTIC(ExportNotImportedEntitySource, Note, + "Name is declared here."); + context.emitter() + .Build(node_id, ExportNotImportedEntity) + .Note(inst_id, ExportNotImportedEntitySource) + .Emit(); + return true; + } + + auto export_id = context.AddInst( + {node_id, SemIR::BindExport{.type_id = import_ref->type_id, + .bind_name_id = import_ref->bind_name_id, + .value_id = inst_id}}); + context.AddExport(export_id); + + return true; } } // namespace Carbon::Check diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 772ea4a56101..94ff97d2044a 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -106,8 +106,8 @@ static auto BuildInterfaceWitness( CARBON_FATAL() << "Unexpected type: " << type_inst; } auto& fn = context.functions().Get(fn_type->function_id); - auto impl_decl_id = - context.LookupNameInExactScope(decl_id, fn.name_id, impl_scope); + auto impl_decl_id = context.LookupNameInExactScope( + decl_id, fn.name_id, impl.scope_id, impl_scope); if (impl_decl_id.is_valid()) { used_decl_ids.push_back(impl_decl_id); table.push_back(CheckAssociatedFunctionImplementation( diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index 4268a7f59750..83c3eea74475 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -18,12 +18,13 @@ namespace Carbon::Check { // Returns name information for the entity, corresponding to IDs in the import -// IR rather than the current IR. May return Invalid for a TODO. +// IR rather than the current IR. static auto GetImportName(const SemIR::File& import_sem_ir, SemIR::Inst import_inst) -> std::pair { CARBON_KIND_SWITCH(import_inst) { case SemIR::BindAlias::Kind: + case SemIR::BindExport::Kind: case SemIR::BindName::Kind: case SemIR::BindSymbolicName::Kind: { auto bind_inst = import_inst.As(); @@ -139,12 +140,17 @@ static auto CopySingleNameScopeFromImportIR( SemIR::NameId name_id) -> SemIR::NameScopeId { // Produce the namespace for the entry. auto make_import_id = [&]() { + auto bind_name_id = context.bind_names().Add( + {.name_id = name_id, + .enclosing_scope_id = enclosing_scope_id, + .bind_index = SemIR::CompileTimeBindIndex::Invalid}); auto import_ir_inst_id = context.import_ir_insts().Add( {.ir_id = ir_id, .inst_id = import_inst_id}); return context.AddInst( {import_ir_inst_id, SemIR::ImportRefLoaded{.type_id = namespace_type_id, - .import_ir_inst_id = import_ir_inst_id}}); + .import_ir_inst_id = import_ir_inst_id, + .bind_name_id = bind_name_id}}); }; auto [namespace_scope_id, namespace_const_id, _] = AddNamespace(context, namespace_type_id, Parse::NodeId::Invalid, name_id, @@ -228,11 +234,6 @@ auto ImportLibraryFromCurrentPackage(Context& context, auto import_inst = import_sem_ir.insts().Get(import_inst_id); auto [import_name_id, import_enclosing_scope_id] = GetImportName(import_sem_ir, import_inst); - // TODO: This should only be invalid when GetImportName for an inst - // isn't yet implemented. Long-term this should be removed. - if (!import_name_id.is_valid()) { - continue; - } llvm::DenseMap copied_namespaces; @@ -249,12 +250,18 @@ auto ImportLibraryFromCurrentPackage(Context& context, import_namespace_inst->name_scope_id, enclosing_scope_id, name_id); } else { // Leave a placeholder that the inst comes from the other IR. - auto target_id = - AddImportRef(context, {.ir_id = ir_id, .inst_id = import_inst_id}); + auto bind_name_id = context.bind_names().Add( + {.name_id = name_id, + .enclosing_scope_id = enclosing_scope_id, + .bind_index = SemIR::CompileTimeBindIndex::Invalid}); + auto target_id = AddImportRef( + context, {.ir_id = ir_id, .inst_id = import_inst_id}, bind_name_id); auto [it, success] = context.name_scopes() .Get(enclosing_scope_id) .names.insert({name_id, target_id}); if (!success) { + // TODO: Figure out how best to handle when an export is added that's a + // conflict. Right now it diagnoses as a conflict around here. context.DiagnoseDuplicateName(target_id, it->second); } } diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 618b06624a18..901ec53c5556 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -52,11 +52,13 @@ auto AddImportIR(Context& context, SemIR::ImportIR import_ir) return ir_id; } -auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst) - -> SemIR::InstId { +auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst, + SemIR::BindNameId bind_name_id) -> SemIR::InstId { auto import_ir_inst_id = context.import_ir_insts().Add(import_ir_inst); auto import_ref_id = context.AddPlaceholderInstInNoBlock( - {import_ir_inst_id, SemIR::ImportRefUnloaded{import_ir_inst_id}}); + {import_ir_inst_id, + SemIR::ImportRefUnloaded{.import_ir_inst_id = import_ir_inst_id, + .bind_name_id = bind_name_id}}); // We can't insert this instruction into whatever block we happen to be in, // because this function is typically called by name lookup in the middle of @@ -483,7 +485,8 @@ class ImportRefResolver { SemIR::NameScope& new_scope) -> void { for (auto [entry_name_id, entry_inst_id] : import_scope.names) { auto ref_id = AddImportRef( - context_, {.ir_id = import_ir_id_, .inst_id = entry_inst_id}); + context_, {.ir_id = import_ir_id_, .inst_id = entry_inst_id}, + SemIR::BindNameId::Invalid); CARBON_CHECK( new_scope.names.insert({GetLocalNameId(entry_name_id), ref_id}) .second); @@ -503,7 +506,8 @@ class ImportRefResolver { new_associated_entities.reserve(associated_entities.size()); for (auto inst_id : associated_entities) { new_associated_entities.push_back( - AddImportRef(context_, {.ir_id = import_ir_id_, .inst_id = inst_id})); + AddImportRef(context_, {.ir_id = import_ir_id_, .inst_id = inst_id}, + SemIR::BindNameId::Invalid)); } return context_.inst_blocks().Add(new_associated_entities); } @@ -538,6 +542,9 @@ class ImportRefResolver { case CARBON_KIND(SemIR::BindAlias inst): { return TryResolveTypedInst(inst); } + case CARBON_KIND(SemIR::BindExport inst): { + return TryResolveTypedInst(inst); + } case CARBON_KIND(SemIR::BindName inst): { // TODO: This always returns `ConstantId::NotConstant`. return {TryEvalInst(context_, inst_id, inst)}; @@ -607,7 +614,8 @@ class ImportRefResolver { // Add a lazy reference to the target declaration. auto decl_id = AddImportRef( - context_, {.ir_id = import_ir_id_, .inst_id = inst.decl_id}); + context_, {.ir_id = import_ir_id_, .inst_id = inst.decl_id}, + SemIR::BindNameId::Invalid); auto inst_id = context_.AddInstInNoBlock( {AddImportIRInst(inst.decl_id), @@ -666,6 +674,15 @@ class ImportRefResolver { return {value_id}; } + auto TryResolveTypedInst(SemIR::BindExport inst) -> ResolveResult { + auto initial_work = work_stack_.size(); + auto value_id = GetLocalConstantId(inst.value_id); + if (HasNewWork(initial_work)) { + return ResolveResult::Retry(); + } + return {value_id}; + } + auto TryResolveTypedInst(SemIR::BindSymbolicName inst, SemIR::InstId import_inst_id) -> ResolveResult { auto initial_work = work_stack_.size(); @@ -1217,7 +1234,10 @@ auto LoadImportRef(Context& context, SemIR::InstId inst_id) -> void { // doesn't use ReplaceInstBeforeConstantUse because it would trigger // TryEvalInst, which we want to avoid with ImportRefs. context.sem_ir().insts().Set( - inst_id, SemIR::ImportRefLoaded{type_id, inst->import_ir_inst_id}); + inst_id, + SemIR::ImportRefLoaded{.type_id = type_id, + .import_ir_inst_id = inst->import_ir_inst_id, + .bind_name_id = inst->bind_name_id}); // Store the constant for both the ImportRefLoaded and imported instruction. context.constant_values().Set(inst_id, constant_id); @@ -1242,7 +1262,8 @@ static auto ImportImpl(Context& context, SemIR::ImportIRId import_ir_id, auto& impl = context.impls().Get(impl_id); impl.witness_id = AddImportRef( - context, {.ir_id = import_ir_id, .inst_id = import_impl.witness_id}); + context, {.ir_id = import_ir_id, .inst_id = import_impl.witness_id}, + SemIR::BindNameId::Invalid); } } diff --git a/toolchain/check/import_ref.h b/toolchain/check/import_ref.h index c138f34a4e0b..9a44c187e4a5 100644 --- a/toolchain/check/import_ref.h +++ b/toolchain/check/import_ref.h @@ -21,8 +21,8 @@ auto AddImportIR(Context& context, SemIR::ImportIR import_ir) // Adds an import_ref instruction for the specified instruction in the // specified IR. The import_ref is initially marked as unused. -auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst) - -> SemIR::InstId; +auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst, + SemIR::BindNameId bind_name_id) -> SemIR::InstId; // If the passed in instruction ID is an ImportRefUnloaded, turns it into an // ImportRefLoaded for use. diff --git a/toolchain/check/testdata/alias/no_prelude/export_name.carbon b/toolchain/check/testdata/alias/no_prelude/export_name.carbon new file mode 100644 index 000000000000..f04f2a838fc5 --- /dev/null +++ b/toolchain/check/testdata/alias/no_prelude/export_name.carbon @@ -0,0 +1,241 @@ +// 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 +// +// AUTOUPDATE + +// ============================================================================ +// Setup files +// ============================================================================ + +// --- base.carbon + +library "base" api; + +class C {} +alias D = C; + +// --- export.carbon + +library "export" api; + +import library "base"; + +export D; + +// --- export_orig.carbon + +library "export_orig" api; + +import library "base"; + +export C; + +// ============================================================================ +// Test files +// ============================================================================ + +// --- use_export.carbon + +library "use_export" api; + +import library "export"; + +var d: D = {}; + +// --- fail_orig_name_not_in_export.carbon + +library "fail_orig_name_not_in_export" api; + +import library "export"; + +// CHECK:STDERR: fail_orig_name_not_in_export.carbon:[[@LINE+3]]:8: ERROR: Name `C` not found. +// CHECK:STDERR: var c: C = {}; +// CHECK:STDERR: ^ +var c: C = {}; + +// --- indirect_compat.carbon + +library "indirect_compat" api; + +import library "export"; +import library "export_orig"; + +var c: C = {}; +var d: D* = &c; + +// CHECK:STDOUT: --- base.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .D = %import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1 = import_ref ir1, inst+1, unloaded +// CHECK:STDOUT: %import_ref.2: type = import_ref ir1, inst+5, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %D: type = bind_export D, %import_ref.2 [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_orig.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .D = %import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+5, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %C: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %.3: type = ptr_type {} [template] +// CHECK:STDOUT: %struct: C = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .D = %import_ref.1 +// CHECK:STDOUT: .d = %d +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+7, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+6, unloaded +// CHECK:STDOUT: %D.ref: type = name_ref D, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %d.var: ref C = var d +// CHECK:STDOUT: %d: ref C = bind_name d, %d.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc6_13.1: {} = struct_literal () +// CHECK:STDOUT: %.loc6_13.2: init C = class_init (), file.%d.var [template = constants.%struct] +// CHECK:STDOUT: %.loc6_14: init C = converted %.loc6_13.1, %.loc6_13.2 [template = constants.%struct] +// CHECK:STDOUT: assign file.%d.var, %.loc6_14 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_orig_name_not_in_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .D = %import_ref +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref = import_ref ir1, inst+7, unloaded +// CHECK:STDOUT: %C.ref: = name_ref C, [template = ] +// CHECK:STDOUT: %c.var: ref = var c +// CHECK:STDOUT: %c: ref = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc9: {} = struct_literal () +// CHECK:STDOUT: assign file.%c.var, +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- indirect_compat.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %.3: type = ptr_type {} [template] +// CHECK:STDOUT: %struct: C = struct_value () [template] +// CHECK:STDOUT: %.4: type = ptr_type C [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .D = %import_ref.1 +// CHECK:STDOUT: .C = %import_ref.2 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .d = %d +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+7, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: type = import_ref ir2, inst+7, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.3 = import_ref ir2, inst+6, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.2 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %D.ref: type = name_ref D, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %.loc8: type = ptr_type C [template = constants.%.4] +// CHECK:STDOUT: %d.var: ref C* = var d +// CHECK:STDOUT: %d: ref C* = bind_name d, %d.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc7_13.1: {} = struct_literal () +// CHECK:STDOUT: %.loc7_13.2: init C = class_init (), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc7_14: init C = converted %.loc7_13.1, %.loc7_13.2 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc7_14 +// CHECK:STDOUT: %c.ref: ref C = name_ref c, file.%c +// CHECK:STDOUT: %.loc8: C* = addr_of %c.ref +// CHECK:STDOUT: assign file.%d.var, %.loc8 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/no_prelude/export_name.carbon b/toolchain/check/testdata/class/no_prelude/export_name.carbon new file mode 100644 index 000000000000..c7800cd04755 --- /dev/null +++ b/toolchain/check/testdata/class/no_prelude/export_name.carbon @@ -0,0 +1,112 @@ +// 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 +// +// AUTOUPDATE + +// ============================================================================ +// Setup files +// ============================================================================ + +// --- base.carbon + +library "base" api; + +class C {} + +// --- export.carbon + +library "export" api; + +import library "base"; + +export C; + +// ============================================================================ +// Test files +// ============================================================================ + +// --- use_export.carbon + +library "use_export" api; + +import library "export"; + +var c: C = {}; + +// CHECK:STDOUT: --- base.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %C: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %.3: type = ptr_type {} [template] +// CHECK:STDOUT: %struct: C = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+6, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+5, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc6_13.1: {} = struct_literal () +// CHECK:STDOUT: %.loc6_13.2: init C = class_init (), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc6_14: init C = converted %.loc6_13.1, %.loc6_13.2 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc6_14 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/no_prelude/export_name.carbon b/toolchain/check/testdata/function/declaration/no_prelude/export_name.carbon new file mode 100644 index 000000000000..11adafc4fc2a --- /dev/null +++ b/toolchain/check/testdata/function/declaration/no_prelude/export_name.carbon @@ -0,0 +1,101 @@ +// 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 +// +// AUTOUPDATE + +// ============================================================================ +// Setup files +// ============================================================================ + +// --- base.carbon + +library "base" api; + +fn F(); + +// --- export.carbon + +library "export" api; + +import library "base"; + +export F; + +// ============================================================================ +// Test files +// ============================================================================ + +// --- use_export.carbon + +library "use_export" api; + +import library "export"; + +var f: () = F(); + +// CHECK:STDOUT: --- base.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F: type = fn_type @F [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %struct: F = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: F = fn_decl @F [template = constants.%struct] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F: type = fn_type @F [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %struct: F = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .F = %import_ref +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref: F = import_ref ir1, inst+1, loaded [template = constants.%struct] +// CHECK:STDOUT: %F: F = bind_export F, %import_ref [template = constants.%struct] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %F: type = fn_type @F [template] +// CHECK:STDOUT: %struct: F = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .F = %import_ref +// CHECK:STDOUT: .f = %f +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref: F = import_ref ir1, inst+6, loaded [template = constants.%struct] +// CHECK:STDOUT: %.loc6_9.1: () = tuple_literal () +// CHECK:STDOUT: %.loc6_9.2: type = converted %.loc6_9.1, constants.%.1 [template = constants.%.1] +// CHECK:STDOUT: %f.var: ref () = var f +// CHECK:STDOUT: %f: ref () = bind_name f, %f.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %F.ref: F = name_ref F, file.%import_ref [template = constants.%struct] +// CHECK:STDOUT: %F.call: init () = call %F.ref() +// CHECK:STDOUT: assign file.%f.var, %F.call +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/export_name.carbon b/toolchain/check/testdata/interface/no_prelude/export_name.carbon new file mode 100644 index 000000000000..f181ee91f1ba --- /dev/null +++ b/toolchain/check/testdata/interface/no_prelude/export_name.carbon @@ -0,0 +1,115 @@ +// 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 +// +// AUTOUPDATE + +// ============================================================================ +// Setup files +// ============================================================================ + +// --- base.carbon + +library "base" api; + +interface I {} + +// --- export.carbon + +library "export" api; + +import library "base"; + +export I; + +// ============================================================================ +// Test files +// ============================================================================ + +// --- use_export.carbon + +library "use_export" api; + +import library "export"; + +fn UseEmpty(i: I) {} + +// CHECK:STDOUT: --- base.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = interface_type @I [template] +// CHECK:STDOUT: %Self: I = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%.1] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: I = bind_symbolic_name Self 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = interface_type @I [template] +// CHECK:STDOUT: %Self: I = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .I = %import_ref.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%.1] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+3, unloaded +// CHECK:STDOUT: %I: type = bind_export I, %import_ref.1 [template = constants.%.1] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = interface_type @I [template] +// CHECK:STDOUT: %Self: I = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: %UseEmpty: type = fn_type @UseEmpty [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %struct: UseEmpty = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .I = %import_ref.1 +// CHECK:STDOUT: .UseEmpty = %UseEmpty.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+7, loaded [template = constants.%.1] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+6, unloaded +// CHECK:STDOUT: %UseEmpty.decl: UseEmpty = fn_decl @UseEmpty [template = constants.%struct] { +// CHECK:STDOUT: %I.ref: type = name_ref I, %import_ref.1 [template = constants.%.1] +// CHECK:STDOUT: %i.loc6_13.1: I = param i +// CHECK:STDOUT: @UseEmpty.%i: I = bind_name i, %i.loc6_13.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @UseEmpty(%i: I) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon b/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon new file mode 100644 index 000000000000..a9cbb8cc3377 --- /dev/null +++ b/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon @@ -0,0 +1,588 @@ +// 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 +// +// AUTOUPDATE + +// ============================================================================ +// Setup files +// ============================================================================ + +// --- base.carbon + +library "base" api; + +class C { + var x: (); +}; + +class D { + var y: (); +}; + +// --- export_import.carbon + +library "export_import" api; + +export import library "base"; + +// --- export_import_then_name.carbon + +library "export_import_then_name" api; + +import library "export_import"; + +export C; + +// --- export_name.carbon + +library "export_name" api; + +import library "base"; + +export C; + +// --- export_name_then_import.carbon + +library "export_name_then_import" api; + +export import library "export_name"; + +// ============================================================================ +// Test files +// ============================================================================ + +// --- use_export_import_then_name.carbon + +library "use_export_import_then_name" api; + +import library "export_import_then_name"; + +var c: C = {.x = ()}; + +// --- use_export_name_then_import.carbon + +library "use_export_name_then_import" api; + +import library "export_name_then_import"; + +var c: C = {.x = ()}; + +// --- fail_todo_use_both.carbon + +library "use_both" api; + +import library "export_import_then_name"; +// CHECK:STDERR: fail_todo_use_both.carbon:[[@LINE+19]]:1: In import. +// CHECK:STDERR: import library "export_name_then_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_name.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_use_both.carbon:[[@LINE-10]]:1: In import. +// CHECK:STDERR: import library "export_import_then_name"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_import_then_name.carbon:4:1: In import. +// CHECK:STDERR: import library "export_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +import library "export_name_then_import"; + +var c: C = {.x = ()}; + +// --- fail_nonexport_use_both.carbon + +library "fail_nonexport_use_both" api; + +import library "export_import_then_name"; +// CHECK:STDERR: fail_nonexport_use_both.carbon:[[@LINE+19]]:1: In import. +// CHECK:STDERR: import library "export_name_then_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_name.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_nonexport_use_both.carbon:[[@LINE-10]]:1: In import. +// CHECK:STDERR: import library "export_import_then_name"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_import_then_name.carbon:4:1: In import. +// CHECK:STDERR: import library "export_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +import library "export_name_then_import"; + +// CHECK:STDERR: fail_nonexport_use_both.carbon:[[@LINE+4]]:8: ERROR: Name `D` not found. +// CHECK:STDERR: var d: D = {.y = ()}; +// CHECK:STDERR: ^ +// CHECK:STDERR: +var d: D = {.y = ()}; + +// --- fail_todo_use_both_reversed.carbon + +library "use_both_reversed" api; + +import library "export_import_then_name"; +// CHECK:STDERR: fail_todo_use_both_reversed.carbon:[[@LINE+19]]:1: In import. +// CHECK:STDERR: import library "export_name_then_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_name.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_use_both_reversed.carbon:[[@LINE-10]]:1: In import. +// CHECK:STDERR: import library "export_import_then_name"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_import_then_name.carbon:4:1: In import. +// CHECK:STDERR: import library "export_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +import library "export_name_then_import"; + +var c: C = {.x = ()}; + +// --- fail_todo_use_both_and_export_import.carbon + +library "use_both_and_export_import" api; + +import library "export_import_then_name"; +// CHECK:STDERR: fail_todo_use_both_and_export_import.carbon:[[@LINE+19]]:1: In import. +// CHECK:STDERR: import library "export_name_then_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_name.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_use_both_and_export_import.carbon:[[@LINE-10]]:1: In import. +// CHECK:STDERR: import library "export_import_then_name"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_import_then_name.carbon:4:1: In import. +// CHECK:STDERR: import library "export_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +import library "export_name_then_import"; +// CHECK:STDERR: fail_todo_use_both_and_export_import.carbon:[[@LINE+15]]:1: In import. +// CHECK:STDERR: import library "export_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_use_both_and_export_import.carbon:[[@LINE-27]]:1: In import. +// CHECK:STDERR: import library "export_import_then_name"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export_import_then_name.carbon:4:1: In import. +// CHECK:STDERR: import library "export_import"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +import library "export_import"; + +var c: C = {.x = ()}; +var d: D = {.y = ()}; + +// CHECK:STDOUT: --- base.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = unbound_element_type C, () [template] +// CHECK:STDOUT: %.3: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %D: type = class_type @D [template] +// CHECK:STDOUT: %.4: type = unbound_element_type D, () [template] +// CHECK:STDOUT: %.5: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %D.decl: type = class_decl @D [template = constants.%D] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %.loc5_11.1: () = tuple_literal () +// CHECK:STDOUT: %.loc5_11.2: type = converted %.loc5_11.1, constants.%.1 [template = constants.%.1] +// CHECK:STDOUT: %.loc5_8: = field_decl x, element0 [template] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .x = %.loc5_8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @D { +// CHECK:STDOUT: %.loc9_11.1: () = tuple_literal () +// CHECK:STDOUT: %.loc9_11.2: type = converted %.loc9_11.1, constants.%.1 [template = constants.%.1] +// CHECK:STDOUT: %.loc9_8: = field_decl y, element0 [template] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%D +// CHECK:STDOUT: .y = %.loc9_8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .D = %import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1 = import_ref ir1, inst+1, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_import_then_name.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .D = %import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir2, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+11, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir2, inst+7, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref ir2, inst+2, unloaded +// CHECK:STDOUT: %C: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .x = file.%import_ref.3 +// CHECK:STDOUT: .Self = file.%import_ref.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_name.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .D = %import_ref.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+7, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %C: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .x = file.%import_ref.3 +// CHECK:STDOUT: .Self = file.%import_ref.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_name_then_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export_import_then_name.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct: C = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+10, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+9, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: .x = file.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc6_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc6_20.1: {.x: ()} = struct_literal (%.loc6_19.1) +// CHECK:STDOUT: %.loc6_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc6_19.2: init () = tuple_init () to %.loc6_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.3: init () = converted %.loc6_19.1, %.loc6_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.4: init C = class_init (%.loc6_20.3), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc6_21: init C = converted %.loc6_20.1, %.loc6_20.4 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc6_21 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export_name_then_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct: C = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir2, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+10, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir2, inst+9, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.2 +// CHECK:STDOUT: .x = file.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc6_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc6_20.1: {.x: ()} = struct_literal (%.loc6_19.1) +// CHECK:STDOUT: %.loc6_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc6_19.2: init () = tuple_init () to %.loc6_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.3: init () = converted %.loc6_19.1, %.loc6_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.4: init C = class_init (%.loc6_20.3), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc6_21: init C = converted %.loc6_20.1, %.loc6_20.4 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc6_21 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_use_both.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct: C = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir3, inst+11, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+10, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+9, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.3 +// CHECK:STDOUT: .x = file.%import_ref.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc26_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc26_20.1: {.x: ()} = struct_literal (%.loc26_19.1) +// CHECK:STDOUT: %.loc26_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc26_19.2: init () = tuple_init () to %.loc26_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc26_20.3: init () = converted %.loc26_19.1, %.loc26_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc26_20.4: init C = class_init (%.loc26_20.3), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc26_21: init C = converted %.loc26_20.1, %.loc26_20.4 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc26_21 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_nonexport_use_both.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .d = %d +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref ir3, inst+11, unloaded +// CHECK:STDOUT: %D.ref: = name_ref D, [template = ] +// CHECK:STDOUT: %d.var: ref = var d +// CHECK:STDOUT: %d: ref = bind_name d, %d.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc30_19: () = tuple_literal () +// CHECK:STDOUT: %.loc30_20: {.y: ()} = struct_literal (%.loc30_19) +// CHECK:STDOUT: assign file.%d.var, +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_use_both_reversed.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct: C = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir3, inst+11, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+10, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+9, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.3 +// CHECK:STDOUT: .x = file.%import_ref.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc26_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc26_20.1: {.x: ()} = struct_literal (%.loc26_19.1) +// CHECK:STDOUT: %.loc26_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc26_19.2: init () = tuple_init () to %.loc26_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc26_20.3: init () = converted %.loc26_19.1, %.loc26_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc26_20.4: init C = class_init (%.loc26_20.3), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc26_21: init C = converted %.loc26_20.1, %.loc26_20.4 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc26_21 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_use_both_and_export_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct.1: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %D: type = class_type @D [template] +// CHECK:STDOUT: %.4: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: %.5: type = ptr_type {.y: ()} [template] +// CHECK:STDOUT: %struct.2: D = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .D = %import_ref.4 +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .d = %d +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir3, inst+11, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir5, inst+1, unloaded +// CHECK:STDOUT: %import_ref.4: type = import_ref ir5, inst+11, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+10, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+9, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %import_ref.7 = import_ref ir5, inst+12, unloaded +// CHECK:STDOUT: %import_ref.8 = import_ref ir5, inst+16, unloaded +// CHECK:STDOUT: %D.ref: type = name_ref D, %import_ref.4 [template = constants.%D] +// CHECK:STDOUT: %d.var: ref D = var d +// CHECK:STDOUT: %d: ref D = bind_name d, %d.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.5 +// CHECK:STDOUT: .x = file.%import_ref.6 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @D { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.7 +// CHECK:STDOUT: .y = file.%import_ref.8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc42_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc42_20.1: {.x: ()} = struct_literal (%.loc42_19.1) +// CHECK:STDOUT: %.loc42_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc42_19.2: init () = tuple_init () to %.loc42_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc42_20.3: init () = converted %.loc42_19.1, %.loc42_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc42_20.4: init C = class_init (%.loc42_20.3), file.%c.var [template = constants.%struct.1] +// CHECK:STDOUT: %.loc42_21: init C = converted %.loc42_20.1, %.loc42_20.4 [template = constants.%struct.1] +// CHECK:STDOUT: assign file.%c.var, %.loc42_21 +// CHECK:STDOUT: %.loc43_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc43_20.1: {.y: ()} = struct_literal (%.loc43_19.1) +// CHECK:STDOUT: %.loc43_20.2: ref () = class_element_access file.%d.var, element0 +// CHECK:STDOUT: %.loc43_19.2: init () = tuple_init () to %.loc43_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc43_20.3: init () = converted %.loc43_19.1, %.loc43_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc43_20.4: init D = class_init (%.loc43_20.3), file.%d.var [template = constants.%struct.2] +// CHECK:STDOUT: %.loc43_21: init D = converted %.loc43_20.1, %.loc43_20.4 [template = constants.%struct.2] +// CHECK:STDOUT: assign file.%d.var, %.loc43_21 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/no_prelude/export_name.carbon b/toolchain/check/testdata/packages/no_prelude/export_name.carbon index a8ebd267269f..5c3cf1c737e4 100644 --- a/toolchain/check/testdata/packages/no_prelude/export_name.carbon +++ b/toolchain/check/testdata/packages/no_prelude/export_name.carbon @@ -8,9 +8,9 @@ // Setup files // ============================================================================ -// --- class.carbon +// --- base.carbon -library "class" api; +library "base" api; class C { var x: (); @@ -18,36 +18,30 @@ class C { namespace NS; class NS.NSC { - var x: (); + var y: (); }; -// --- fail_todo_export_class.carbon +// --- export.carbon -library "export_class" api; +library "export" api; -import library "class"; -// CHECK:STDERR: fail_todo_export_class.carbon:[[@LINE+4]]:1: ERROR: Semantics TODO: `ExportDirective`. -// CHECK:STDERR: export C; -// CHECK:STDERR: ^~~~~~~~~ -// CHECK:STDERR: +import library "base"; export C; +export NS.NSC; -// --- non_export_class.carbon +// --- not_reexporting.carbon -library "non_export_class" api; +library "not_reexporting" api; -import library "export_class"; +import library "export"; -// --- fail_todo_export_export_class.carbon +// --- export_export.carbon -library "export_export_class" api; +library "export_export" api; -import library "export_class"; -// CHECK:STDERR: fail_todo_export_export_class.carbon:[[@LINE+4]]:1: ERROR: Semantics TODO: `ExportDirective`. -// CHECK:STDERR: export C; -// CHECK:STDERR: ^~~~~~~~~ -// CHECK:STDERR: +import library "export"; export C; +export NS.NSC; // --- export_in_impl.carbon @@ -58,85 +52,201 @@ library "export_in_impl" api; // Test files // ============================================================================ -// --- fail_todo_use_export_class.carbon +// --- use_export.carbon -library "use_export_class" api; +library "use_export" api; -import library "export_class"; +import library "export"; -// CHECK:STDERR: fail_todo_use_export_class.carbon:[[@LINE+4]]:8: ERROR: Name `C` not found. -// CHECK:STDERR: var c: C = {.x = ()}; -// CHECK:STDERR: ^ -// CHECK:STDERR: var c: C = {.x = ()}; +var nsc: NS.NSC = {.y = ()}; -// --- fail_todo_export_in_impl.impl.carbon +// --- export_export.impl.carbon -library "export_in_impl" impl; +library "export_export" impl; -import library "class"; -// CHECK:STDERR: fail_todo_export_in_impl.impl.carbon:[[@LINE+8]]:1: ERROR: `export` is only allowed in API files. -// CHECK:STDERR: export C; +var c: C = {.x = ()}; +var nsc: NS.NSC = {.y = ()}; + +// --- use_export_export.carbon + +library "use_export_export" api; + +import library "export_export"; + +var c: C = {.x = ()}; +var nsc: NS.NSC = {.y = ()}; + +// --- fail_export_ns.carbon + +library "fail_export_ns" api; + +import library "base"; + +// CHECK:STDERR: fail_export_ns.carbon:[[@LINE+10]]:1: ERROR: Only imported entities are valid for `export`. +// CHECK:STDERR: export NS; +// CHECK:STDERR: ^~~~~~~~~~ +// CHECK:STDERR: fail_export_ns.carbon:[[@LINE-5]]:1: In import. +// CHECK:STDERR: import library "base"; // CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:8:1: Name is declared here. +// CHECK:STDERR: namespace NS; +// CHECK:STDERR: ^~~~~~~~~~~~~ // CHECK:STDERR: -// CHECK:STDERR: fail_todo_export_in_impl.impl.carbon:[[@LINE+4]]:1: ERROR: Semantics TODO: `ExportDirective`. -// CHECK:STDERR: export C; -// CHECK:STDERR: ^~~~~~~~~ -// CHECK:STDERR: -export C; +export NS; -// --- fail_todo_export_export_class.impl.carbon +// --- fail_export_member.carbon -library "export_export_class" impl; +library "fail_export_member" api; -// CHECK:STDERR: fail_todo_export_export_class.impl.carbon:[[@LINE+4]]:8: ERROR: Name `C` not found. -// CHECK:STDERR: var c: C = {.x = ()}; +import library "base"; + +// CHECK:STDERR: fail_export_member.carbon:[[@LINE+7]]:10: ERROR: Name qualifiers are only allowed for entities that provide a scope. +// CHECK:STDERR: export C.x; +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_export_member.carbon:[[@LINE+4]]:8: Non-scope entity referenced here. +// CHECK:STDERR: export C.x; // CHECK:STDERR: ^ // CHECK:STDERR: -var c: C = {.x = ()}; +export C.x; -// --- fail_todo_use_export_export_class.carbon - -library "use_export_export_class" api; - -import library "export_export_class"; - -// CHECK:STDERR: fail_todo_use_export_export_class.carbon:[[@LINE+4]]:8: ERROR: Name `C` not found. -// CHECK:STDERR: var c: C = {.x = ()}; -// CHECK:STDERR: ^ -// CHECK:STDERR: -var c: C = {.x = ()}; - -// --- import_both.carbon +// --- fail_todo_import_both.carbon library "import_both" api; -import library "class"; -import library "export_class"; +import library "base"; +// CHECK:STDERR: fail_todo_import_both.carbon:[[@LINE+32]]:1: In import. +// CHECK:STDERR: import library "export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_import_both.carbon:[[@LINE-10]]:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_todo_import_both.carbon:[[@LINE+16]]:1: In import. +// CHECK:STDERR: import library "export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:9:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class NS.NSC { +// CHECK:STDERR: ^~~~~~~~~~~~~~ +// CHECK:STDERR: fail_todo_import_both.carbon:[[@LINE-26]]:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:9:1: Name is previously declared here. +// CHECK:STDERR: class NS.NSC { +// CHECK:STDERR: ^~~~~~~~~~~~~~ +// CHECK:STDERR: +import library "export"; var c: C = {.x = ()}; +var nsc: NS.NSC = {.y = ()}; -// --- import_both_reversed.carbon +// --- fail_todo_import_both_reversed.carbon library "import_both_reversed" api; -import library "export_class"; -import library "class"; +import library "export"; +// CHECK:STDERR: fail_todo_import_both_reversed.carbon:[[@LINE+32]]:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_import_both_reversed.carbon:[[@LINE-7]]:1: In import. +// CHECK:STDERR: import library "export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_todo_import_both_reversed.carbon:[[@LINE+16]]:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:9:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class NS.NSC { +// CHECK:STDERR: ^~~~~~~~~~~~~~ +// CHECK:STDERR: fail_todo_import_both_reversed.carbon:[[@LINE-23]]:1: In import. +// CHECK:STDERR: import library "export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:9:1: Name is previously declared here. +// CHECK:STDERR: class NS.NSC { +// CHECK:STDERR: ^~~~~~~~~~~~~~ +// CHECK:STDERR: +import library "base"; + +var c: C = {.x = ()}; +var nsc: NS.NSC = {.y = ()}; + +// --- fail_use_not_reexporting.carbon + +library "fail_use_not_reexporting" api; + +import library "not_reexporting"; + +// CHECK:STDERR: fail_use_not_reexporting.carbon:[[@LINE+4]]:15: ERROR: Name `C` not found. +// CHECK:STDERR: alias Local = C; +// CHECK:STDERR: ^ +// CHECK:STDERR: +alias Local = C; +// CHECK:STDERR: fail_use_not_reexporting.carbon:[[@LINE+4]]:17: ERROR: Name `NS` not found. +// CHECK:STDERR: alias NSLocal = NS.NSC; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +alias NSLocal = NS.NSC; + +// --- repeat_export.carbon + +library "repeat_export" api; + +import library "base"; + +export C; +export C; + +// --- fail_todo_use_repeat_export.carbon + +library "use_repeat_export" api; + +// CHECK:STDERR: fail_todo_use_repeat_export.carbon:[[@LINE+18]]:1: In import. +// CHECK:STDERR: import library "repeat_export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: repeat_export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_todo_use_repeat_export.carbon:[[@LINE+9]]:1: In import. +// CHECK:STDERR: import library "repeat_export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: repeat_export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:1: Name is previously declared here. +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +import library "repeat_export"; var c: C = {.x = ()}; -// --- fail_use_non_export_class.carbon - -library "fail_use_non_export_class" api; - -import library "non_export_class"; - -// CHECK:STDERR: fail_use_non_export_class.carbon:[[@LINE+3]]:15: ERROR: Name `C` not found. -// CHECK:STDERR: alias Local = C; -// CHECK:STDERR: ^ -alias Local = C; - -// CHECK:STDOUT: --- class.carbon +// CHECK:STDOUT: --- base.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [template] @@ -145,6 +255,7 @@ alias Local = C; // CHECK:STDOUT: %.3: type = struct_type {.x: ()} [template] // CHECK:STDOUT: %NSC: type = class_type @NSC [template] // CHECK:STDOUT: %.4: type = unbound_element_type NSC, () [template] +// CHECK:STDOUT: %.5: type = struct_type {.y: ()} [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -172,26 +283,109 @@ alias Local = C; // CHECK:STDOUT: class @NSC { // CHECK:STDOUT: %.loc10_11.1: () = tuple_literal () // CHECK:STDOUT: %.loc10_11.2: type = converted %.loc10_11.1, constants.%.1 [template = constants.%.1] -// CHECK:STDOUT: %.loc10_8: = field_decl x, element0 [template] +// CHECK:STDOUT: %.loc10_8: = field_decl y, element0 [template] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%NSC -// CHECK:STDOUT: .x = %.loc10_8 +// CHECK:STDOUT: .y = %.loc10_8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_export_class.carbon +// CHECK:STDOUT: --- export.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- non_export_class.carbon +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.3: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] {} +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+11, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir1, inst+12, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+7, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %C: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+13, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir1, inst+17, unloaded +// CHECK:STDOUT: %NSC: type = bind_export NSC, %import_ref.3 [template = constants.%NSC] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_export_export_class.carbon +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .x = file.%import_ref.4 +// CHECK:STDOUT: .Self = file.%import_ref.5 +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.6 +// CHECK:STDOUT: .y = file.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- not_reexporting.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1 = import_ref ir1, inst+13, unloaded +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+3, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+21, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.3: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+3, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir1, inst+21, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: %C: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+20, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir1, inst+19, unloaded +// CHECK:STDOUT: %NSC: type = bind_export NSC, %import_ref.3 [template = constants.%NSC] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.4 +// CHECK:STDOUT: .x = file.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .y = file.%import_ref.6 +// CHECK:STDOUT: .Self = file.%import_ref.7 +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- export_in_impl.carbon // CHECK:STDOUT: @@ -199,83 +393,7 @@ alias Local = C; // CHECK:STDOUT: package: = namespace [template] {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_use_export_class.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %.1: type = tuple_type () [template] -// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .c = %c -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.ref: = name_ref C, [template = ] -// CHECK:STDOUT: %c.var: ref = var c -// CHECK:STDOUT: %c: ref = bind_name c, %c.var -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @__global_init() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc10_19: () = tuple_literal () -// CHECK:STDOUT: %.loc10_20: {.x: ()} = struct_literal (%.loc10_19) -// CHECK:STDOUT: assign file.%c.var, -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_export_in_impl.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_export_export_class.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %.1: type = tuple_type () [template] -// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .c = %c -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.ref: = name_ref C, [template = ] -// CHECK:STDOUT: %c.var: ref = var c -// CHECK:STDOUT: %c: ref = bind_name c, %c.var -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @__global_init() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc8_19: () = tuple_literal () -// CHECK:STDOUT: %.loc8_20: {.x: ()} = struct_literal (%.loc8_19) -// CHECK:STDOUT: assign file.%c.var, -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_use_export_export_class.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %.1: type = tuple_type () [template] -// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .c = %c -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.ref: = name_ref C, [template = ] -// CHECK:STDOUT: %c.var: ref = var c -// CHECK:STDOUT: %c: ref = bind_name c, %c.var -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @__global_init() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc10_19: () = tuple_literal () -// CHECK:STDOUT: %.loc10_20: {.x: ()} = struct_literal (%.loc10_19) -// CHECK:STDOUT: assign file.%c.var, -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- import_both.carbon +// CHECK:STDOUT: --- use_export.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [template] @@ -283,7 +401,11 @@ alias Local = C; // CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] // CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] // CHECK:STDOUT: %tuple: () = tuple_value () [template] -// CHECK:STDOUT: %struct: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %struct.1: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.4: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: %.5: type = ptr_type {.y: ()} [template] +// CHECK:STDOUT: %struct.2: NSC = struct_value (%tuple) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -291,6 +413,235 @@ alias Local = C; // CHECK:STDOUT: .C = %import_ref.1 // CHECK:STDOUT: .NS = %NS // CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .nsc = %nsc +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+3, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir1, inst+21, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %NS.ref: = name_ref NS, %NS [template = %NS] +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+20, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir1, inst+19, unloaded +// CHECK:STDOUT: %NSC.ref: type = name_ref NSC, %import_ref.3 [template = constants.%NSC] +// CHECK:STDOUT: %nsc.var: ref NSC = var nsc +// CHECK:STDOUT: %nsc: ref NSC = bind_name nsc, %nsc.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.4 +// CHECK:STDOUT: .x = file.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .y = file.%import_ref.6 +// CHECK:STDOUT: .Self = file.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc6_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc6_20.1: {.x: ()} = struct_literal (%.loc6_19.1) +// CHECK:STDOUT: %.loc6_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc6_19.2: init () = tuple_init () to %.loc6_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.3: init () = converted %.loc6_19.1, %.loc6_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.4: init C = class_init (%.loc6_20.3), file.%c.var [template = constants.%struct.1] +// CHECK:STDOUT: %.loc6_21: init C = converted %.loc6_20.1, %.loc6_20.4 [template = constants.%struct.1] +// CHECK:STDOUT: assign file.%c.var, %.loc6_21 +// CHECK:STDOUT: %.loc7_26.1: () = tuple_literal () +// CHECK:STDOUT: %.loc7_27.1: {.y: ()} = struct_literal (%.loc7_26.1) +// CHECK:STDOUT: %.loc7_27.2: ref () = class_element_access file.%nsc.var, element0 +// CHECK:STDOUT: %.loc7_26.2: init () = tuple_init () to %.loc7_27.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc7_27.3: init () = converted %.loc7_26.1, %.loc7_26.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc7_27.4: init NSC = class_init (%.loc7_27.3), file.%nsc.var [template = constants.%struct.2] +// CHECK:STDOUT: %.loc7_28: init NSC = converted %.loc7_27.1, %.loc7_27.4 [template = constants.%struct.2] +// CHECK:STDOUT: assign file.%nsc.var, %.loc7_28 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export_export.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct.1: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.4: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: %.5: type = ptr_type {.y: ()} [template] +// CHECK:STDOUT: %struct.2: NSC = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .nsc = %nsc +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir0, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir0, inst+3, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir0, inst+21, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir0, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir0, inst+12, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %NS.ref: = name_ref NS, %NS [template = %NS] +// CHECK:STDOUT: %import_ref.6 = import_ref ir0, inst+19, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir0, inst+20, unloaded +// CHECK:STDOUT: %NSC.ref: type = name_ref NSC, %import_ref.3 [template = constants.%NSC] +// CHECK:STDOUT: %nsc.var: ref NSC = var nsc +// CHECK:STDOUT: %nsc: ref NSC = bind_name nsc, %nsc.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.4 +// CHECK:STDOUT: .x = file.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .y = file.%import_ref.6 +// CHECK:STDOUT: .Self = file.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc4_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc4_20.1: {.x: ()} = struct_literal (%.loc4_19.1) +// CHECK:STDOUT: %.loc4_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc4_19.2: init () = tuple_init () to %.loc4_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc4_20.3: init () = converted %.loc4_19.1, %.loc4_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc4_20.4: init C = class_init (%.loc4_20.3), file.%c.var [template = constants.%struct.1] +// CHECK:STDOUT: %.loc4_21: init C = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%struct.1] +// CHECK:STDOUT: assign file.%c.var, %.loc4_21 +// CHECK:STDOUT: %.loc5_26.1: () = tuple_literal () +// CHECK:STDOUT: %.loc5_27.1: {.y: ()} = struct_literal (%.loc5_26.1) +// CHECK:STDOUT: %.loc5_27.2: ref () = class_element_access file.%nsc.var, element0 +// CHECK:STDOUT: %.loc5_26.2: init () = tuple_init () to %.loc5_27.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc5_27.3: init () = converted %.loc5_26.1, %.loc5_26.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc5_27.4: init NSC = class_init (%.loc5_27.3), file.%nsc.var [template = constants.%struct.2] +// CHECK:STDOUT: %.loc5_28: init NSC = converted %.loc5_27.1, %.loc5_27.4 [template = constants.%struct.2] +// CHECK:STDOUT: assign file.%nsc.var, %.loc5_28 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- use_export_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct.1: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.4: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: %.5: type = ptr_type {.y: ()} [template] +// CHECK:STDOUT: %struct.2: NSC = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .nsc = %nsc +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+3, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir1, inst+21, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %NS.ref: = name_ref NS, %NS [template = %NS] +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+19, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir1, inst+20, unloaded +// CHECK:STDOUT: %NSC.ref: type = name_ref NSC, %import_ref.3 [template = constants.%NSC] +// CHECK:STDOUT: %nsc.var: ref NSC = var nsc +// CHECK:STDOUT: %nsc: ref NSC = bind_name nsc, %nsc.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.4 +// CHECK:STDOUT: .x = file.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .y = file.%import_ref.6 +// CHECK:STDOUT: .Self = file.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc6_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc6_20.1: {.x: ()} = struct_literal (%.loc6_19.1) +// CHECK:STDOUT: %.loc6_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc6_19.2: init () = tuple_init () to %.loc6_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.3: init () = converted %.loc6_19.1, %.loc6_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc6_20.4: init C = class_init (%.loc6_20.3), file.%c.var [template = constants.%struct.1] +// CHECK:STDOUT: %.loc6_21: init C = converted %.loc6_20.1, %.loc6_20.4 [template = constants.%struct.1] +// CHECK:STDOUT: assign file.%c.var, %.loc6_21 +// CHECK:STDOUT: %.loc7_26.1: () = tuple_literal () +// CHECK:STDOUT: %.loc7_27.1: {.y: ()} = struct_literal (%.loc7_26.1) +// CHECK:STDOUT: %.loc7_27.2: ref () = class_element_access file.%nsc.var, element0 +// CHECK:STDOUT: %.loc7_26.2: init () = tuple_init () to %.loc7_27.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc7_27.3: init () = converted %.loc7_26.1, %.loc7_26.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc7_27.4: init NSC = class_init (%.loc7_27.3), file.%nsc.var [template = constants.%struct.2] +// CHECK:STDOUT: %.loc7_28: init NSC = converted %.loc7_27.1, %.loc7_27.4 [template = constants.%struct.2] +// CHECK:STDOUT: assign file.%nsc.var, %.loc7_28 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_export_ns.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1 = import_ref ir1, inst+1, unloaded +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+11, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_export_member.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+11, loaded @@ -300,9 +651,6 @@ alias Local = C; // CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+12, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+7, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+2, unloaded -// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] -// CHECK:STDOUT: %c.var: ref C = var c -// CHECK:STDOUT: %c: ref C = bind_name c, %c.var // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { @@ -311,20 +659,203 @@ alias Local = C; // CHECK:STDOUT: .Self = file.%import_ref.5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_import_both.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct.1: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.4: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: %.5: type = ptr_type {.y: ()} [template] +// CHECK:STDOUT: %struct.2: NSC = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .nsc = %nsc +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+11, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir1, inst+12, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir2, inst+13, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir2, inst+21, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+7, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %NS.ref: = name_ref NS, %NS [template = %NS] +// CHECK:STDOUT: %import_ref.8 = import_ref ir1, inst+13, unloaded +// CHECK:STDOUT: %import_ref.9 = import_ref ir1, inst+17, unloaded +// CHECK:STDOUT: %NSC.ref: type = name_ref NSC, %import_ref.3 [template = constants.%NSC] +// CHECK:STDOUT: %nsc.var: ref NSC = var nsc +// CHECK:STDOUT: %nsc: ref NSC = bind_name nsc, %nsc.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .x = file.%import_ref.6 +// CHECK:STDOUT: .Self = file.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.8 +// CHECK:STDOUT: .y = file.%import_ref.9 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc7_19.1: () = tuple_literal () -// CHECK:STDOUT: %.loc7_20.1: {.x: ()} = struct_literal (%.loc7_19.1) -// CHECK:STDOUT: %.loc7_20.2: ref () = class_element_access file.%c.var, element0 -// CHECK:STDOUT: %.loc7_19.2: init () = tuple_init () to %.loc7_20.2 [template = constants.%tuple] -// CHECK:STDOUT: %.loc7_20.3: init () = converted %.loc7_19.1, %.loc7_19.2 [template = constants.%tuple] -// CHECK:STDOUT: %.loc7_20.4: init C = class_init (%.loc7_20.3), file.%c.var [template = constants.%struct] -// CHECK:STDOUT: %.loc7_21: init C = converted %.loc7_20.1, %.loc7_20.4 [template = constants.%struct] -// CHECK:STDOUT: assign file.%c.var, %.loc7_21 +// CHECK:STDOUT: %.loc39_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc39_20.1: {.x: ()} = struct_literal (%.loc39_19.1) +// CHECK:STDOUT: %.loc39_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc39_19.2: init () = tuple_init () to %.loc39_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc39_20.3: init () = converted %.loc39_19.1, %.loc39_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc39_20.4: init C = class_init (%.loc39_20.3), file.%c.var [template = constants.%struct.1] +// CHECK:STDOUT: %.loc39_21: init C = converted %.loc39_20.1, %.loc39_20.4 [template = constants.%struct.1] +// CHECK:STDOUT: assign file.%c.var, %.loc39_21 +// CHECK:STDOUT: %.loc40_26.1: () = tuple_literal () +// CHECK:STDOUT: %.loc40_27.1: {.y: ()} = struct_literal (%.loc40_26.1) +// CHECK:STDOUT: %.loc40_27.2: ref () = class_element_access file.%nsc.var, element0 +// CHECK:STDOUT: %.loc40_26.2: init () = tuple_init () to %.loc40_27.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc40_27.3: init () = converted %.loc40_26.1, %.loc40_26.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc40_27.4: init NSC = class_init (%.loc40_27.3), file.%nsc.var [template = constants.%struct.2] +// CHECK:STDOUT: %.loc40_28: init NSC = converted %.loc40_27.1, %.loc40_27.4 [template = constants.%struct.2] +// CHECK:STDOUT: assign file.%nsc.var, %.loc40_28 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- import_both_reversed.carbon +// CHECK:STDOUT: --- fail_todo_import_both_reversed.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: %.3: type = ptr_type {.x: ()} [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: %struct.1: C = struct_value (%tuple) [template] +// CHECK:STDOUT: %NSC: type = class_type @NSC [template] +// CHECK:STDOUT: %.4: type = struct_type {.y: ()} [template] +// CHECK:STDOUT: %.5: type = ptr_type {.y: ()} [template] +// CHECK:STDOUT: %struct.2: NSC = struct_value (%tuple) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: .nsc = %nsc +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+3, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3: type = import_ref ir1, inst+21, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref ir2, inst+1, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir2, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref ir1, inst+11, unloaded +// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %c.var: ref C = var c +// CHECK:STDOUT: %c: ref C = bind_name c, %c.var +// CHECK:STDOUT: %NS.ref: = name_ref NS, %NS [template = %NS] +// CHECK:STDOUT: %import_ref.8 = import_ref ir1, inst+20, unloaded +// CHECK:STDOUT: %import_ref.9 = import_ref ir1, inst+19, unloaded +// CHECK:STDOUT: %NSC.ref: type = name_ref NSC, %import_ref.3 [template = constants.%NSC] +// CHECK:STDOUT: %nsc.var: ref NSC = var nsc +// CHECK:STDOUT: %nsc: ref NSC = bind_name nsc, %nsc.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.6 +// CHECK:STDOUT: .x = file.%import_ref.7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @NSC { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .y = file.%import_ref.8 +// CHECK:STDOUT: .Self = file.%import_ref.9 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc39_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc39_20.1: {.x: ()} = struct_literal (%.loc39_19.1) +// CHECK:STDOUT: %.loc39_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc39_19.2: init () = tuple_init () to %.loc39_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc39_20.3: init () = converted %.loc39_19.1, %.loc39_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc39_20.4: init C = class_init (%.loc39_20.3), file.%c.var [template = constants.%struct.1] +// CHECK:STDOUT: %.loc39_21: init C = converted %.loc39_20.1, %.loc39_20.4 [template = constants.%struct.1] +// CHECK:STDOUT: assign file.%c.var, %.loc39_21 +// CHECK:STDOUT: %.loc40_26.1: () = tuple_literal () +// CHECK:STDOUT: %.loc40_27.1: {.y: ()} = struct_literal (%.loc40_26.1) +// CHECK:STDOUT: %.loc40_27.2: ref () = class_element_access file.%nsc.var, element0 +// CHECK:STDOUT: %.loc40_26.2: init () = tuple_init () to %.loc40_27.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc40_27.3: init () = converted %.loc40_26.1, %.loc40_26.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc40_27.4: init NSC = class_init (%.loc40_27.3), file.%nsc.var [template = constants.%struct.2] +// CHECK:STDOUT: %.loc40_28: init NSC = converted %.loc40_27.1, %.loc40_27.4 [template = constants.%struct.2] +// CHECK:STDOUT: assign file.%nsc.var, %.loc40_28 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_not_reexporting.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Local = %Local +// CHECK:STDOUT: .NSLocal = %NSLocal +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.ref: = name_ref C, [template = ] +// CHECK:STDOUT: %Local: = bind_alias Local, [template = ] +// CHECK:STDOUT: %NS.ref: = name_ref NS, [template = ] +// CHECK:STDOUT: %NSLocal: = bind_alias NSLocal, [template = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- repeat_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %import_ref.1 +// CHECK:STDOUT: .NS = %NS +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: = import_ref ir1, inst+11, loaded +// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { +// CHECK:STDOUT: .NSC = %import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+7, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref ir1, inst+2, unloaded +// CHECK:STDOUT: %C.loc6: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %C.loc7: type = bind_export C, %import_ref.1 [template = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .x = file.%import_ref.4 +// CHECK:STDOUT: .Self = file.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_use_repeat_export.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [template] @@ -338,17 +869,12 @@ alias Local = C; // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [template] { // CHECK:STDOUT: .C = %import_ref.1 -// CHECK:STDOUT: .NS = %NS // CHECK:STDOUT: .c = %c // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.1: type = import_ref ir2, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: = import_ref ir2, inst+11, loaded -// CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { -// CHECK:STDOUT: .NSC = %import_ref.3 -// CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref ir2, inst+12, unloaded -// CHECK:STDOUT: %import_ref.4 = import_ref ir2, inst+7, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref ir2, inst+2, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+14, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+12, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref ir1, inst+11, unloaded // CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C] // CHECK:STDOUT: %c.var: ref C = var c // CHECK:STDOUT: %c: ref C = bind_name c, %c.var @@ -356,30 +882,20 @@ alias Local = C; // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = file.%import_ref.3 // CHECK:STDOUT: .x = file.%import_ref.4 -// CHECK:STDOUT: .Self = file.%import_ref.5 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc7_19.1: () = tuple_literal () -// CHECK:STDOUT: %.loc7_20.1: {.x: ()} = struct_literal (%.loc7_19.1) -// CHECK:STDOUT: %.loc7_20.2: ref () = class_element_access file.%c.var, element0 -// CHECK:STDOUT: %.loc7_19.2: init () = tuple_init () to %.loc7_20.2 [template = constants.%tuple] -// CHECK:STDOUT: %.loc7_20.3: init () = converted %.loc7_19.1, %.loc7_19.2 [template = constants.%tuple] -// CHECK:STDOUT: %.loc7_20.4: init C = class_init (%.loc7_20.3), file.%c.var [template = constants.%struct] -// CHECK:STDOUT: %.loc7_21: init C = converted %.loc7_20.1, %.loc7_20.4 [template = constants.%struct] -// CHECK:STDOUT: assign file.%c.var, %.loc7_21 +// CHECK:STDOUT: %.loc24_19.1: () = tuple_literal () +// CHECK:STDOUT: %.loc24_20.1: {.x: ()} = struct_literal (%.loc24_19.1) +// CHECK:STDOUT: %.loc24_20.2: ref () = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc24_19.2: init () = tuple_init () to %.loc24_20.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc24_20.3: init () = converted %.loc24_19.1, %.loc24_19.2 [template = constants.%tuple] +// CHECK:STDOUT: %.loc24_20.4: init C = class_init (%.loc24_20.3), file.%c.var [template = constants.%struct] +// CHECK:STDOUT: %.loc24_21: init C = converted %.loc24_20.1, %.loc24_20.4 [template = constants.%struct] +// CHECK:STDOUT: assign file.%c.var, %.loc24_21 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_non_export_class.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .Local = %Local -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.ref: = name_ref C, [template = ] -// CHECK:STDOUT: %Local: = bind_alias Local, [template = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/var/no_prelude/export_name.carbon b/toolchain/check/testdata/var/no_prelude/export_name.carbon new file mode 100644 index 000000000000..00be38fab0b2 --- /dev/null +++ b/toolchain/check/testdata/var/no_prelude/export_name.carbon @@ -0,0 +1,103 @@ +// 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 +// +// AUTOUPDATE + +// ============================================================================ +// Setup files +// ============================================================================ + +// --- base.carbon + +library "base" api; + +var v: (); + +// --- export.carbon + +library "export" api; + +import library "base"; + +export v; + +// ============================================================================ +// Test files +// ============================================================================ + +// --- fail_todo_use_export.carbon + +library "use_export" api; + +// CHECK:STDERR: fail_todo_use_export.carbon:[[@LINE+9]]:1: In import. +// CHECK:STDERR: import library "export"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: export.carbon:4:1: In import. +// CHECK:STDERR: import library "base"; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: base.carbon:4:5: ERROR: Semantics TODO: `Non-constant ImportRefLoaded (comes up with var)`. +// CHECK:STDERR: var v: (); +// CHECK:STDERR: ^ +import library "export"; + +var w: () = v; + +// CHECK:STDOUT: --- base.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .v = %v +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc4_9.1: () = tuple_literal () +// CHECK:STDOUT: %.loc4_9.2: type = converted %.loc4_9.1, constants.%.1 [template = constants.%.1] +// CHECK:STDOUT: %v.var: ref () = var v +// CHECK:STDOUT: %v: ref () = bind_name v, %v.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .v = %import_ref +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref: ref () = import_ref ir1, inst+5, loaded +// CHECK:STDOUT: %v: ref () = bind_export v, %import_ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_use_export.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %tuple: () = tuple_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .v = %import_ref +// CHECK:STDOUT: .w = %w +// CHECK:STDOUT: } +// CHECK:STDOUT: %import_ref: ref () = import_ref ir1, inst+3, loaded [template = ] +// CHECK:STDOUT: %.loc15_9.1: () = tuple_literal () +// CHECK:STDOUT: %.loc15_9.2: type = converted %.loc15_9.1, constants.%.1 [template = constants.%.1] +// CHECK:STDOUT: %w.var: ref () = var w +// CHECK:STDOUT: %w: ref () = bind_name w, %w.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %v.ref: ref () = name_ref v, file.%import_ref [template = ] +// CHECK:STDOUT: %.loc15_13: init () = tuple_init () to file.%w.var [template = constants.%tuple] +// CHECK:STDOUT: %.loc15_14: init () = converted %v.ref, %.loc15_13 [template = constants.%tuple] +// CHECK:STDOUT: assign file.%w.var, %.loc15_14 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 909ecdd61308..704864388dd8 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -201,6 +201,10 @@ CARBON_DIAGNOSTIC_KIND(ClassSpecificDeclRepeated) CARBON_DIAGNOSTIC_KIND(ClassIncompleteWithinDefinition) CARBON_DIAGNOSTIC_KIND(ConstructionOfAbstractClass) +// Export checking. +CARBON_DIAGNOSTIC_KIND(ExportNotImportedEntity) +CARBON_DIAGNOSTIC_KIND(ExportNotImportedEntitySource) + // Interface checking. CARBON_DIAGNOSTIC_KIND(InterfacePreviousDefinition) CARBON_DIAGNOSTIC_KIND(InterfaceRedefinition) diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index fe1af484a31f..464be8a7cd83 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -88,6 +88,16 @@ auto HandleBindAlias(FunctionContext& context, SemIR::InstId inst_id, context.SetLocal(inst_id, context.GetValue(inst.value_id)); } +auto HandleBindExport(FunctionContext& context, SemIR::InstId inst_id, + SemIR::BindExport inst) -> void { + auto type_inst_id = context.sem_ir().types().GetInstId(inst.type_id); + if (type_inst_id == SemIR::InstId::BuiltinNamespaceType) { + return; + } + + context.SetLocal(inst_id, context.GetValue(inst.value_id)); +} + auto HandleBindName(FunctionContext& context, SemIR::InstId inst_id, SemIR::BindName inst) -> void { context.SetLocal(inst_id, context.GetValue(inst.value_id)); diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index b764d87cb03a..fe2a8c610ddf 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -266,6 +266,7 @@ static auto StringifyTypeExprImpl(const SemIR::File& outer_sem_ir, break; } case BindAlias::Kind: + case BindExport::Kind: case BindSymbolicName::Kind: { auto name_id = untyped_inst.As().bind_name_id; out << sem_ir.names().GetFormatted( @@ -534,6 +535,10 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory { inst_id = inst.value_id; continue; } + case CARBON_KIND(BindExport inst): { + inst_id = inst.value_id; + continue; + } case CARBON_KIND(NameRef inst): { inst_id = inst.value_id; continue; diff --git a/toolchain/sem_ir/inst_kind.def b/toolchain/sem_ir/inst_kind.def index 02053822fdd9..c6238c031aff 100644 --- a/toolchain/sem_ir/inst_kind.def +++ b/toolchain/sem_ir/inst_kind.def @@ -85,6 +85,7 @@ CARBON_SEM_IR_INST_KIND_IMPL(AssociatedEntityType, TYPE_ALWAYS, CONSTANT_CONDITIONAL) CARBON_SEM_IR_INST_KIND_IMPL(BaseDecl, TYPE_NEVER, CONSTANT_ALWAYS) CARBON_SEM_IR_INST_KIND_IMPL(BindAlias, TYPE_NEVER, CONSTANT_NEVER) +CARBON_SEM_IR_INST_KIND_IMPL(BindExport, TYPE_NEVER, CONSTANT_NEVER) CARBON_SEM_IR_INST_KIND_IMPL(BindName, TYPE_NEVER, CONSTANT_NEVER) CARBON_SEM_IR_INST_KIND_IMPL(BindSymbolicName, TYPE_MAYBE, CONSTANT_SYMBOLIC_ONLY) diff --git a/toolchain/sem_ir/inst_namer.cpp b/toolchain/sem_ir/inst_namer.cpp index 5e247e973a54..e81bc24cf7dd 100644 --- a/toolchain/sem_ir/inst_namer.cpp +++ b/toolchain/sem_ir/inst_namer.cpp @@ -391,6 +391,7 @@ auto InstNamer::CollectNamesInBlock(ScopeId scope_id, continue; } case BindAlias::Kind: + case BindExport::Kind: case BindName::Kind: case BindSymbolicName::Kind: { auto inst = untyped_inst.As(); diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index d36f0ec24b27..98b974439c40 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -222,7 +222,8 @@ struct BaseDecl { // Common representation for both kinds of `bind*name` node. struct AnyBindName { // TODO: Also handle BindTemplateName once it exists. - static constexpr InstKind Kinds[] = {InstKind::BindAlias, InstKind::BindName, + static constexpr InstKind Kinds[] = {InstKind::BindAlias, + InstKind::BindExport, InstKind::BindName, InstKind::BindSymbolicName}; InstKind kind; @@ -240,6 +241,15 @@ struct BindAlias { InstId value_id; }; +struct BindExport { + static constexpr auto Kind = + InstKind::BindExport.Define("bind_export"); + + TypeId type_id; + BindNameId bind_name_id; + InstId value_id; +}; + struct BindName { // TODO: Make Parse::NodeId more specific. static constexpr auto Kind = @@ -522,6 +532,9 @@ struct AnyImportRef { InstKind kind; ImportIRInstId import_ir_inst_id; + // A BindName is currently only set on directly imported names. It is not + // generically available. + BindNameId bind_name_id; }; // An imported entity that is not yet been loaded. @@ -531,6 +544,7 @@ struct ImportRefUnloaded { InstKind::ImportRefUnloaded.Define("import_ref"); ImportIRInstId import_ir_inst_id; + BindNameId bind_name_id; }; // A imported entity that is loaded, and may be used. @@ -541,6 +555,7 @@ struct ImportRefLoaded { TypeId type_id; ImportIRInstId import_ir_inst_id; + BindNameId bind_name_id; }; // Finalizes the initialization of `dest_id` from the initializer expression