mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:30:12 +01:00
Initial 'export name' handling. (#3949)
This adds a `BindExport` instruction in order to better track the location of the `export` itself, but a `bind_name_id` is also added to `ImportRef` so that we know quickly where to put it in name lookup. Merging identical names is a TODO. I haven't quite decided how best to achieve that, because I do think the BindExport should be what's actually added to name lookup. Also, I will probably add a mode to DeclNameStack that blocks non-namespace scopes. This seems to already be an error, but the wrong one (maybe due to lack of support for cross-file decl/def support).
This commit is contained in:
@@ -87,6 +87,13 @@ class SemIRDiagnosticConverter : public DiagnosticConverter<SemIRLoc> {
|
||||
|
||||
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<SemIR::BindExport>();
|
||||
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<SemIRLoc> {
|
||||
|
||||
// If a namespace has an instruction for an import, switch to looking at
|
||||
// it.
|
||||
if (auto ns =
|
||||
cursor_ir->insts().TryGetAs<SemIR::Namespace>(cursor_inst_id)) {
|
||||
if (auto ns = cursor_inst.TryAs<SemIR::Namespace>()) {
|
||||
if (ns->import_id.is_valid()) {
|
||||
cursor_inst_id = ns->import_id;
|
||||
continue;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<SemIR::ImportRefLoaded>(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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<SemIR::NameId, SemIR::NameScopeId> {
|
||||
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<SemIR::AnyBindName>();
|
||||
@@ -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<SemIR::NameScopeId, SemIR::NameScopeId> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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> = 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> = 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> = 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> = 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> = 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: <error> = name_ref C, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %c.var: ref <error> = var c
|
||||
// CHECK:STDOUT: %c: ref <error> = 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, <error>
|
||||
// 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> = 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:
|
||||
@@ -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> = 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> = 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> = 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:
|
||||
@@ -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> = 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> = 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> = 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:
|
||||
@@ -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> = 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> = 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> = 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:
|
||||
@@ -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> = 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: <unbound element of class C> = 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: <unbound element of class D> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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: <error> = name_ref D, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %d.var: ref <error> = var d
|
||||
// CHECK:STDOUT: %d: ref <error> = 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, <error>
|
||||
// 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> = 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> = 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:
|
||||
+715
-199
File diff suppressed because it is too large
Load Diff
@@ -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> = 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> = 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> = 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 = <error>]
|
||||
// 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 = <error>]
|
||||
// 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:
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<AnyBindName>().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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<AnyBindName>();
|
||||
|
||||
@@ -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<Parse::NodeId>("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<Parse::InvalidNodeId>("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
|
||||
|
||||
Reference in New Issue
Block a user