mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Move 'export name' out of the import section. (#3950)
This implements recent updates to #3938
This commit is contained in:
@@ -71,6 +71,7 @@ struct DeclState {
|
||||
Base,
|
||||
Class,
|
||||
Constraint,
|
||||
Export,
|
||||
Fn,
|
||||
Impl,
|
||||
Interface,
|
||||
|
||||
@@ -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;
|
||||
|
||||
+86
-10
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -208,6 +208,7 @@ struct ExportDirective {
|
||||
NodeKind::ExportDirective.Define(NodeCategory::Decl);
|
||||
|
||||
ExportIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
AnyNameComponentId name;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user