From d1862e829b42ce4abaebc79eb96713f55b762dbd Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 5 Jun 2024 14:04:53 -0700 Subject: [PATCH] Add a macro for introducer tokens. (#4031) Playing with the macro suggestion on #4028, replace DeclKind with some templating that asserts the in-use token is an introducer token. This allows type-safe usage of Lex::TokenKind, reducing the benefit of a separate enum while improving stdout (since now this will ostream as the keyword name). --- toolchain/check/BUILD | 1 + toolchain/check/decl_introducer_state.h | 61 ++++++++++--------- toolchain/check/handle_alias.cpp | 4 +- toolchain/check/handle_class.cpp | 12 ++-- toolchain/check/handle_export.cpp | 4 +- toolchain/check/handle_function.cpp | 4 +- toolchain/check/handle_impl.cpp | 4 +- toolchain/check/handle_import_and_package.cpp | 12 ++-- toolchain/check/handle_interface.cpp | 4 +- toolchain/check/handle_let.cpp | 4 +- toolchain/check/handle_loop_statement.cpp | 2 +- toolchain/check/handle_namespace.cpp | 4 +- toolchain/check/handle_variable.cpp | 4 +- toolchain/check/modifiers.cpp | 40 +----------- toolchain/lex/token_kind.def | 42 ++++++++----- toolchain/lex/token_kind.h | 3 + 16 files changed, 92 insertions(+), 113 deletions(-) diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index 8f3a2c3f79f6..cfc315d75bdf 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -90,6 +90,7 @@ cc_library( "//toolchain/base:kind_switch", "//toolchain/check:scope_stack", "//toolchain/diagnostics:diagnostic_emitter", + "//toolchain/lex:token_kind", "//toolchain/lex:tokenized_buffer", "//toolchain/parse:node_kind", "//toolchain/parse:tree", diff --git a/toolchain/check/decl_introducer_state.h b/toolchain/check/decl_introducer_state.h index 15fb5630e741..ade36dc9310b 100644 --- a/toolchain/check/decl_introducer_state.h +++ b/toolchain/check/decl_introducer_state.h @@ -6,6 +6,7 @@ #define CARBON_TOOLCHAIN_CHECK_DECL_INTRODUCER_STATE_H_ #include "toolchain/check/keyword_modifier_set.h" +#include "toolchain/lex/token_kind.h" #include "toolchain/parse/node_ids.h" namespace Carbon::Check { @@ -14,27 +15,6 @@ namespace Carbon::Check { // declaration and the keyword modifiers that apply to that declaration // introducer. struct DeclIntroducerState { - // The kind of declaration. - enum DeclKind : int8_t { - Adapt, - Alias, - Base, - Class, - Constraint, - Export, - Fn, - Impl, - Import, - Interface, - Let, - Library, - Namespace, - Package, - Var - }; - - explicit DeclIntroducerState(DeclKind decl_kind) : kind(decl_kind) {} - auto modifier_node_id(ModifierOrder order) -> Parse::NodeId { return ordered_modifier_node_ids[static_cast(order)]; } @@ -43,7 +23,8 @@ struct DeclIntroducerState { ordered_modifier_node_ids[static_cast(order)] = node_id; } - DeclKind kind; + // The token kind of the introducer. + Lex::TokenKind kind; // Nodes of modifiers on this declaration, in expected order. `Invalid` if no // modifier of that kind is present. @@ -53,26 +34,46 @@ struct DeclIntroducerState { Parse::NodeId::Invalid}; // Invariant: contains just the modifiers represented by `saw_*_modifier`. - KeywordModifierSet modifier_set; + KeywordModifierSet modifier_set = KeywordModifierSet(); }; // Stack of `DeclIntroducerState` values, representing all the declaration // introducers we are currently nested within. Commonly size 0 or 1, as nested // introducers are rare. class DeclIntroducerStateStack { + private: + // Returns true for introducer tokens. Supports Push/Pop `requires`. + template + static constexpr auto IsDeclIntroducer() -> bool { + switch (Kind) { +#define CARBON_TOKEN(...) +#define CARBON_DECL_INTRODUCER_TOKEN(Name, ...) case Lex::TokenKind::Name: +#include "toolchain/lex/token_kind.def" + return true; + default: + return false; + } + } + public: - // Begins introducing a declaration of kind `k`. - auto Push(DeclIntroducerState::DeclKind k) -> void { stack_.emplace_back(k); } + // Begins a declaration introducer `Kind`. + template + requires(IsDeclIntroducer()) + auto Push() -> void { + stack_.push_back({.kind = Lex::TokenKind::Make(Kind)}); + } // Gets the state of declaration at the top of the stack -- the innermost // declaration currently being processed. auto innermost() -> DeclIntroducerState& { return stack_.back(); } - // Finishes introducing a declaration of kind `k` and returns the - // produced state. - auto Pop(DeclIntroducerState::DeclKind k) -> DeclIntroducerState { - CARBON_CHECK(stack_.back().kind == k) - << "Found: " << stack_.back().kind << " expected: " << k; + // Finishes a declaration introducer `Kind` and returns the produced state. + template + requires(IsDeclIntroducer()) + auto Pop() -> DeclIntroducerState { + CARBON_CHECK(stack_.back().kind == Kind) + << "Found: " << stack_.back().kind + << " expected: " << Lex::TokenKind::Make(Kind); return stack_.pop_back_val(); } diff --git a/toolchain/check/handle_alias.cpp b/toolchain/check/handle_alias.cpp index 2055bd8ab793..51c699c45910 100644 --- a/toolchain/check/handle_alias.cpp +++ b/toolchain/check/handle_alias.cpp @@ -14,7 +14,7 @@ namespace Carbon::Check { auto HandleAliasIntroducer(Context& context, Parse::AliasIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Alias); + context.decl_introducer_state_stack().Push(); context.decl_name_stack().PushScopeAndStartName(); return true; } @@ -31,7 +31,7 @@ auto HandleAlias(Context& context, Parse::AliasId /*node_id*/) -> bool { PopNameComponentWithoutParams(context, Lex::TokenKind::Alias)); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Alias); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Access); if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Access)) { context.TODO(introducer.modifier_node_id(ModifierOrder::Access), diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index da2f8316d1ae..a1c440bec4d6 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -36,7 +36,7 @@ auto HandleClassIntroducer(Context& context, Parse::ClassIntroducerId node_id) // Push the bracketing node. context.node_stack().Push(node_id); // Optional modifiers and the name follow. - context.decl_introducer_state_stack().Push(DeclIntroducerState::Class); + context.decl_introducer_state_stack().Push(); context.decl_name_stack().PushScopeAndStartName(); return true; } @@ -188,7 +188,7 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id, auto [_, parent_scope_inst] = context.name_scopes().GetInstIfValid(name_context.parent_scope_id); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Class); + context.decl_introducer_state_stack().Pop(); CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Class | KeywordModifierSet::Access | @@ -355,7 +355,7 @@ static auto DiagnoseClassSpecificDeclRepeated(Context& context, auto HandleAdaptIntroducer(Context& context, Parse::AdaptIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Adapt); + context.decl_introducer_state_stack().Push(); return true; } @@ -365,7 +365,7 @@ auto HandleAdaptDecl(Context& context, Parse::AdaptDeclId node_id) -> bool { // Process modifiers. `extend` is permitted, no others are allowed. auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Adapt); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Extend); auto parent_class_decl = @@ -422,7 +422,7 @@ auto HandleAdaptDecl(Context& context, Parse::AdaptDeclId node_id) -> bool { auto HandleBaseIntroducer(Context& context, Parse::BaseIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Base); + context.decl_introducer_state_stack().Push(); return true; } @@ -495,7 +495,7 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId node_id) -> bool { // Process modifiers. `extend` is required, no others are allowed. auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Base); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Extend); if (!introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) { CARBON_DIAGNOSTIC(BaseMissingExtend, Error, diff --git a/toolchain/check/handle_export.cpp b/toolchain/check/handle_export.cpp index d3c482de11e2..d583554415fb 100644 --- a/toolchain/check/handle_export.cpp +++ b/toolchain/check/handle_export.cpp @@ -15,7 +15,7 @@ namespace Carbon::Check { auto HandleExportIntroducer(Context& context, Parse::ExportIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Export); + context.decl_introducer_state_stack().Push(); // TODO: Probably need to update DeclNameStack to restrict to only namespaces. context.decl_name_stack().PushScopeAndStartName(); return true; @@ -27,7 +27,7 @@ auto HandleExportDecl(Context& context, Parse::ExportDeclId node_id) -> bool { context.decl_name_stack().PopScope(); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Export); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::None); if (name_context.state == DeclNameStack::NameContext::State::Error) { diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 814ebe2ab06a..8d1d1a1e546f 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -30,7 +30,7 @@ auto HandleFunctionIntroducer(Context& context, // Push the bracketing node. context.node_stack().Push(node_id); // Optional modifiers and the name follow. - context.decl_introducer_state_stack().Push(DeclIntroducerState::Fn); + context.decl_introducer_state_stack().Push(); context.decl_name_stack().PushScopeAndStartName(); return true; } @@ -225,7 +225,7 @@ static auto BuildFunctionDecl(Context& context, auto [parent_scope_inst_id, parent_scope_inst] = context.name_scopes().GetInstIfValid(name_context.parent_scope_id); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Fn); + context.decl_introducer_state_stack().Pop(); DiagnoseModifiers(context, introducer, is_definition, parent_scope_inst_id, parent_scope_inst); if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Access)) { diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index bd0a6117c241..fa1fb1728531 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -24,7 +24,7 @@ auto HandleImplIntroducer(Context& context, Parse::ImplIntroducerId node_id) context.node_stack().Push(node_id); // Optional modifiers follow. - context.decl_introducer_state_stack().Push(DeclIntroducerState::Impl); + context.decl_introducer_state_stack().Push(); // An impl doesn't have a name per se, but it makes the processing more // consistent to imagine that it does. This also gives us a scope for implicit @@ -193,7 +193,7 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id) // TODO: Should we somehow permit access specifiers on `impl`s? // TODO: Handle `final` modifier. auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Impl); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::ImplDecl); // Finish processing the name, which should be empty, but might have diff --git a/toolchain/check/handle_import_and_package.cpp b/toolchain/check/handle_import_and_package.cpp index 3734c0469f6f..63e6dcb706f0 100644 --- a/toolchain/check/handle_import_and_package.cpp +++ b/toolchain/check/handle_import_and_package.cpp @@ -14,42 +14,42 @@ namespace Carbon::Check { auto HandleImportIntroducer(Context& context, Parse::ImportIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Import); + context.decl_introducer_state_stack().Push(); return true; } auto HandleImportDecl(Context& context, Parse::ImportDeclId /*node_id*/) -> bool { auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Import); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Export); return true; } auto HandleLibraryIntroducer(Context& context, Parse::LibraryIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Library); + context.decl_introducer_state_stack().Push(); return true; } auto HandleLibraryDecl(Context& context, Parse::LibraryDeclId /*node_id*/) -> bool { auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Library); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Impl); return true; } auto HandlePackageIntroducer(Context& context, Parse::PackageIntroducerId /*node_id*/) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Package); + context.decl_introducer_state_stack().Push(); return true; } auto HandlePackageDecl(Context& context, Parse::PackageDeclId /*node_id*/) -> bool { auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Package); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Impl); return true; } diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index 91d4c792520f..a1a8581111c7 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -20,7 +20,7 @@ auto HandleInterfaceIntroducer(Context& context, // Push the bracketing node. context.node_stack().Push(node_id); // Optional modifiers and the name follow. - context.decl_introducer_state_stack().Push(DeclIntroducerState::Interface); + context.decl_introducer_state_stack().Push(); context.decl_name_stack().PushScopeAndStartName(); return true; } @@ -37,7 +37,7 @@ static auto BuildInterfaceDecl(Context& context, auto [_, parent_scope_inst] = context.name_scopes().GetInstIfValid(name_context.parent_scope_id); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Interface); + context.decl_introducer_state_stack().Pop(); CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Access); diff --git a/toolchain/check/handle_let.cpp b/toolchain/check/handle_let.cpp index d740000a7799..f86e5049cf51 100644 --- a/toolchain/check/handle_let.cpp +++ b/toolchain/check/handle_let.cpp @@ -15,7 +15,7 @@ namespace Carbon::Check { auto HandleLetIntroducer(Context& context, Parse::LetIntroducerId node_id) -> bool { - context.decl_introducer_state_stack().Push(DeclIntroducerState::Let); + context.decl_introducer_state_stack().Push(); // Push a bracketing node to establish the pattern context. context.node_stack().Push(node_id); return true; @@ -83,7 +83,7 @@ auto HandleLetDecl(Context& context, Parse::LetDeclId node_id) -> bool { context.name_scopes().GetInstIfValid( context.scope_stack().PeekNameScopeId()); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Let); + context.decl_introducer_state_stack().Pop(); CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst); RequireDefaultFinalOnlyInInterfaces(context, introducer, parent_scope_inst); LimitModifiersOnDecl( diff --git a/toolchain/check/handle_loop_statement.cpp b/toolchain/check/handle_loop_statement.cpp index afa0d93dadb1..d204a2165df4 100644 --- a/toolchain/check/handle_loop_statement.cpp +++ b/toolchain/check/handle_loop_statement.cpp @@ -77,7 +77,7 @@ auto HandleForHeaderStart(Context& context, Parse::ForHeaderStartId node_id) } auto HandleForIn(Context& context, Parse::ForInId node_id) -> bool { - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Var); + context.decl_introducer_state_stack().Pop(); return context.TODO(node_id, "HandleForIn"); } diff --git a/toolchain/check/handle_namespace.cpp b/toolchain/check/handle_namespace.cpp index 004d26536447..45fdb427f750 100644 --- a/toolchain/check/handle_namespace.cpp +++ b/toolchain/check/handle_namespace.cpp @@ -15,7 +15,7 @@ namespace Carbon::Check { auto HandleNamespaceStart(Context& context, Parse::NamespaceStartId /*node_id*/) -> bool { // Optional modifiers and the name follow. - context.decl_introducer_state_stack().Push(DeclIntroducerState::Namespace); + context.decl_introducer_state_stack().Push(); context.decl_name_stack().PushScopeAndStartName(); return true; } @@ -25,7 +25,7 @@ auto HandleNamespace(Context& context, Parse::NamespaceId node_id) -> bool { PopNameComponentWithoutParams(context, Lex::TokenKind::Namespace)); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Namespace); + context.decl_introducer_state_stack().Pop(); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::None); auto namespace_inst = SemIR::Namespace{ diff --git a/toolchain/check/handle_variable.cpp b/toolchain/check/handle_variable.cpp index 81932c316d99..03791c82daac 100644 --- a/toolchain/check/handle_variable.cpp +++ b/toolchain/check/handle_variable.cpp @@ -13,7 +13,7 @@ auto HandleVariableIntroducer(Context& context, Parse::VariableIntroducerId node_id) -> bool { // No action, just a bracketing node. context.node_stack().Push(node_id); - context.decl_introducer_state_stack().Push(DeclIntroducerState::Var); + context.decl_introducer_state_stack().Push(); return true; } @@ -102,7 +102,7 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId node_id) auto [_, parent_scope_inst] = context.name_scopes().GetInstIfValid( context.scope_stack().PeekNameScopeId()); auto introducer = - context.decl_introducer_state_stack().Pop(DeclIntroducerState::Var); + context.decl_introducer_state_stack().Pop(); CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst); LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Access); if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Access)) { diff --git a/toolchain/check/modifiers.cpp b/toolchain/check/modifiers.cpp index ae9563199ad5..1caf82995b14 100644 --- a/toolchain/check/modifiers.cpp +++ b/toolchain/check/modifiers.cpp @@ -8,43 +8,6 @@ namespace Carbon::Check { -// Returns the TokenKind for a DeclKind. -static auto DeclKindToken(DeclIntroducerState::DeclKind decl_kind) - -> Lex::TokenKind { - switch (decl_kind) { - case DeclIntroducerState::Adapt: - return Lex::TokenKind::Adapt; - case DeclIntroducerState::Alias: - return Lex::TokenKind::Alias; - case DeclIntroducerState::Base: - return Lex::TokenKind::Base; - case DeclIntroducerState::Class: - return Lex::TokenKind::Class; - case DeclIntroducerState::Constraint: - return Lex::TokenKind::Constraint; - case DeclIntroducerState::Export: - return Lex::TokenKind::Export; - case DeclIntroducerState::Fn: - return Lex::TokenKind::Fn; - case DeclIntroducerState::Import: - return Lex::TokenKind::Import; - case DeclIntroducerState::Impl: - return Lex::TokenKind::Impl; - case DeclIntroducerState::Interface: - return Lex::TokenKind::Interface; - case DeclIntroducerState::Let: - return Lex::TokenKind::Let; - case DeclIntroducerState::Library: - return Lex::TokenKind::Library; - case DeclIntroducerState::Namespace: - return Lex::TokenKind::Namespace; - case DeclIntroducerState::Package: - return Lex::TokenKind::Package; - case DeclIntroducerState::Var: - return Lex::TokenKind::Var; - } -} - static auto DiagnoseNotAllowed(Context& context, Parse::NodeId modifier_node, Lex::TokenKind decl_kind, llvm::StringRef context_string, @@ -89,8 +52,7 @@ auto ForbidModifiersOnDecl(Context& context, DeclIntroducerState& introducer, auto order = static_cast(order_index); if (not_allowed.HasAnyOf(ModifierOrderAsSet(order))) { DiagnoseNotAllowed(context, introducer.modifier_node_id(order), - DeclKindToken(introducer.kind), context_string, - context_loc_id); + introducer.kind, context_string, context_loc_id); introducer.set_modifier_node_id(order, Parse::NodeId::Invalid); } } diff --git a/toolchain/lex/token_kind.def b/toolchain/lex/token_kind.def index 341506a878a8..6205cfe8f5ea 100644 --- a/toolchain/lex/token_kind.def +++ b/toolchain/lex/token_kind.def @@ -21,6 +21,8 @@ // - CARBON_KEYWORD_TOKEN(Name, Spelling) // Defines a keyword which has the provided spelling, such as `if`. // Spellings must be unique. +// - CARBON_DECL_INTRODUCER_TOKEN(Name, Spelling) +// A declaration introducer keyword, such as `fn`. // - CARBON_TOKEN_WITH_VIRTUAL_NODE(TokenIndex) // Wrapped around one of the above _TOKEN macros, indicates that this // token has one additional virtual node in the parse tree. @@ -137,53 +139,62 @@ CARBON_CLOSING_GROUP_SYMBOL_TOKEN(CloseSquareBracket, "]", OpenSquareBracket) #ifndef CARBON_KEYWORD_TOKEN #define CARBON_KEYWORD_TOKEN(Name, Spelling) CARBON_TOKEN(Name) #endif + +#ifndef CARBON_DECL_INTRODUCER_TOKEN +#define CARBON_DECL_INTRODUCER_TOKEN(Name, Spelling) \ + CARBON_KEYWORD_TOKEN(Name, Spelling) +#endif + // clang-format off + +CARBON_DECL_INTRODUCER_TOKEN(Adapt, "adapt") +CARBON_DECL_INTRODUCER_TOKEN(Alias, "alias") +CARBON_DECL_INTRODUCER_TOKEN(Base, "base") +CARBON_DECL_INTRODUCER_TOKEN(Class, "class") +CARBON_DECL_INTRODUCER_TOKEN(Constraint, "constraint") +CARBON_DECL_INTRODUCER_TOKEN(Export, "export") +CARBON_DECL_INTRODUCER_TOKEN(Fn, "fn") +CARBON_DECL_INTRODUCER_TOKEN(Impl, "impl") +CARBON_DECL_INTRODUCER_TOKEN(Import, "import") +CARBON_DECL_INTRODUCER_TOKEN(Interface, "interface") +CARBON_DECL_INTRODUCER_TOKEN(Let, "let") +CARBON_DECL_INTRODUCER_TOKEN(Library, "library") +CARBON_DECL_INTRODUCER_TOKEN(Namespace, "namespace") +CARBON_DECL_INTRODUCER_TOKEN(Package, "package") +CARBON_DECL_INTRODUCER_TOKEN(Var, "var") + CARBON_KEYWORD_TOKEN(Abstract, "abstract") -CARBON_KEYWORD_TOKEN(Adapt, "adapt") CARBON_KEYWORD_TOKEN(Addr, "addr") -CARBON_KEYWORD_TOKEN(Alias, "alias") CARBON_TOKEN_WITH_VIRTUAL_NODE( CARBON_KEYWORD_TOKEN(And, "and")) CARBON_KEYWORD_TOKEN(Api, "api") CARBON_KEYWORD_TOKEN(As, "as") CARBON_KEYWORD_TOKEN(Auto, "auto") -CARBON_KEYWORD_TOKEN(Base, "base") CARBON_KEYWORD_TOKEN(Bool, "bool") CARBON_KEYWORD_TOKEN(Break, "break") CARBON_KEYWORD_TOKEN(Case, "case") CARBON_KEYWORD_TOKEN(Choice, "choice") -CARBON_KEYWORD_TOKEN(Class, "class") CARBON_KEYWORD_TOKEN(Const, "const") -CARBON_KEYWORD_TOKEN(Constraint, "constraint") 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") CARBON_KEYWORD_TOKEN(Final, "final") -CARBON_KEYWORD_TOKEN(Fn, "fn") CARBON_KEYWORD_TOKEN(For, "for") CARBON_KEYWORD_TOKEN(Forall, "forall") CARBON_KEYWORD_TOKEN(Friend, "friend") CARBON_KEYWORD_TOKEN(If, "if") -CARBON_KEYWORD_TOKEN(Impl, "impl") CARBON_KEYWORD_TOKEN(Impls, "impls") -CARBON_KEYWORD_TOKEN(Import, "import") CARBON_KEYWORD_TOKEN(In, "in") -CARBON_KEYWORD_TOKEN(Interface, "interface") -CARBON_KEYWORD_TOKEN(Let, "let") -CARBON_KEYWORD_TOKEN(Library, "library") CARBON_KEYWORD_TOKEN(Like, "like") CARBON_KEYWORD_TOKEN(Match, "match") -CARBON_KEYWORD_TOKEN(Namespace, "namespace") CARBON_KEYWORD_TOKEN(Not, "not") CARBON_KEYWORD_TOKEN(Observe, "observe") CARBON_TOKEN_WITH_VIRTUAL_NODE( CARBON_KEYWORD_TOKEN(Or, "or")) -CARBON_KEYWORD_TOKEN(Package, "package") CARBON_KEYWORD_TOKEN(Partial, "partial") CARBON_KEYWORD_TOKEN(Private, "private") CARBON_KEYWORD_TOKEN(Protected, "protected") @@ -200,11 +211,12 @@ CARBON_KEYWORD_TOKEN(True, "true") CARBON_KEYWORD_TOKEN(Type, "type") // Underscore is tokenized as a keyword because it's part of identifiers. CARBON_KEYWORD_TOKEN(Underscore, "_") -CARBON_KEYWORD_TOKEN(Var, "var") CARBON_KEYWORD_TOKEN(Virtual, "virtual") CARBON_KEYWORD_TOKEN(Where, "where") CARBON_KEYWORD_TOKEN(While, "while") + // clang-format on +#undef CARBON_DECL_INTRODUCER_TOKEN #undef CARBON_KEYWORD_TOKEN CARBON_TOKEN(Identifier) diff --git a/toolchain/lex/token_kind.h b/toolchain/lex/token_kind.h index 3b41fc2a408a..bde12c7bb68c 100644 --- a/toolchain/lex/token_kind.h +++ b/toolchain/lex/token_kind.h @@ -30,6 +30,9 @@ class TokenKind : public CARBON_ENUM_BASE(TokenKind) { using EnumBase::EnumBase; + // Permit creation from RawEnumType for templates. + using EnumBase::Make; + // Permit conversion to integer for use as an array index. using EnumBase::AsInt;