Move 'export name' out of the import section. (#3950)

This implements recent updates to #3938
This commit is contained in:
Jon Ross-Perkins
2024-05-17 18:26:14 +00:00
committed by GitHub
parent 40b2217421
commit ecb300ee5e
12 changed files with 208 additions and 74 deletions
+1
View File
@@ -71,6 +71,7 @@ struct DeclState {
Base,
Class,
Constraint,
Export,
Fn,
Impl,
Interface,
+6
View File
@@ -4,6 +4,7 @@
#include "toolchain/check/context.h"
#include "toolchain/check/decl_name_stack.h"
#include "toolchain/check/modifiers.h"
#include "toolchain/parse/typed_nodes.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/typed_insts.h"
@@ -12,6 +13,7 @@ namespace Carbon::Check {
auto HandleExportIntroducer(Context& context,
Parse::ExportIntroducerId /*node_id*/) -> bool {
context.decl_state_stack().Push(DeclState::Export);
// TODO: Probably need to update DeclNameStack to restrict to only namespaces.
context.decl_name_stack().PushScopeAndStartName();
return true;
@@ -22,6 +24,10 @@ auto HandleExportDirective(Context& context, Parse::ExportDirectiveId node_id)
auto name_context = context.decl_name_stack().FinishName();
context.decl_name_stack().PopScope();
LimitModifiersOnDecl(context, KeywordModifierSet::None,
Lex::TokenKind::Export);
context.decl_state_stack().Pop(DeclState::Export);
if (name_context.state == DeclNameStack::NameContext::State::Error) {
// Should already be diagnosed.
return true;
@@ -95,6 +95,21 @@ import library "base";
// CHECK:STDERR:
export NS;
// --- fail_export_decl.carbon
library "fail_export_decl" api;
class Local {}
// CHECK:STDERR: fail_export_decl.carbon:[[@LINE+7]]:1: ERROR: Only imported entities are valid for `export`.
// CHECK:STDERR: export Local;
// CHECK:STDERR: ^~~~~~~~~~~~~
// CHECK:STDERR: fail_export_decl.carbon:[[@LINE-5]]:1: Name is declared here.
// CHECK:STDERR: class Local {}
// CHECK:STDERR: ^~~~~~~~~~~~~
// CHECK:STDERR:
export Local;
// --- fail_export_member.carbon
library "fail_export_member" api;
@@ -224,7 +239,7 @@ export C;
library "use_repeat_export" api;
// CHECK:STDERR: fail_todo_use_repeat_export.carbon:[[@LINE+18]]:1: In import.
// CHECK:STDERR: fail_todo_use_repeat_export.carbon:[[@LINE+19]]:1: In import.
// CHECK:STDERR: import library "repeat_export";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR: repeat_export.carbon:4:1: In import.
@@ -233,7 +248,7 @@ library "use_repeat_export" api;
// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
// CHECK:STDERR: class C {
// CHECK:STDERR: ^~~~~~~~~
// CHECK:STDERR: fail_todo_use_repeat_export.carbon:[[@LINE+9]]:1: In import.
// CHECK:STDERR: fail_todo_use_repeat_export.carbon:[[@LINE+10]]:1: In import.
// CHECK:STDERR: import library "repeat_export";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR: repeat_export.carbon:4:1: In import.
@@ -242,10 +257,22 @@ library "use_repeat_export" api;
// CHECK:STDERR: base.carbon:4:1: Name is previously declared here.
// CHECK:STDERR: class C {
// CHECK:STDERR: ^~~~~~~~~
// CHECK:STDERR:
import library "repeat_export";
var c: C = {.x = ()};
// --- fail_modifiers.carbon
library "fail_modifiers" api;
import library "base";
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+3]]:1: ERROR: `private` not allowed on `export` declaration.
// CHECK:STDERR: private export C;
// CHECK:STDERR: ^~~~~~~
private export C;
// CHECK:STDOUT: --- base.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -630,6 +657,25 @@ var c: C = {.x = ()};
// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+12, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_export_decl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Local: type = class_type @Local [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Local = %Local.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Local.decl: type = class_decl @Local [template = constants.%Local] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @Local {
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Local
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_export_member.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -888,14 +934,44 @@ var c: C = {.x = ()};
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %.loc24_19.1: () = tuple_literal ()
// CHECK:STDOUT: %.loc24_20.1: {.x: ()} = struct_literal (%.loc24_19.1)
// CHECK:STDOUT: %.loc24_20.2: ref () = class_element_access file.%c.var, element0
// CHECK:STDOUT: %.loc24_19.2: init () = tuple_init () to %.loc24_20.2 [template = constants.%tuple]
// CHECK:STDOUT: %.loc24_20.3: init () = converted %.loc24_19.1, %.loc24_19.2 [template = constants.%tuple]
// CHECK:STDOUT: %.loc24_20.4: init C = class_init (%.loc24_20.3), file.%c.var [template = constants.%struct]
// CHECK:STDOUT: %.loc24_21: init C = converted %.loc24_20.1, %.loc24_20.4 [template = constants.%struct]
// CHECK:STDOUT: assign file.%c.var, %.loc24_21
// CHECK:STDOUT: %.loc25_19.1: () = tuple_literal ()
// CHECK:STDOUT: %.loc25_20.1: {.x: ()} = struct_literal (%.loc25_19.1)
// CHECK:STDOUT: %.loc25_20.2: ref () = class_element_access file.%c.var, element0
// CHECK:STDOUT: %.loc25_19.2: init () = tuple_init () to %.loc25_20.2 [template = constants.%tuple]
// CHECK:STDOUT: %.loc25_20.3: init () = converted %.loc25_19.1, %.loc25_19.2 [template = constants.%tuple]
// CHECK:STDOUT: %.loc25_20.4: init C = class_init (%.loc25_20.3), file.%c.var [template = constants.%struct]
// CHECK:STDOUT: %.loc25_21: init C = converted %.loc25_20.1, %.loc25_20.4 [template = constants.%struct]
// CHECK:STDOUT: assign file.%c.var, %.loc25_21
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_modifiers.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .C = %import_ref.1
// CHECK:STDOUT: .NS = %NS
// 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: type = bind_export C, %import_ref.1 [template = constants.%C]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .x = file.%import_ref.4
// CHECK:STDOUT: .Self = file.%import_ref.5
// CHECK:STDOUT: }
// CHECK:STDOUT:
+22 -13
View File
@@ -21,11 +21,14 @@ static auto TryHandleEndOrPackagingDecl(Context& context) -> bool {
}
// Packaging-related keywords manage their packaging state.
case Lex::TokenKind::Export: {
context.PushState(State::Export);
if (!context.PositionIs(Lex::TokenKind::Import, Lookahead::NextToken)) {
break;
}
context.PushState(State::ImportAsExport);
return true;
}
case Lex::TokenKind::Import: {
context.PushState(State::Import);
context.PushState(State::ImportAsRegular);
return true;
}
case Lex::TokenKind::Library: {
@@ -37,18 +40,19 @@ static auto TryHandleEndOrPackagingDecl(Context& context) -> bool {
return true;
}
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() !=
Context::PackagingState::AfterNonPackagingDecl) {
if (!context.first_non_packaging_token().is_valid()) {
context.set_first_non_packaging_token(*context.position());
}
context.set_packaging_state(
Context::PackagingState::AfterNonPackagingDecl);
}
return false;
break;
}
// Because a non-packaging keyword was encountered, packaging is complete.
// Misplaced packaging keywords may lead to this being re-triggered.
if (context.packaging_state() !=
Context::PackagingState::AfterNonPackagingDecl) {
if (!context.first_non_packaging_token().is_valid()) {
context.set_first_non_packaging_token(*context.position());
}
context.set_packaging_state(Context::PackagingState::AfterNonPackagingDecl);
}
return false;
}
// Finishes an invalid declaration, skipping past its end.
@@ -142,6 +146,11 @@ static auto TryHandleAsDecl(Context& context, Context::StateStackEntry state,
State::TypeAfterIntroducerAsNamedConstraint);
return true;
}
case Lex::TokenKind::Export: {
ApplyIntroducer(context, state, NodeKind::ExportIntroducer,
State::ExportName);
return true;
}
case Lex::TokenKind::Extend: {
// TODO: Treat this `extend` token as a declaration introducer
HandleUnrecognizedDecl(context, state.subtree_start);
+27 -23
View File
@@ -183,8 +183,8 @@ static auto VerifyInImports(Context& context, Lex::TokenIndex intro_token)
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 "
"`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()
@@ -225,11 +225,15 @@ static auto HandleImportHelper(Context& context,
}
}
auto HandleExport(Context& context) -> void {
auto HandleImportAsRegular(Context& context) -> void {
auto state = context.PopState();
context.ConsumeChecked(Lex::TokenKind::Export);
HandleImportHelper(context, state, /*export_token=*/Lex::TokenIndex::Invalid);
}
// Diagnoses if `export` is used in an `impl` file.
static auto RestrictExportToApi(Context& context,
Context::StateStackEntry& state) -> void {
// Error for both Main//default and every implementation file.
auto packaging = context.tree().packaging_directive();
if (!packaging || packaging->api_or_impl == Tree::ApiOrImpl::Impl) {
@@ -238,21 +242,27 @@ auto HandleExport(Context& context) -> void {
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 HandleImportAsExport(Context& context) -> void {
auto state = context.PopState();
context.ConsumeChecked(Lex::TokenKind::Export);
RestrictExportToApi(context, state);
HandleImportHelper(context, state, state.token);
}
auto HandleExportName(Context& context) -> void {
auto state = context.PopState();
RestrictExportToApi(context, state);
context.PushState(state, State::ExportNameFinish);
context.PushState(State::DeclNameAndParamsAsNone, state.token);
}
auto HandleExportNameFinish(Context& context) -> void {
auto state = context.PopState();
context.AddNodeExpectingDeclSemi(state, NodeKind::ExportDirective,
@@ -260,12 +270,6 @@ auto HandleExportFinish(Context& context) -> void {
/*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`.
static auto HandlePackageAndLibraryDirectives(Context& context,
Lex::TokenKind intro_token_kind,
+2 -1
View File
@@ -223,7 +223,8 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibrarySpecifier, 1, Library)
// _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))
CARBON_PARSE_NODE_KIND_BRACKET(ExportDirective, ExportIntroducer,
CARBON_IF_VALID(Semi))
// `namespace`:
// NamespaceStart
+13 -12
View File
@@ -334,6 +334,11 @@ CARBON_PARSE_STATE(DeclNameAndParamsAfterImplicit)
// 1. TypeAfterIntroducerAsNamedConstraint
// 2. DeclScopeLoop
//
// export <name> ...
// ^~~~~~
// 1. ExportName
// 2. DeclScopeLoop
//
// fn ...
// ^~
// 1. FunctionIntroducer
@@ -670,24 +675,20 @@ CARBON_PARSE_STATE(FunctionSignatureFinish)
// (state done)
CARBON_PARSE_STATE(FunctionDefinitionFinish)
// Handles `export`.
//
// export import library "libname";
// ^~~~~~
// 1. Import
// Handles `export <name>`.
//
// export Name;
// ^~~~~~
// ^
// 1. DeclNameAndParamsAsNone
// 2. ExportFinish
CARBON_PARSE_STATE(Export)
CARBON_PARSE_STATE(ExportName)
// Finishes an `export`.
// Finishes an `export <name>`.
//
// export Name;
// ^
// (state done)
CARBON_PARSE_STATE(ExportFinish)
CARBON_PARSE_STATE(ExportNameFinish)
// Handles `import`.
//
@@ -695,10 +696,10 @@ CARBON_PARSE_STATE(ExportFinish)
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// import ??? ;
// ^~~~~~~~~~~~
// export import library "libname";
// ^~~~~~~~~~~~~~~~~~~~~~~~~
// export import library "libname" ;
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (state done)
CARBON_PARSE_STATE(Import)
CARBON_PARSE_STATE_VARIANTS2(Import, Regular, Export)
// Handles `library` in directive form.
//
+46 -11
View File
@@ -4,6 +4,10 @@
//
// AUTOUPDATE
// --- lib.carbon
library "lib" api;
// --- name.carbon
package Pkg api;
@@ -86,20 +90,28 @@ package Pkg api;
// CHECK:STDERR:
export .Bar;
// --- fail_after_decl.carbon
// --- 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.
export Foo;
// --- fail_before_import.carbon
package Pkg api;
export Foo;
// CHECK:STDERR: fail_before_import.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: import library "lib";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR: fail_before_import.carbon:[[@LINE-5]]:1: First declaration is here.
// 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;
import library "lib";
// --- fail_in_default_library.carbon
@@ -118,6 +130,15 @@ package Pkg impl;
// CHECK:STDERR: ^~~~~~
export Foo;
// CHECK:STDOUT: - filename: lib.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'},
// CHECK:STDOUT: {kind: 'LibraryName', text: '"lib"'},
// CHECK:STDOUT: {kind: 'PackageApi', text: 'api'},
// CHECK:STDOUT: {kind: 'LibraryDirective', text: ';', subtree_size: 4},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
// CHECK:STDOUT: - filename: name.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
@@ -230,7 +251,7 @@ export Foo;
// 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: - filename: after_decl.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'},
@@ -240,15 +261,29 @@ export Foo;
// 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: 'ExportIntroducer', text: 'export'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
// CHECK:STDOUT: - filename: fail_before_import.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: 'ImportIntroducer', text: 'import'},
// CHECK:STDOUT: {kind: 'ImportDirective', text: ';', has_error: yes, subtree_size: 2},
// 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: 'ExportIntroducer', text: 'export'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
@@ -260,7 +295,7 @@ export Foo;
// 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: 'ExportIntroducer', text: 'export'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
// CHECK:STDOUT: {kind: 'ExportDirective', text: ';', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
+1 -1
View File
@@ -34,7 +34,7 @@ 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: fail_order.carbon:[[@LINE+7]]:8: ERROR: `import` 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.
@@ -6,7 +6,7 @@
fn A();
// 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: 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: 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` and `export` 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` 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` and `export` 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` 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.
+1
View File
@@ -208,6 +208,7 @@ struct ExportDirective {
NodeKind::ExportDirective.Define(NodeCategory::Decl);
ExportIntroducerId introducer;
llvm::SmallVector<AnyModifierId> modifiers;
AnyNameComponentId name;
};