mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:11:12 +01:00
Add export keyword handling. (#3944)
This provides `export import` logic in lex, parse, and check; `export name` logic is only in lex and parse, not check. I think with `export name` I'm going to need to modify import_ref and some consolidation logic, whereas `export import` seems feasible to keep as primarily import logic. Given the implementations were looking like they'd diverge more substantially, I thought it'd be helpful to cut the PR here.
This commit is contained in:
+82
-25
@@ -200,6 +200,82 @@ struct UnitInfo {
|
||||
UnitInfo* api_for_impl = nullptr;
|
||||
};
|
||||
|
||||
// Imports the current package.
|
||||
static auto ImportCurrentPackage(Context& context, UnitInfo& unit_info,
|
||||
int total_ir_count,
|
||||
SemIR::InstId package_inst_id,
|
||||
SemIR::TypeId namespace_type_id) -> void {
|
||||
// Add imports from the current package.
|
||||
auto self_import = unit_info.package_imports_map.find(IdentifierId::Invalid);
|
||||
if (self_import == unit_info.package_imports_map.end()) {
|
||||
// Push the scope; there are no names to add.
|
||||
context.scope_stack().Push(package_inst_id, SemIR::NameScopeId::Package);
|
||||
return;
|
||||
}
|
||||
|
||||
// Track whether an IR was imported in full, including `export import`. This
|
||||
// distinguishes from IRs that are indirectly added without all names being
|
||||
// exported to this IR.
|
||||
llvm::SmallVector<bool> imported_irs(total_ir_count, false);
|
||||
if (self_import->second.has_load_error) {
|
||||
context.name_scopes().Get(SemIR::NameScopeId::Package).has_error = true;
|
||||
}
|
||||
|
||||
for (const auto& import : self_import->second.imports) {
|
||||
const auto& import_sem_ir = **import.unit_info->unit->sem_ir;
|
||||
|
||||
auto& imported_ir = imported_irs[import_sem_ir.check_ir_id().index];
|
||||
if (!imported_ir) {
|
||||
imported_ir = true;
|
||||
|
||||
// Import the IR and its exported imports.
|
||||
ImportLibraryFromCurrentPackage(context, namespace_type_id,
|
||||
import.names.node_id, import_sem_ir,
|
||||
import.names.is_export);
|
||||
|
||||
for (const auto& indirect_ir : import_sem_ir.import_irs().array_ref()) {
|
||||
if (indirect_ir.is_export) {
|
||||
auto& imported_indirect_ir =
|
||||
imported_irs[indirect_ir.sem_ir->check_ir_id().index];
|
||||
if (!imported_indirect_ir) {
|
||||
imported_indirect_ir = true;
|
||||
|
||||
ImportLibraryFromCurrentPackage(
|
||||
context, namespace_type_id, import.names.node_id,
|
||||
*indirect_ir.sem_ir, import.names.is_export);
|
||||
} else if (import.names.is_export) {
|
||||
// The indirect IR was previously indirectly imported, but it's
|
||||
// found through `export import`. We need to mark it for re-export.
|
||||
context.import_irs()
|
||||
.Get(context.check_ir_map()[indirect_ir.sem_ir->check_ir_id()
|
||||
.index])
|
||||
.is_export = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (import.names.is_export) {
|
||||
// The IR was previously indirectly imported, but it's `export import`.
|
||||
// We need to mark it -- and transitive `export import`s -- for re-export.
|
||||
context.import_irs()
|
||||
.Get(context.check_ir_map()[import_sem_ir.check_ir_id().index])
|
||||
.is_export = true;
|
||||
|
||||
for (const auto& indirect_ir : import_sem_ir.import_irs().array_ref()) {
|
||||
if (indirect_ir.is_export) {
|
||||
context.import_irs()
|
||||
.Get(context
|
||||
.check_ir_map()[indirect_ir.sem_ir->check_ir_id().index])
|
||||
.is_export = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.scope_stack().Push(
|
||||
package_inst_id, SemIR::NameScopeId::Package,
|
||||
context.name_scopes().Get(SemIR::NameScopeId::Package).has_error);
|
||||
}
|
||||
|
||||
// Add imports to the root block.
|
||||
static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info,
|
||||
int total_ir_count) -> void {
|
||||
@@ -248,30 +324,8 @@ static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info,
|
||||
{.node_id = Parse::InvalidNodeId(), .sem_ir = nullptr});
|
||||
}
|
||||
|
||||
// Add imports from the current package.
|
||||
auto self_import = unit_info.package_imports_map.find(IdentifierId::Invalid);
|
||||
if (self_import != unit_info.package_imports_map.end()) {
|
||||
bool error_in_import = self_import->second.has_load_error;
|
||||
for (const auto& import : self_import->second.imports) {
|
||||
const auto& import_sem_ir = **import.unit_info->unit->sem_ir;
|
||||
ImportLibraryFromCurrentPackage(context, namespace_type_id,
|
||||
import.names.node_id, import_sem_ir);
|
||||
error_in_import |= import_sem_ir.name_scopes()
|
||||
.Get(SemIR::NameScopeId::Package)
|
||||
.has_error;
|
||||
}
|
||||
|
||||
// If an import of the current package caused an error for the imported
|
||||
// file, it transitively affects the current file too.
|
||||
if (error_in_import) {
|
||||
context.name_scopes().Get(SemIR::NameScopeId::Package).has_error = true;
|
||||
}
|
||||
context.scope_stack().Push(package_inst_id, SemIR::NameScopeId::Package,
|
||||
error_in_import);
|
||||
} else {
|
||||
// Push the scope; there are no names to add.
|
||||
context.scope_stack().Push(package_inst_id, SemIR::NameScopeId::Package);
|
||||
}
|
||||
ImportCurrentPackage(context, unit_info, total_ir_count, package_inst_id,
|
||||
namespace_type_id);
|
||||
CARBON_CHECK(context.scope_stack().PeekIndex() == ScopeIndex::Package);
|
||||
|
||||
for (auto& [package_id, package_imports] : unit_info.package_imports_map) {
|
||||
@@ -283,7 +337,10 @@ static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info,
|
||||
llvm::SmallVector<SemIR::ImportIR> import_irs;
|
||||
for (auto import : package_imports.imports) {
|
||||
import_irs.push_back({.node_id = import.names.node_id,
|
||||
.sem_ir = &**import.unit_info->unit->sem_ir});
|
||||
.sem_ir = &**import.unit_info->unit->sem_ir,
|
||||
.is_export = false});
|
||||
CARBON_CHECK(!import.names.is_export)
|
||||
<< "Imports from other packages can't be exported.";
|
||||
}
|
||||
ImportLibrariesFromOtherPackage(context, namespace_type_id,
|
||||
package_imports.node_id, package_id,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// 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
|
||||
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/parse/typed_nodes.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
auto HandleExportIntroducer(Context& /*context*/,
|
||||
Parse::ExportIntroducerId /*node_id*/) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleExportDirective(Context& context, Parse::ExportDirectiveId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "ExportDirective");
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
@@ -14,6 +14,11 @@ auto HandleImportIntroducer(Context& /*context*/,
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleImportExport(Context& /*context*/, Parse::ImportExportId /*node_id*/)
|
||||
-> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleImportDirective(Context& /*context*/,
|
||||
Parse::ImportDirectiveId /*node_id*/) -> bool {
|
||||
return true;
|
||||
|
||||
@@ -213,9 +213,11 @@ static auto CopyEnclosingNameScopesFromImportIR(
|
||||
auto ImportLibraryFromCurrentPackage(Context& context,
|
||||
SemIR::TypeId namespace_type_id,
|
||||
Parse::ImportDirectiveId node_id,
|
||||
const SemIR::File& import_sem_ir) -> void {
|
||||
auto ir_id =
|
||||
AddImportIR(context, {.node_id = node_id, .sem_ir = &import_sem_ir});
|
||||
const SemIR::File& import_sem_ir,
|
||||
bool is_export) -> void {
|
||||
auto ir_id = AddImportIR(
|
||||
context,
|
||||
{.node_id = node_id, .sem_ir = &import_sem_ir, .is_export = is_export});
|
||||
|
||||
context.import_ir_constant_values()[ir_id.index].Set(
|
||||
SemIR::InstId::PackageNamespace,
|
||||
@@ -257,6 +259,12 @@ auto ImportLibraryFromCurrentPackage(Context& context,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If an import of the current package caused an error for the imported
|
||||
// file, it transitively affects the current file too.
|
||||
if (import_sem_ir.name_scopes().Get(SemIR::NameScopeId::Package).has_error) {
|
||||
context.name_scopes().Get(SemIR::NameScopeId::Package).has_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto ImportLibrariesFromOtherPackage(Context& context,
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace Carbon::Check {
|
||||
auto ImportLibraryFromCurrentPackage(Context& context,
|
||||
SemIR::TypeId namespace_type_id,
|
||||
Parse::ImportDirectiveId node_id,
|
||||
const SemIR::File& import_sem_ir) -> void;
|
||||
const SemIR::File& import_sem_ir,
|
||||
bool is_export) -> void;
|
||||
|
||||
// Adds another package's imports to name lookup, with all libraries together.
|
||||
// This only adds the package name to lookup, so that `package.ImportedPackage`
|
||||
|
||||
@@ -44,6 +44,10 @@ auto AddImportIR(Context& context, SemIR::ImportIR import_ir)
|
||||
if (!ir_id.is_valid()) {
|
||||
// Note this updates check_ir_map.
|
||||
ir_id = InternalAddImportIR(context, import_ir);
|
||||
} else if (import_ir.is_export) {
|
||||
// We're processing an `export import`. In case the IR was indirectly added
|
||||
// as a non-export, mark it as an export.
|
||||
context.import_irs().Get(ir_id).is_export = true;
|
||||
}
|
||||
return ir_id;
|
||||
}
|
||||
@@ -246,8 +250,9 @@ class ImportRefResolver {
|
||||
cursor_ir_id = context_.check_ir_map()[cursor_ir->check_ir_id().index];
|
||||
if (!cursor_ir_id.is_valid()) {
|
||||
// TODO: Should we figure out a location to assign here?
|
||||
cursor_ir_id = AddImportIR(
|
||||
context_, {.node_id = Parse::NodeId::Invalid, .sem_ir = cursor_ir});
|
||||
cursor_ir_id = AddImportIR(context_, {.node_id = Parse::NodeId::Invalid,
|
||||
.sem_ir = cursor_ir,
|
||||
.is_export = false});
|
||||
}
|
||||
cursor_inst_id = ir_inst.inst_id;
|
||||
|
||||
|
||||
@@ -0,0 +1,726 @@
|
||||
// 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: ();
|
||||
};
|
||||
|
||||
// --- export.carbon
|
||||
|
||||
library "export" api;
|
||||
|
||||
export import library "base";
|
||||
|
||||
// --- export_copy.carbon
|
||||
|
||||
library "export_copy" api;
|
||||
|
||||
export import library "base";
|
||||
|
||||
// --- non_export.carbon
|
||||
|
||||
library "non_export" api;
|
||||
|
||||
import library "export";
|
||||
|
||||
// --- export_export.carbon
|
||||
|
||||
library "export_export" api;
|
||||
|
||||
export import library "export";
|
||||
|
||||
// --- import_then_export.carbon
|
||||
|
||||
library "import_then_export" api;
|
||||
|
||||
import library "base";
|
||||
export import library "export";
|
||||
|
||||
// --- export_in_impl.carbon
|
||||
|
||||
// This is just providing an API for the implicit import.
|
||||
library "export_in_impl" api;
|
||||
|
||||
// ============================================================================
|
||||
// Test files
|
||||
// ============================================================================
|
||||
|
||||
// --- use_export.carbon
|
||||
|
||||
library "use_export" api;
|
||||
|
||||
import library "export";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- fail_export_in_impl.impl.carbon
|
||||
|
||||
library "export_in_impl" impl;
|
||||
|
||||
// CHECK:STDERR: fail_export_in_impl.impl.carbon:[[@LINE+4]]:1: ERROR: `export` is only allowed in API files.
|
||||
// CHECK:STDERR: export import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
export import library "base";
|
||||
|
||||
// Note the import still occurs.
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- export_export.impl.carbon
|
||||
|
||||
library "export_export" impl;
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- use_export_export.carbon
|
||||
|
||||
library "use_export_export" api;
|
||||
|
||||
import library "export_export";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- use_import_then_export.carbon
|
||||
|
||||
library "use_import_then_export" api;
|
||||
|
||||
import library "import_then_export";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- use_import_when_export.carbon
|
||||
|
||||
library "use_import_when_export" api;
|
||||
|
||||
export import library "base";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- use_base_and_export.carbon
|
||||
|
||||
library "use_base_and_export" api;
|
||||
|
||||
import library "base";
|
||||
import library "export";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- use_export_and_base.carbon
|
||||
|
||||
library "import_both_reversed" api;
|
||||
|
||||
import library "export";
|
||||
import library "base";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- use_export_copy.carbon
|
||||
|
||||
library "use_export_copy" api;
|
||||
|
||||
import library "export";
|
||||
import library "export_copy";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- fail_use_non_export.carbon
|
||||
|
||||
library "fail_use_non_export" api;
|
||||
|
||||
import library "non_export";
|
||||
|
||||
// CHECK:STDERR: fail_use_non_export.carbon:[[@LINE+3]]:15: ERROR: Name `C` not found.
|
||||
// CHECK:STDERR: alias Local = C;
|
||||
// CHECK:STDERR: ^
|
||||
alias Local = C;
|
||||
|
||||
// --- use_non_export_then_base.carbon
|
||||
|
||||
library "use_non_export_then_base" api;
|
||||
|
||||
import library "non_export";
|
||||
export import library "base";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- indirect_use_non_export_then_base.carbon
|
||||
|
||||
library "indirect_use_non_export_then_base" api;
|
||||
|
||||
import library "use_non_export_then_base";
|
||||
|
||||
var indirect_c: C = {.x = ()};
|
||||
|
||||
// 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: }
|
||||
// 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: %.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: --- export.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+1, unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- export_copy.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+1, unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- non_export.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 ir2, inst+1, unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- export_export.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 ir2, inst+1, unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_then_export.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+1, unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- export_in_impl.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
|
||||
// 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 = 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = 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_export_in_impl.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: 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc11_19.1: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc11_20.1: {.x: ()} = struct_literal (%.loc11_19.1)
|
||||
// CHECK:STDOUT: %.loc11_20.2: ref () = class_element_access file.%c.var, element0
|
||||
// CHECK:STDOUT: %.loc11_19.2: init () = tuple_init () to %.loc11_20.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc11_20.3: init () = converted %.loc11_19.1, %.loc11_19.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc11_20.4: init C = class_init (%.loc11_20.3), file.%c.var [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc11_21: init C = converted %.loc11_20.1, %.loc11_20.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%c.var, %.loc11_21
|
||||
// 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: 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.3
|
||||
// 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]
|
||||
// CHECK:STDOUT: %.loc4_21: init C = converted %.loc4_20.1, %.loc4_20.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%c.var, %.loc4_21
|
||||
// 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: 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 ir3, inst+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir3, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir3, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = 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_import_then_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: 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = 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_import_when_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: 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = 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_base_and_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: 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.3
|
||||
// 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: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_export_and_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 = 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.3
|
||||
// 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: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_export_copy.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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.3
|
||||
// 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: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_use_non_export.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Local = %Local
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.ref: <error> = name_ref C, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %Local: <error> = bind_alias Local, <error> [template = <error>]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_non_export_then_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 = 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+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+7, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, 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 {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .x = file.%import_ref.2
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.3
|
||||
// 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: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- indirect_use_non_export_then_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 = 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 = %import_ref.2
|
||||
// CHECK:STDOUT: .indirect_c = %indirect_c
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref.1 = import_ref ir1, inst+13, unloaded
|
||||
// CHECK:STDOUT: %import_ref.2: type = import_ref ir2, inst+1, loaded [template = constants.%C]
|
||||
// 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.ref: type = name_ref C, %import_ref.2 [template = constants.%C]
|
||||
// CHECK:STDOUT: %indirect_c.var: ref C = var indirect_c
|
||||
// CHECK:STDOUT: %indirect_c: ref C = bind_name indirect_c, %indirect_c.var
|
||||
// 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: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc6_28.1: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc6_29.1: {.x: ()} = struct_literal (%.loc6_28.1)
|
||||
// CHECK:STDOUT: %.loc6_29.2: ref () = class_element_access file.%indirect_c.var, element0
|
||||
// CHECK:STDOUT: %.loc6_28.2: init () = tuple_init () to %.loc6_29.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc6_29.3: init () = converted %.loc6_28.1, %.loc6_28.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc6_29.4: init C = class_init (%.loc6_29.3), file.%indirect_c.var [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc6_30: init C = converted %.loc6_29.1, %.loc6_29.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%indirect_c.var, %.loc6_30
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -0,0 +1,385 @@
|
||||
// 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
|
||||
// ============================================================================
|
||||
|
||||
// --- class.carbon
|
||||
|
||||
library "class" api;
|
||||
|
||||
class C {
|
||||
var x: ();
|
||||
};
|
||||
|
||||
namespace NS;
|
||||
class NS.NSC {
|
||||
var x: ();
|
||||
};
|
||||
|
||||
// --- fail_todo_export_class.carbon
|
||||
|
||||
library "export_class" 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:
|
||||
export C;
|
||||
|
||||
// --- non_export_class.carbon
|
||||
|
||||
library "non_export_class" api;
|
||||
|
||||
import library "export_class";
|
||||
|
||||
// --- fail_todo_export_export_class.carbon
|
||||
|
||||
library "export_export_class" 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:
|
||||
export C;
|
||||
|
||||
// --- export_in_impl.carbon
|
||||
|
||||
// This is just providing an API for the implicit import.
|
||||
library "export_in_impl" api;
|
||||
|
||||
// ============================================================================
|
||||
// Test files
|
||||
// ============================================================================
|
||||
|
||||
// --- fail_todo_use_export_class.carbon
|
||||
|
||||
library "use_export_class" api;
|
||||
|
||||
import library "export_class";
|
||||
|
||||
// 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 = ()};
|
||||
|
||||
// --- fail_todo_export_in_impl.impl.carbon
|
||||
|
||||
library "export_in_impl" 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;
|
||||
// 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;
|
||||
|
||||
// --- fail_todo_export_export_class.impl.carbon
|
||||
|
||||
library "export_export_class" impl;
|
||||
|
||||
// CHECK:STDERR: fail_todo_export_export_class.impl.carbon:[[@LINE+4]]:8: ERROR: Name `C` not found.
|
||||
// CHECK:STDERR: var c: C = {.x = ()};
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
var c: 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
|
||||
|
||||
library "import_both" api;
|
||||
|
||||
import library "class";
|
||||
import library "export_class";
|
||||
|
||||
var c: C = {.x = ()};
|
||||
|
||||
// --- import_both_reversed.carbon
|
||||
|
||||
library "import_both_reversed" api;
|
||||
|
||||
import library "export_class";
|
||||
import library "class";
|
||||
|
||||
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:
|
||||
// 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: %NSC: type = class_type @NSC [template]
|
||||
// CHECK:STDOUT: %.4: type = unbound_element_type NSC, () [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: .NS = %NS
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
|
||||
// CHECK:STDOUT: %NS: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .NSC = %NSC.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %NSC.decl: type = class_decl @NSC [template = constants.%NSC] {}
|
||||
// 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 @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: <unbound element of class NSC> = field_decl x, element0 [template]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%NSC
|
||||
// CHECK:STDOUT: .x = %.loc10_8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_export_class.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- non_export_class.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_export_export_class.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- export_in_impl.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = 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> = namespace [template] {
|
||||
// CHECK:STDOUT: .c = %c
|
||||
// CHECK:STDOUT: }
|
||||
// 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: %.loc10_19: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc10_20: {.x: ()} = struct_literal (%.loc10_19)
|
||||
// CHECK:STDOUT: assign file.%c.var, <error>
|
||||
// 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> = namespace [template] {
|
||||
// CHECK:STDOUT: .c = %c
|
||||
// CHECK:STDOUT: }
|
||||
// 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: %.loc8_19: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc8_20: {.x: ()} = struct_literal (%.loc8_19)
|
||||
// CHECK:STDOUT: assign file.%c.var, <error>
|
||||
// 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> = namespace [template] {
|
||||
// CHECK:STDOUT: .c = %c
|
||||
// CHECK:STDOUT: }
|
||||
// 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: %.loc10_19: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc10_20: {.x: ()} = struct_literal (%.loc10_19)
|
||||
// CHECK:STDOUT: assign file.%c.var, <error>
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- 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: 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: .NS = %NS
|
||||
// CHECK:STDOUT: .c = %c
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+1, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2: <namespace> = import_ref ir1, inst+11, loaded
|
||||
// CHECK:STDOUT: %NS: <namespace> = 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.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: .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: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- 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: 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: .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: <namespace> = import_ref ir2, inst+11, loaded
|
||||
// CHECK:STDOUT: %NS: <namespace> = 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: %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: .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: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_use_non_export_class.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Local = %Local
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.ref: <error> = name_ref C, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %Local: <error> = bind_alias Local, <error> [template = <error>]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -99,6 +99,7 @@ CARBON_DIAGNOSTIC_KIND(ExpectedLibraryName)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedLibraryNameOrDefault)
|
||||
CARBON_DIAGNOSTIC_KIND(MissingLibraryKeyword)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedApiOrImpl)
|
||||
CARBON_DIAGNOSTIC_KIND(ExportImportPackage)
|
||||
|
||||
// For-specific diagnostics.
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedIn)
|
||||
@@ -148,6 +149,7 @@ CARBON_DIAGNOSTIC_KIND(ImportSelf)
|
||||
CARBON_DIAGNOSTIC_KIND(ExplicitImportApi)
|
||||
CARBON_DIAGNOSTIC_KIND(RepeatedImport)
|
||||
CARBON_DIAGNOSTIC_KIND(FirstImported)
|
||||
CARBON_DIAGNOSTIC_KIND(ExportFromImpl)
|
||||
|
||||
// Merge-related redeclaration checking.
|
||||
CARBON_DIAGNOSTIC_KIND(RedeclPrevDecl)
|
||||
|
||||
@@ -159,6 +159,7 @@ CARBON_KEYWORD_TOKEN(Continue, "continue")
|
||||
CARBON_KEYWORD_TOKEN(Default, "default")
|
||||
CARBON_KEYWORD_TOKEN(Destructor, "destructor")
|
||||
CARBON_KEYWORD_TOKEN(Else, "else")
|
||||
CARBON_KEYWORD_TOKEN(Export, "export")
|
||||
CARBON_KEYWORD_TOKEN(Extend, "extend")
|
||||
CARBON_KEYWORD_TOKEN(Extern, "extern")
|
||||
CARBON_KEYWORD_TOKEN(False, "false")
|
||||
|
||||
@@ -19,7 +19,11 @@ static auto TryHandleEndOrPackagingDecl(Context& context) -> bool {
|
||||
context.PopAndDiscardState();
|
||||
return true;
|
||||
}
|
||||
// `import`, `library`, and `package` manage their packaging state.
|
||||
// Packaging-related keywords manage their packaging state.
|
||||
case Lex::TokenKind::Export: {
|
||||
context.PushState(State::Export);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Import: {
|
||||
context.PushState(State::Import);
|
||||
return true;
|
||||
@@ -32,7 +36,7 @@ static auto TryHandleEndOrPackagingDecl(Context& context) -> bool {
|
||||
context.PushState(State::Package);
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
// Because a non-packaging keyword was encountered, packaging is complete.
|
||||
// Misplaced packaging keywords may lead to this being re-triggered.
|
||||
if (context.packaging_state() !=
|
||||
@@ -44,7 +48,6 @@ static auto TryHandleEndOrPackagingDecl(Context& context) -> bool {
|
||||
Context::PackagingState::AfterNonPackagingDecl);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +127,11 @@ static auto TryHandleAsDecl(Context& context, Context::StateStackEntry state,
|
||||
HandleBaseAsDecl(context, state);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Choice: {
|
||||
ApplyIntroducer(context, state, NodeKind::ChoiceIntroducer,
|
||||
State::ChoiceIntroducer);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Class: {
|
||||
ApplyIntroducer(context, state, NodeKind::ClassIntroducer,
|
||||
State::TypeAfterIntroducerAsClass);
|
||||
@@ -168,11 +176,6 @@ static auto TryHandleAsDecl(Context& context, Context::StateStackEntry state,
|
||||
State::VarAsDecl);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Choice: {
|
||||
ApplyIntroducer(context, state, NodeKind::ChoiceIntroducer,
|
||||
State::ChoiceIntroducer);
|
||||
return true;
|
||||
}
|
||||
|
||||
case Lex::TokenKind::Semi: {
|
||||
if (saw_modifier) {
|
||||
|
||||
@@ -73,14 +73,23 @@ static auto HandleApiOrImpl(Context& context)
|
||||
// Handles everything after the directive's introducer.
|
||||
static auto HandleDirectiveContent(Context& context,
|
||||
Context::StateStackEntry state,
|
||||
NodeKind directive,
|
||||
NodeKind directive, bool is_export,
|
||||
llvm::function_ref<void()> on_parse_error)
|
||||
-> void {
|
||||
Tree::PackagingNames names{
|
||||
.node_id = ImportDirectiveId(NodeId(state.subtree_start))};
|
||||
.node_id = ImportDirectiveId(NodeId(state.subtree_start)),
|
||||
.is_export = is_export};
|
||||
if (directive != NodeKind::LibraryDirective) {
|
||||
if (auto package_name_token =
|
||||
context.ConsumeIf(Lex::TokenKind::Identifier)) {
|
||||
if (names.is_export) {
|
||||
names.is_export = false;
|
||||
state.has_error = true;
|
||||
|
||||
CARBON_DIAGNOSTIC(ExportImportPackage, Error,
|
||||
"`export` cannot be used when importing a package.");
|
||||
context.emitter().Emit(*package_name_token, ExportImportPackage);
|
||||
}
|
||||
names.package_id = context.tokens().GetIdentifier(*package_name_token);
|
||||
context.AddLeafNode(NodeKind::PackageName, *package_name_token);
|
||||
} else if (directive == NodeKind::PackageDirective ||
|
||||
@@ -157,47 +166,104 @@ static auto HandleDirectiveContent(Context& context,
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleImport(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
// Returns true if currently in a valid state for imports, false otherwise. May
|
||||
// update the packaging state respectively.
|
||||
static auto VerifyInImports(Context& context, Lex::TokenIndex intro_token)
|
||||
-> bool {
|
||||
switch (context.packaging_state()) {
|
||||
case Context::PackagingState::FileStart:
|
||||
// `package` is no longer allowed, but `import` may repeat.
|
||||
context.set_packaging_state(Context::PackagingState::InImports);
|
||||
return true;
|
||||
|
||||
case Context::PackagingState::InImports:
|
||||
return true;
|
||||
|
||||
case Context::PackagingState::AfterNonPackagingDecl: {
|
||||
context.set_packaging_state(
|
||||
Context::PackagingState::InImportsAfterNonPackagingDecl);
|
||||
CARBON_DIAGNOSTIC(ImportTooLate, Error,
|
||||
"`import` and `export` directives must come after the "
|
||||
"`package` directive (if present) and before any other "
|
||||
"entities in the file.");
|
||||
CARBON_DIAGNOSTIC(FirstDecl, Note, "First declaration is here.");
|
||||
context.emitter()
|
||||
.Build(intro_token, ImportTooLate)
|
||||
.Note(context.first_non_packaging_token(), FirstDecl)
|
||||
.Emit();
|
||||
return false;
|
||||
}
|
||||
|
||||
case Context::PackagingState::InImportsAfterNonPackagingDecl:
|
||||
// There is a sequential block of misplaced `import` statements, which can
|
||||
// occur if a declaration is added above `import`s. Avoid duplicate
|
||||
// warnings.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Common logic for both `import` and `export import`, distinguished by whether
|
||||
// `export_token` is valid.
|
||||
static auto HandleImportHelper(Context& context,
|
||||
const Context::StateStackEntry& state,
|
||||
Lex::TokenIndex export_token) -> void {
|
||||
auto directive = NodeKind::ImportDirective;
|
||||
auto on_parse_error = [&] { OnParseError(context, state, directive); };
|
||||
|
||||
auto intro_token = context.ConsumeChecked(Lex::TokenKind::Import);
|
||||
context.AddLeafNode(NodeKind::ImportIntroducer, intro_token);
|
||||
|
||||
switch (context.packaging_state()) {
|
||||
case Context::PackagingState::FileStart:
|
||||
// `package` is no longer allowed, but `import` may repeat.
|
||||
context.set_packaging_state(Context::PackagingState::InImports);
|
||||
[[fallthrough]];
|
||||
|
||||
case Context::PackagingState::InImports:
|
||||
HandleDirectiveContent(context, state, directive, on_parse_error);
|
||||
break;
|
||||
|
||||
case Context::PackagingState::AfterNonPackagingDecl: {
|
||||
context.set_packaging_state(
|
||||
Context::PackagingState::InImportsAfterNonPackagingDecl);
|
||||
CARBON_DIAGNOSTIC(
|
||||
ImportTooLate, Error,
|
||||
"`import` directives must come after the `package` directive (if "
|
||||
"present) and before any other entities in the file.");
|
||||
CARBON_DIAGNOSTIC(FirstDecl, Note, "First declaration is here.");
|
||||
context.emitter()
|
||||
.Build(intro_token, ImportTooLate)
|
||||
.Note(context.first_non_packaging_token(), FirstDecl)
|
||||
.Emit();
|
||||
on_parse_error();
|
||||
break;
|
||||
}
|
||||
case Context::PackagingState::InImportsAfterNonPackagingDecl:
|
||||
// There is a sequential block of misplaced `import` statements, which can
|
||||
// occur if a declaration is added above `import`s. Avoid duplicate
|
||||
// warnings.
|
||||
on_parse_error();
|
||||
break;
|
||||
if (export_token.is_valid()) {
|
||||
context.AddLeafNode(NodeKind::ImportExport, export_token);
|
||||
}
|
||||
|
||||
if (VerifyInImports(context, intro_token)) {
|
||||
HandleDirectiveContent(context, state, directive, export_token.is_valid(),
|
||||
on_parse_error);
|
||||
} else {
|
||||
on_parse_error();
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleExport(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
context.ConsumeChecked(Lex::TokenKind::Export);
|
||||
|
||||
// Error for both Main//default and every implementation file.
|
||||
auto packaging = context.tree().packaging_directive();
|
||||
if (!packaging || packaging->api_or_impl == Tree::ApiOrImpl::Impl) {
|
||||
CARBON_DIAGNOSTIC(ExportFromImpl, Error,
|
||||
"`export` is only allowed in API files.");
|
||||
context.emitter().Emit(state.token, ExportFromImpl);
|
||||
state.has_error = true;
|
||||
}
|
||||
|
||||
if (context.PositionIs(Lex::TokenKind::Import)) {
|
||||
HandleImportHelper(context, state, state.token);
|
||||
} else {
|
||||
if (!VerifyInImports(context, state.token)) {
|
||||
state.has_error = true;
|
||||
}
|
||||
context.AddLeafNode(NodeKind::ExportIntroducer, state.token,
|
||||
state.has_error);
|
||||
context.PushState(state, State::ExportFinish);
|
||||
context.PushState(State::DeclNameAndParamsAsNone, state.token);
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleExportFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
context.AddNodeExpectingDeclSemi(state, NodeKind::ExportDirective,
|
||||
Lex::TokenKind::Export,
|
||||
/*is_def_allowed=*/false);
|
||||
}
|
||||
|
||||
auto HandleImport(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
HandleImportHelper(context, state, /*export_token=*/Lex::TokenIndex::Invalid);
|
||||
}
|
||||
|
||||
// Handles common logic for `package` and `library`.
|
||||
@@ -229,7 +295,8 @@ static auto HandlePackageAndLibraryDirectives(Context& context,
|
||||
// `package`/`library` is no longer allowed, but `import` may repeat.
|
||||
context.set_packaging_state(Context::PackagingState::InImports);
|
||||
|
||||
HandleDirectiveContent(context, state, directive, on_parse_error);
|
||||
HandleDirectiveContent(context, state, directive, /*is_export=*/false,
|
||||
on_parse_error);
|
||||
}
|
||||
|
||||
auto HandlePackage(Context& context) -> void {
|
||||
|
||||
@@ -194,12 +194,15 @@ CARBON_PARSE_NODE_KIND_BRACKET(PackageDirective, PackageIntroducer,
|
||||
|
||||
// `import`:
|
||||
// ImportIntroducer
|
||||
// _optional_: ImportExport
|
||||
// _optional_ _external_: PackageName
|
||||
// _optional_ _external_: LibrarySpecifier
|
||||
// ImportDirective
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImportIntroducer, 0, Import)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImportExport, 0, Export)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ImportDirective, ImportIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
|
||||
// `library` as directive:
|
||||
// LibraryIntroducer
|
||||
// DefaultLibrary or _external_: LibraryName
|
||||
@@ -215,6 +218,13 @@ CARBON_PARSE_NODE_KIND_BRACKET(LibraryDirective, LibraryIntroducer,
|
||||
// LibrarySpecifier
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibrarySpecifier, 1, Library)
|
||||
|
||||
// `export`:
|
||||
// ExportIntroducer
|
||||
// _external_: IdentifierName or QualifiedName
|
||||
// ExportDirective
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExportIntroducer, 0, Export)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExportDirective, 2, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `namespace`:
|
||||
// NamespaceStart
|
||||
// _repeated_ _external_: modifier
|
||||
|
||||
@@ -670,12 +670,33 @@ CARBON_PARSE_STATE(FunctionSignatureFinish)
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(FunctionDefinitionFinish)
|
||||
|
||||
// Handles `export`.
|
||||
//
|
||||
// export import library "libname";
|
||||
// ^~~~~~
|
||||
// 1. Import
|
||||
//
|
||||
// export Name;
|
||||
// ^~~~~~
|
||||
// 1. DeclNameAndParamsAsNone
|
||||
// 2. ExportFinish
|
||||
CARBON_PARSE_STATE(Export)
|
||||
|
||||
// Finishes an `export`.
|
||||
//
|
||||
// export Name;
|
||||
// ^
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(ExportFinish)
|
||||
|
||||
// Handles `import`.
|
||||
//
|
||||
// import pkgname [library "libname"] ;
|
||||
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// import ??? ;
|
||||
// ^~~~~~~~~~~~
|
||||
// export import library "libname";
|
||||
// ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(Import)
|
||||
|
||||
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
// 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
|
||||
|
||||
// --- name.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
export Foo;
|
||||
|
||||
// --- qual_name.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
export Foo.Bar;
|
||||
|
||||
// --- fail_expr.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_expr.carbon:[[@LINE+4]]:8: ERROR: `export` introducer should be followed by a name.
|
||||
// CHECK:STDERR: export ();
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
export ();
|
||||
|
||||
// --- fail_package_in_name.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_package_in_name.carbon:[[@LINE+4]]:8: ERROR: `export` introducer should be followed by a name.
|
||||
// CHECK:STDERR: export package.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
export package.Bar;
|
||||
|
||||
// --- fail_keyword_only
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_keyword_only:[[@LINE+4]]:1: ERROR: `export` introducer should be followed by a name.
|
||||
// CHECK:STDERR: export
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
export
|
||||
|
||||
// --- fail_no_name.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_no_name.carbon:[[@LINE+4]]:8: ERROR: `export` introducer should be followed by a name.
|
||||
// CHECK:STDERR: export ;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
export ;
|
||||
|
||||
// --- fail_no_semi.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
export Foo
|
||||
// CHECK:STDERR: fail_no_semi.carbon:[[@LINE+4]]:1: ERROR: `export` declarations must end with a `;`.
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
|
||||
// --- fail_incomplete_qual_name.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_incomplete_qual_name.carbon:[[@LINE+4]]:12: ERROR: Expected identifier after `.`.
|
||||
// CHECK:STDERR: export Foo.;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
export Foo.;
|
||||
|
||||
// --- fail_incomplete_qual_name2.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_incomplete_qual_name2.carbon:[[@LINE+4]]:8: ERROR: `export` introducer should be followed by a name.
|
||||
// CHECK:STDERR: export .Bar;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
export .Bar;
|
||||
|
||||
// --- fail_after_decl.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
class C;
|
||||
|
||||
// CHECK:STDERR: fail_after_decl.carbon:[[@LINE+7]]:1: ERROR: `import` and `export` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: export Foo;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_after_decl.carbon:[[@LINE-5]]:1: First declaration is here.
|
||||
// CHECK:STDERR: class C;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
export Foo;
|
||||
|
||||
// --- fail_in_default_library.carbon
|
||||
|
||||
// CHECK:STDERR: fail_in_default_library.carbon:[[@LINE+4]]:1: ERROR: `export` is only allowed in API files.
|
||||
// CHECK:STDERR: export Foo;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
export Foo;
|
||||
|
||||
// --- fail_in_impl.carbon
|
||||
|
||||
package Pkg impl;
|
||||
|
||||
// CHECK:STDERR: fail_in_impl.carbon:[[@LINE+3]]:1: ERROR: `export` is only allowed in API files.
|
||||
// CHECK:STDERR: export Foo;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
export Foo;
|
||||
|
||||
// CHECK:STDOUT: - filename: name.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: qual_name.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Bar'},
|
||||
// CHECK:STDOUT: {kind: 'QualifiedName', text: '.', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_expr.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_package_in_name.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'package', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_keyword_only
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: '', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: 'export', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_no_name.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_no_semi.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: 'Foo', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_incomplete_qual_name.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: ';', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'QualifiedName', text: '.', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_incomplete_qual_name2.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: '.', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_after_decl.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'C'},
|
||||
// CHECK:STDOUT: {kind: 'ClassDecl', text: ';', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_in_default_library.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_in_impl.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageImpl', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,147 @@
|
||||
// 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
|
||||
|
||||
// --- fail_package.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
// CHECK:STDERR: fail_package.carbon:[[@LINE+4]]:15: ERROR: `export` cannot be used when importing a package.
|
||||
// CHECK:STDERR: export import Bar;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
export import Bar;
|
||||
|
||||
// --- default.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
export import library default;
|
||||
|
||||
// --- named.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
export import library "lib";
|
||||
|
||||
// --- fail_order.carbon
|
||||
|
||||
package Pkg api;
|
||||
|
||||
export import library "a";
|
||||
|
||||
class C;
|
||||
|
||||
// CHECK:STDERR: fail_order.carbon:[[@LINE+7]]:8: ERROR: `import` and `export` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: export import library "b";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_order.carbon:[[@LINE-5]]:1: First declaration is here.
|
||||
// CHECK:STDERR: class C;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
export import library "b";
|
||||
|
||||
// --- fail_in_default_library.carbon
|
||||
|
||||
// CHECK:STDERR: fail_in_default_library.carbon:[[@LINE+4]]:1: ERROR: `export` is only allowed in API files.
|
||||
// CHECK:STDERR: export import library "lib";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
export import library "lib";
|
||||
|
||||
// --- fail_in_impl.carbon
|
||||
|
||||
package Pkg impl;
|
||||
|
||||
// CHECK:STDERR: fail_in_impl.carbon:[[@LINE+3]]:1: ERROR: `export` is only allowed in API files.
|
||||
// CHECK:STDERR: export import library "lib";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
export import library "lib";
|
||||
|
||||
// CHECK:STDOUT: - filename: fail_package.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Bar'},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', has_error: yes, subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: default.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'DefaultLibrary', text: 'default'},
|
||||
// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: named.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'LibraryName', text: '"lib"'},
|
||||
// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_order.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'LibraryName', text: '"a"'},
|
||||
// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'C'},
|
||||
// CHECK:STDOUT: {kind: 'ClassDecl', text: ';', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_in_default_library.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'LibraryName', text: '"lib"'},
|
||||
// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', has_error: yes, subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_in_impl.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'},
|
||||
// CHECK:STDOUT: {kind: 'PackageImpl', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'},
|
||||
// CHECK:STDOUT: {kind: 'ImportExport', text: 'export'},
|
||||
// CHECK:STDOUT: {kind: 'LibraryName', text: '"lib"'},
|
||||
// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', has_error: yes, subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
fn A();
|
||||
|
||||
// CHECK:STDERR: fail_after_decl.carbon:[[@LINE+6]]:1: ERROR: `import` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: fail_after_decl.carbon:[[@LINE+6]]:1: ERROR: `import` and `export` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: import B;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_after_decl.carbon:[[@LINE-5]]:1: First declaration is here.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
fn A();
|
||||
|
||||
// CHECK:STDERR: fail_after_decl_repeated.carbon:[[@LINE+7]]:1: ERROR: `import` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: fail_after_decl_repeated.carbon:[[@LINE+7]]:1: ERROR: `import` and `export` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: import B;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_after_decl_repeated.carbon:[[@LINE-5]]:1: First declaration is here.
|
||||
@@ -28,7 +28,7 @@ package D;
|
||||
|
||||
fn E();
|
||||
|
||||
// CHECK:STDERR: fail_after_decl_repeated.carbon:[[@LINE+6]]:1: ERROR: `import` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: fail_after_decl_repeated.carbon:[[@LINE+6]]:1: ERROR: `import` and `export` directives must come after the `package` directive (if present) and before any other entities in the file.
|
||||
// CHECK:STDERR: import F;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_after_decl_repeated.carbon:[[@LINE-27]]:1: First declaration is here.
|
||||
|
||||
@@ -92,6 +92,9 @@ class Tree : public Printable<Tree> {
|
||||
ImportDirectiveId node_id;
|
||||
IdentifierId package_id = IdentifierId::Invalid;
|
||||
StringLiteralValueId library_id = StringLiteralValueId::Invalid;
|
||||
// Whether an import is exported. This is on the file's packaging directive
|
||||
// even though it doesn't apply, for consistency in structure.
|
||||
bool is_export = false;
|
||||
};
|
||||
|
||||
// The file's packaging.
|
||||
|
||||
@@ -143,8 +143,8 @@ struct QualifiedName {
|
||||
IdentifierNameId rhs;
|
||||
};
|
||||
|
||||
// Library, package, import
|
||||
// ------------------------
|
||||
// Library, package, import, export
|
||||
// --------------------------------
|
||||
|
||||
// The `package` keyword in an expression.
|
||||
using PackageExpr = LeafNode<NodeKind::PackageExpr, NodeCategory::Expr>;
|
||||
@@ -179,11 +179,13 @@ struct PackageDirective {
|
||||
|
||||
// `import TheirPackage library "TheirLibrary";`
|
||||
using ImportIntroducer = LeafNode<NodeKind::ImportIntroducer>;
|
||||
using ImportExport = LeafNode<NodeKind::ImportExport>;
|
||||
struct ImportDirective {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ImportDirective.Define(NodeCategory::Decl);
|
||||
|
||||
ImportIntroducerId introducer;
|
||||
std::optional<ImportExportId> export_modifier;
|
||||
std::optional<PackageNameId> name;
|
||||
std::optional<LibrarySpecifierId> library;
|
||||
};
|
||||
@@ -199,6 +201,16 @@ struct LibraryDirective {
|
||||
NodeIdOneOf<PackageApi, PackageImpl> api_or_impl;
|
||||
};
|
||||
|
||||
// `export` as a directive.
|
||||
using ExportIntroducer = LeafNode<NodeKind::ExportIntroducer>;
|
||||
struct ExportDirective {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ExportDirective.Define(NodeCategory::Decl);
|
||||
|
||||
ExportIntroducerId introducer;
|
||||
AnyNameComponentId name;
|
||||
};
|
||||
|
||||
// Namespace nodes
|
||||
// ---------------
|
||||
|
||||
@@ -210,7 +222,7 @@ struct Namespace {
|
||||
|
||||
NamespaceStartId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
NodeIdOneOf<IdentifierName, QualifiedName> name;
|
||||
AnyNameComponentId name;
|
||||
};
|
||||
|
||||
// Pattern nodes
|
||||
|
||||
@@ -19,6 +19,8 @@ struct ImportIR : public Printable<ImportIR> {
|
||||
Parse::ImportDirectiveId node_id;
|
||||
// The imported IR.
|
||||
const File* sem_ir;
|
||||
// True if this is part of an `export import`.
|
||||
bool is_export;
|
||||
};
|
||||
|
||||
// A reference to an instruction in an imported IR. Used for diagnostics with
|
||||
|
||||
Reference in New Issue
Block a user