mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:50:13 +01:00
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).
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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<int8_t>(order)];
|
||||
}
|
||||
@@ -43,7 +23,8 @@ struct DeclIntroducerState {
|
||||
ordered_modifier_node_ids[static_cast<int8_t>(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 <Lex::TokenKind::RawEnumType Kind>
|
||||
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 <Lex::TokenKind::RawEnumType Kind>
|
||||
requires(IsDeclIntroducer<Kind>())
|
||||
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 <Lex::TokenKind::RawEnumType Kind>
|
||||
requires(IsDeclIntroducer<Kind>())
|
||||
auto Pop() -> DeclIntroducerState {
|
||||
CARBON_CHECK(stack_.back().kind == Kind)
|
||||
<< "Found: " << stack_.back().kind
|
||||
<< " expected: " << Lex::TokenKind::Make(Kind);
|
||||
return stack_.pop_back_val();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Lex::TokenKind::Alias>();
|
||||
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<Lex::TokenKind::Alias>();
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Access);
|
||||
if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Access)) {
|
||||
context.TODO(introducer.modifier_node_id(ModifierOrder::Access),
|
||||
|
||||
@@ -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<Lex::TokenKind::Class>();
|
||||
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<Lex::TokenKind::Class>();
|
||||
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<Lex::TokenKind::Adapt>();
|
||||
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<Lex::TokenKind::Adapt>();
|
||||
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<Lex::TokenKind::Base>();
|
||||
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<Lex::TokenKind::Base>();
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Extend);
|
||||
if (!introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) {
|
||||
CARBON_DIAGNOSTIC(BaseMissingExtend, Error,
|
||||
|
||||
@@ -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<Lex::TokenKind::Export>();
|
||||
// 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<Lex::TokenKind::Export>();
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::None);
|
||||
|
||||
if (name_context.state == DeclNameStack::NameContext::State::Error) {
|
||||
|
||||
@@ -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<Lex::TokenKind::Fn>();
|
||||
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<Lex::TokenKind::Fn>();
|
||||
DiagnoseModifiers(context, introducer, is_definition, parent_scope_inst_id,
|
||||
parent_scope_inst);
|
||||
if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Access)) {
|
||||
|
||||
@@ -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<Lex::TokenKind::Impl>();
|
||||
|
||||
// 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<Lex::TokenKind::Impl>();
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::ImplDecl);
|
||||
|
||||
// Finish processing the name, which should be empty, but might have
|
||||
|
||||
@@ -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<Lex::TokenKind::Import>();
|
||||
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<Lex::TokenKind::Import>();
|
||||
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<Lex::TokenKind::Library>();
|
||||
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<Lex::TokenKind::Library>();
|
||||
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<Lex::TokenKind::Package>();
|
||||
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<Lex::TokenKind::Package>();
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Impl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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<Lex::TokenKind::Interface>();
|
||||
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<Lex::TokenKind::Interface>();
|
||||
CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst);
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Access);
|
||||
|
||||
|
||||
@@ -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<Lex::TokenKind::Let>();
|
||||
// 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<Lex::TokenKind::Let>();
|
||||
CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst);
|
||||
RequireDefaultFinalOnlyInInterfaces(context, introducer, parent_scope_inst);
|
||||
LimitModifiersOnDecl(
|
||||
|
||||
@@ -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<Lex::TokenKind::Var>();
|
||||
return context.TODO(node_id, "HandleForIn");
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Lex::TokenKind::Namespace>();
|
||||
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<Lex::TokenKind::Namespace>();
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::None);
|
||||
|
||||
auto namespace_inst = SemIR::Namespace{
|
||||
|
||||
@@ -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<Lex::TokenKind::Var>();
|
||||
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<Lex::TokenKind::Var>();
|
||||
CheckAccessModifiersOnDecl(context, introducer, parent_scope_inst);
|
||||
LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Access);
|
||||
if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Access)) {
|
||||
|
||||
@@ -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<ModifierOrder>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user