mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 10:21:04 +01:00
Move child count and bracketing information for parse nodes into the node kind definition. (#4000)
Instead of tracking the bracketing and child count information in the kind macro in `node_kind.def`, provide it to `NodeKind::Define` in `typed_nodes.h`. If a node is both bracketed and has a fixed child count, track both facts and check them both in tree verification, since it's easy to do so now. The overall goal here is to reduce `node_kind.def` down to a simple list of names. I have a slightly different approach in mind for the token kinds. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com> Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
Carbon Infra Bot
parent
512583d744
commit
419d2e39d8
@@ -39,55 +39,17 @@ CARBON_DEFINE_ENUM_CLASS_NAMES(NodeKind) = {
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
};
|
||||
|
||||
auto NodeKind::has_bracket() const -> bool {
|
||||
static constexpr bool HasBracket[] = {
|
||||
#define CARBON_PARSE_NODE_KIND_BRACKET(...) true,
|
||||
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(...) false,
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
};
|
||||
return HasBracket[AsInt()];
|
||||
}
|
||||
|
||||
auto NodeKind::bracket() const -> NodeKind {
|
||||
// Nodes are never self-bracketed, so we use that for nodes that instead set
|
||||
// child_count.
|
||||
static constexpr NodeKind Bracket[] = {
|
||||
#define CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, ...) \
|
||||
NodeKind::BracketName,
|
||||
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ...) NodeKind::Name,
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
};
|
||||
auto bracket = Bracket[AsInt()];
|
||||
CARBON_CHECK(bracket != *this) << *this;
|
||||
return bracket;
|
||||
}
|
||||
|
||||
auto NodeKind::child_count() const -> int32_t {
|
||||
static constexpr int32_t ChildCount[] = {
|
||||
#define CARBON_PARSE_NODE_KIND_BRACKET(...) -1,
|
||||
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, Size, ...) Size,
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
};
|
||||
auto child_count = ChildCount[AsInt()];
|
||||
CARBON_CHECK(child_count >= 0) << *this;
|
||||
return child_count;
|
||||
}
|
||||
|
||||
auto NodeKind::CheckMatchesTokenKind(Lex::TokenKind token_kind, bool has_error)
|
||||
-> void {
|
||||
static constexpr Lex::TokenKind TokenIfValid[] = {
|
||||
#define CARBON_IF_VALID(LexTokenKind) LexTokenKind
|
||||
#define CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, LexTokenKind) \
|
||||
Lex::TokenKind::LexTokenKind,
|
||||
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, Size, LexTokenKind) \
|
||||
#define CARBON_PARSE_NODE_KIND_WITH_TOKEN(Name, LexTokenKind) \
|
||||
Lex::TokenKind::LexTokenKind,
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
};
|
||||
static constexpr Lex::TokenKind TokenIfError[] = {
|
||||
#define CARBON_IF_VALID(LexTokenKind) Error
|
||||
#define CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, LexTokenKind) \
|
||||
Lex::TokenKind::LexTokenKind,
|
||||
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, Size, LexTokenKind) \
|
||||
#define CARBON_PARSE_NODE_KIND_WITH_TOKEN(Name, LexTokenKind) \
|
||||
Lex::TokenKind::LexTokenKind,
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
};
|
||||
@@ -102,6 +64,20 @@ auto NodeKind::CheckMatchesTokenKind(Lex::TokenKind token_kind, bool has_error)
|
||||
<< ", but expected token kind " << expected_token_kind;
|
||||
}
|
||||
|
||||
auto NodeKind::has_bracket() const -> bool {
|
||||
return definition().has_bracket();
|
||||
}
|
||||
|
||||
auto NodeKind::bracket() const -> NodeKind { return definition().bracket(); }
|
||||
|
||||
auto NodeKind::has_child_count() const -> bool {
|
||||
return definition().has_child_count();
|
||||
}
|
||||
|
||||
auto NodeKind::child_count() const -> int32_t {
|
||||
return definition().child_count();
|
||||
}
|
||||
|
||||
auto NodeKind::category() const -> NodeCategory {
|
||||
return definition().category();
|
||||
}
|
||||
|
||||
+182
-227
@@ -10,12 +10,8 @@
|
||||
// Supported x-macros are:
|
||||
// - CARBON_PARSE_NODE_KIND(Name)
|
||||
// Used as a fallback if other macros are missing.
|
||||
// - CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, LexTokenKind)
|
||||
// Defines a bracketed node kind. BracketName should refer to the node
|
||||
// kind that is the _start_ of the bracketed range.
|
||||
// - CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ChildCount, LexTokenKind)
|
||||
// Defines a parse node with a set number of children, often 0. This count
|
||||
// must be correct even when the node contains errors.
|
||||
// - CARBON_PARSE_NODE_KIND_WITH_TOKEN(Name, LexTokenKind)
|
||||
// Defines a parse node kind and specifies its corresponding token kind.
|
||||
// - CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name)
|
||||
// Defines a parse node for a prefix operator, with the Name as token.
|
||||
// - CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name)
|
||||
@@ -39,22 +35,18 @@
|
||||
// This tree represents the subset relationship between these macros, where if a
|
||||
// specific x-macro isn't defined, it'll fall back to the parent macro.
|
||||
//
|
||||
// Parse nodes are clustered based on language feature. Comments will show their
|
||||
// relationship in postorder, using indentation for child node relationships.
|
||||
// Parse nodes are clustered based on language feature. See typed_nodes.h for
|
||||
// the expected tree structure under each node kind.
|
||||
|
||||
#if !(defined(CARBON_PARSE_NODE_KIND) || \
|
||||
(defined(CARBON_PARSE_NODE_KIND_BRACKET) && \
|
||||
defined(CARBON_PARSE_NODE_KIND_CHILD_COUNT)))
|
||||
#if !(defined(CARBON_PARSE_NODE_KIND) || \
|
||||
defined(CARBON_PARSE_NODE_KIND_WITH_TOKEN))
|
||||
#error "Must define CARBON_PARSE_NODE_KIND family x-macros to use this file."
|
||||
#endif
|
||||
|
||||
// The BRACKET and CHILD_COUNT macros will use CARBON_PARSE_NODE_KIND by default
|
||||
// when undefined.
|
||||
#ifndef CARBON_PARSE_NODE_KIND_BRACKET
|
||||
#define CARBON_PARSE_NODE_KIND_BRACKET(Name, ...) CARBON_PARSE_NODE_KIND(Name)
|
||||
#endif
|
||||
#ifndef CARBON_PARSE_NODE_KIND_CHILD_COUNT
|
||||
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ...) \
|
||||
// The WITH_TOKEN macro will use CARBON_PARSE_NODE_KIND by default when
|
||||
// undefined.
|
||||
#ifndef CARBON_PARSE_NODE_KIND_WITH_TOKEN
|
||||
#define CARBON_PARSE_NODE_KIND_WITH_TOKEN(Name, LexTokenKind) \
|
||||
CARBON_PARSE_NODE_KIND(Name)
|
||||
#endif
|
||||
|
||||
@@ -65,7 +57,7 @@
|
||||
// #define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name, ...) <code>
|
||||
#ifndef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR
|
||||
#define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name) \
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PrefixOperator##Name, 1, Name)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PrefixOperator##Name, Name)
|
||||
#endif
|
||||
|
||||
// This is expected to be used with something like:
|
||||
@@ -75,7 +67,7 @@
|
||||
// #define CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name, ...) <code>
|
||||
#ifndef CARBON_PARSE_NODE_KIND_INFIX_OPERATOR
|
||||
#define CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name) \
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InfixOperator##Name, 2, Name)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InfixOperator##Name, Name)
|
||||
#endif
|
||||
|
||||
// This is expected to be used with something like:
|
||||
@@ -85,7 +77,7 @@
|
||||
// #define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name, ...) <code>
|
||||
#ifndef CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR
|
||||
#define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name) \
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PostfixOperator##Name, 1, Name)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PostfixOperator##Name, Name)
|
||||
#endif
|
||||
|
||||
// This is expected to be used with something like:
|
||||
@@ -95,7 +87,7 @@
|
||||
// #define CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, ...) <code>
|
||||
#ifndef CARBON_PARSE_NODE_KIND_TOKEN_LITERAL
|
||||
#define CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, LexTokenKinds) \
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, 0, LexTokenKinds)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Name, LexTokenKinds)
|
||||
#endif
|
||||
|
||||
// This is expected to be used with something like:
|
||||
@@ -105,49 +97,48 @@
|
||||
// #define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name, ...) <code>
|
||||
#ifndef CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER
|
||||
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name) \
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name##Modifier, 0, Name)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Name##Modifier, Name)
|
||||
#endif
|
||||
|
||||
// The start of the file.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(FileStart, 0, FileStart)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(FileStart, FileStart)
|
||||
|
||||
// The end of the file.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(FileEnd, 0, FileEnd)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(FileEnd, FileEnd)
|
||||
|
||||
// An invalid parse. Used to balance the parse tree. Always has an error.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InvalidParse, 0, Error)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InvalidParse, Error)
|
||||
|
||||
// An invalid subtree. Always has an error.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InvalidParseStart, 0, Error)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(InvalidParseSubtree, InvalidParseStart, Error)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InvalidParseStart, Error)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InvalidParseSubtree, Error)
|
||||
|
||||
// A placeholder node to be replaced; it will never exist in a valid parse tree.
|
||||
// Its token kind is not enforced even when valid.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Placeholder, 0, Error)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Placeholder, Error)
|
||||
|
||||
// An empty declaration, such as `;`.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(EmptyDecl, 0, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(EmptyDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// An identifier name in a non-expression context, such as a declaration.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IdentifierName, 0,
|
||||
CARBON_IF_VALID(Identifier))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IdentifierName, CARBON_IF_VALID(Identifier))
|
||||
|
||||
// An identifier name in an expression context.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IdentifierNameExpr, 0, Identifier)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IdentifierNameExpr, Identifier)
|
||||
|
||||
// The `self` value and `Self` type identifier keywords. Typically of the form
|
||||
// `self: Self`.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(SelfValueName, 0, SelfValueIdentifier)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(SelfValueNameExpr, 0, SelfValueIdentifier)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(SelfTypeNameExpr, 0, SelfTypeIdentifier)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(SelfValueName, SelfValueIdentifier)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(SelfValueNameExpr, SelfValueIdentifier)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(SelfTypeNameExpr, SelfTypeIdentifier)
|
||||
|
||||
// The `base` value keyword, introduced by `base: B`. Typically referenced in
|
||||
// an expression, as in `x.base` or `{.base = ...}`, but can also be used as a
|
||||
// declared name, as in `{.base: partial B}`.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BaseName, 0, Base)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BaseName, Base)
|
||||
|
||||
// The `package` keyword in an expression.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageExpr, 0, Package)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PackageExpr, Package)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -177,8 +168,8 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageExpr, 0, Package)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// The name of a package or library for `package`, `import`, and `library`.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageName, 0, Identifier)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibraryName, 0, StringLiteral)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PackageName, Identifier)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LibraryName, StringLiteral)
|
||||
|
||||
// `package`:
|
||||
// PackageIntroducer
|
||||
@@ -186,9 +177,8 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibraryName, 0, StringLiteral)
|
||||
// _optional_ _external_: PackageName
|
||||
// _optional_ _external_: LibrarySpecifier
|
||||
// PackageDecl
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageIntroducer, 0, Package)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(PackageDecl, PackageIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PackageIntroducer, Package)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PackageDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `import`:
|
||||
// ImportIntroducer
|
||||
@@ -196,24 +186,22 @@ CARBON_PARSE_NODE_KIND_BRACKET(PackageDecl, PackageIntroducer,
|
||||
// _optional_ _external_: PackageName
|
||||
// _optional_ _external_: LibrarySpecifier
|
||||
// ImportDecl
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImportIntroducer, 0, Import)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ImportDecl, ImportIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImportIntroducer, Import)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImportDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `library` as declaration:
|
||||
// LibraryIntroducer
|
||||
// _repeated_ _external_: modifier
|
||||
// DefaultLibrary or _external_: LibraryName
|
||||
// LibraryDecl
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(DefaultLibrary, 0, Default)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibraryIntroducer, 0, Library)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(LibraryDecl, LibraryIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(DefaultLibrary, Default)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LibraryIntroducer, Library)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LibraryDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `library` in `package` or `import`:
|
||||
// _external_: LibraryName or DefaultLibrary
|
||||
// LibrarySpecifier
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibrarySpecifier, 1, Library)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LibrarySpecifier, Library)
|
||||
|
||||
// Declaration names.
|
||||
//
|
||||
@@ -227,33 +215,30 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibrarySpecifier, 1, Library)
|
||||
// _optional_ _external_: ImplicitParamList
|
||||
// _optional_ _external_: TuplePattern
|
||||
// NameQualifier
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(NameQualifier, IdentifierName,
|
||||
CARBON_IF_VALID(Period))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(NameQualifier, CARBON_IF_VALID(Period))
|
||||
|
||||
// `export`:
|
||||
// ExportIntroducer
|
||||
// _external_: _declaration name_
|
||||
// ExportDecl
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExportIntroducer, 0, Export)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ExportDecl, ExportIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ExportIntroducer, Export)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ExportDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `namespace`:
|
||||
// NamespaceStart
|
||||
// _repeated_ _external_: modifier
|
||||
// _external_: _declaration name_
|
||||
// Namespace
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(NamespaceStart, 0, Namespace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(Namespace, NamespaceStart, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(NamespaceStart, Namespace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Namespace, CARBON_IF_VALID(Semi))
|
||||
|
||||
// A code block:
|
||||
// CodeBlockStart
|
||||
// _repeated_ _external_: statement
|
||||
// CodeBlock
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CodeBlockStart, 0,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(CodeBlock, CodeBlockStart,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(CodeBlockStart,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(CodeBlock, CARBON_IF_VALID(CloseCurlyBrace))
|
||||
|
||||
// `fn` declarations start with a function signature:
|
||||
//
|
||||
@@ -277,20 +262,15 @@ CARBON_PARSE_NODE_KIND_BRACKET(CodeBlock, CodeBlockStart,
|
||||
// BuiltinFunctionDefinitionStart
|
||||
// BuiltinName
|
||||
// BuiltinFunctionDefinition
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(FunctionIntroducer, 0, Fn)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnType, 1, MinusGreater)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinitionStart, FunctionIntroducer,
|
||||
OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinition, FunctionDefinitionStart,
|
||||
CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(FunctionDecl, FunctionIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(BuiltinFunctionDefinitionStart,
|
||||
FunctionIntroducer, Equal)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BuiltinName, 0, StringLiteral)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(BuiltinFunctionDefinition,
|
||||
BuiltinFunctionDefinitionStart,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(FunctionIntroducer, Fn)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ReturnType, MinusGreater)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(FunctionDefinitionStart, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(FunctionDefinition, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(FunctionDecl, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BuiltinFunctionDefinitionStart, Equal)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BuiltinName, StringLiteral)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BuiltinFunctionDefinition,
|
||||
CARBON_IF_VALID(Semi))
|
||||
|
||||
// `alias`:
|
||||
// AliasIntroducer
|
||||
@@ -299,9 +279,9 @@ CARBON_PARSE_NODE_KIND_BRACKET(BuiltinFunctionDefinition,
|
||||
// AliasInitializer
|
||||
// _external_: expression
|
||||
// Alias
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(AliasIntroducer, 0, Alias)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(AliasInitializer, 0, Equal)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(Alias, AliasIntroducer, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(AliasIntroducer, Alias)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(AliasInitializer, Equal)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Alias, CARBON_IF_VALID(Semi))
|
||||
|
||||
// A tuple pattern:
|
||||
// TuplePatternStart
|
||||
@@ -312,9 +292,9 @@ CARBON_PARSE_NODE_KIND_BRACKET(Alias, AliasIntroducer, CARBON_IF_VALID(Semi))
|
||||
//
|
||||
// Patterns and PatternListComma may repeat with PatternListComma as a
|
||||
// separator.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TuplePatternStart, 0, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PatternListComma, 0, Comma)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(TuplePattern, TuplePatternStart, CloseParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(TuplePatternStart, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PatternListComma, Comma)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(TuplePattern, CloseParen)
|
||||
|
||||
// An implicit parameter list:
|
||||
// ImplicitParamListStart
|
||||
@@ -325,9 +305,8 @@ CARBON_PARSE_NODE_KIND_BRACKET(TuplePattern, TuplePatternStart, CloseParen)
|
||||
//
|
||||
// Patterns and PatternListComma may repeat with PatternListComma as a
|
||||
// separator.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplicitParamListStart, 0, OpenSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ImplicitParamList, ImplicitParamListStart,
|
||||
CloseSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplicitParamListStart, OpenSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplicitParamList, CloseSquareBracket)
|
||||
|
||||
// An array type, such as `[i32; 3]` or `[i32;]`:
|
||||
// ArrayExprStart
|
||||
@@ -335,9 +314,9 @@ CARBON_PARSE_NODE_KIND_BRACKET(ImplicitParamList, ImplicitParamListStart,
|
||||
// ArrayExprSemi
|
||||
// _optional_ _external_: expression
|
||||
// ArrayExpr
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExprStart, 0, OpenSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExprSemi, 2, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ArrayExpr, ArrayExprSemi, CloseSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ArrayExprStart, OpenSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ArrayExprSemi, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ArrayExpr, CloseSquareBracket)
|
||||
|
||||
// A binding pattern, such as `name: Type`:
|
||||
// IdentifierName or SelfValueName
|
||||
@@ -345,10 +324,10 @@ CARBON_PARSE_NODE_KIND_BRACKET(ArrayExpr, ArrayExprSemi, CloseSquareBracket)
|
||||
// [Generic]BindingPattern
|
||||
// _optional_ Addr
|
||||
// _optional_ Template
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BindingPattern, 2, CARBON_IF_VALID(Colon))
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CompileTimeBindingPattern, 2, ColonExclaim)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Addr, 1, Addr)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Template, 1, Template)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BindingPattern, CARBON_IF_VALID(Colon))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(CompileTimeBindingPattern, ColonExclaim)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Addr, Addr)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(Template, Template)
|
||||
|
||||
// `let` declarations, including associated constant declarations:
|
||||
// LetIntroducer
|
||||
@@ -363,9 +342,9 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(Template, 1, Template)
|
||||
//
|
||||
// The LetInitializer and following expression are paired: either both will be
|
||||
// present, or neither will.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LetIntroducer, 0, Let)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LetInitializer, 0, Equal)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(LetDecl, LetIntroducer, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LetIntroducer, Let)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LetInitializer, Equal)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(LetDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `var` and `returned var`:
|
||||
// VariableIntroducer
|
||||
@@ -382,37 +361,35 @@ CARBON_PARSE_NODE_KIND_BRACKET(LetDecl, LetIntroducer, CARBON_IF_VALID(Semi))
|
||||
//
|
||||
// The VariableInitializer and following expression are paired: either both will
|
||||
// be present, or neither will.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableIntroducer, 0, CARBON_IF_VALID(Var))
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnedModifier, 0, Returned)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 0, Equal)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(VariableDecl, VariableIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(VariableIntroducer, CARBON_IF_VALID(Var))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ReturnedModifier, Returned)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(VariableInitializer, Equal)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(VariableDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// An expression statement:
|
||||
// _external_: expression
|
||||
// ExprStatement
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExprStatement, 1, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ExprStatement, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `break`:
|
||||
// BreakStatementStart
|
||||
// BreakStatement
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatementStart, 0, Break)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatement, 1, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BreakStatementStart, Break)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BreakStatement, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `continue`:
|
||||
// ContinueStatementStart
|
||||
// ContinueStatement
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatementStart, 0, Continue)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatement, 1, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ContinueStatementStart, Continue)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ContinueStatement, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `return`:
|
||||
// ReturnStatementStart
|
||||
// _optional_ ReturnVarModifier or _external_: expression
|
||||
// ReturnStatement
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnStatementStart, 0, Return)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnVarModifier, 0, Var)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ReturnStatement, ReturnStatementStart,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ReturnStatementStart, Return)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ReturnVarModifier, Var)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ReturnStatement, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `for`:
|
||||
// ForHeaderStart
|
||||
@@ -425,12 +402,10 @@ CARBON_PARSE_NODE_KIND_BRACKET(ReturnStatement, ReturnStatementStart,
|
||||
// ForStatement
|
||||
//
|
||||
// Versus a normal `var`, ForIn replaces VariableDecl.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForHeaderStart, 0,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ForIn, VariableIntroducer, CARBON_IF_VALID(In))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ForHeader, ForHeaderStart,
|
||||
CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForStatement, 2, For)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ForHeaderStart, CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ForIn, CARBON_IF_VALID(In))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ForHeader, CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ForStatement, For)
|
||||
|
||||
// `if` statement + `else`:
|
||||
// IfConditionStart
|
||||
@@ -442,12 +417,10 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForStatement, 2, For)
|
||||
// IfStatement
|
||||
//
|
||||
// IfStatementElse and the following node are optional based on `else` presence.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfConditionStart, 0,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(IfCondition, IfConditionStart,
|
||||
CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatementElse, 0, Else)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(IfStatement, IfCondition, If)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfConditionStart, CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfCondition, CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfStatementElse, Else)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfStatement, If)
|
||||
|
||||
// `while`:
|
||||
// WhileConditionStart
|
||||
@@ -455,26 +428,25 @@ CARBON_PARSE_NODE_KIND_BRACKET(IfStatement, IfCondition, If)
|
||||
// WhileCondition
|
||||
// _external_: CodeBlock
|
||||
// WhileStatement
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileConditionStart, 0,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(WhileCondition, WhileConditionStart,
|
||||
CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileStatement, 2, While)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(WhileConditionStart,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(WhileCondition, CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(WhileStatement, While)
|
||||
|
||||
// Index expressions, such as `a[1]`:
|
||||
// _external_: expression
|
||||
// IndexExprStart
|
||||
// _external_: expression
|
||||
// IndexExpr
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IndexExprStart, 1, OpenSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(IndexExpr, IndexExprStart, CloseSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IndexExprStart, OpenSquareBracket)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IndexExpr, CloseSquareBracket)
|
||||
|
||||
// Parenthesized single expressions, such as `(2)`:
|
||||
// ParenExprStart
|
||||
// _external_: expression
|
||||
// ParenExpr
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParenExprStart, 0, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ParenExpr, ParenExprStart, CloseParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ParenExprStart, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ParenExpr, CloseParen)
|
||||
|
||||
// Tuples, such as `(1, 2)`:
|
||||
// TupleLiteralStart
|
||||
@@ -485,9 +457,9 @@ CARBON_PARSE_NODE_KIND_BRACKET(ParenExpr, ParenExprStart, CloseParen)
|
||||
//
|
||||
// Expressions and TupleLiteralComma may repeat with TupleLiteralComma as a
|
||||
// separator.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteralStart, 0, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteralComma, 0, Comma)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(TupleLiteral, TupleLiteralStart, CloseParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(TupleLiteralStart, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(TupleLiteralComma, Comma)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(TupleLiteral, CloseParen)
|
||||
|
||||
// Call expressions, such as `a()`:
|
||||
// _external_: expression
|
||||
@@ -498,23 +470,23 @@ CARBON_PARSE_NODE_KIND_BRACKET(TupleLiteral, TupleLiteralStart, CloseParen)
|
||||
// CallExpr
|
||||
//
|
||||
// Exprs and CallExprComma may repeat with CallExprComma as a separator.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExprStart, 1, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExprComma, 0, Comma)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(CallExpr, CallExprStart, CloseParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(CallExprStart, OpenParen)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(CallExprComma, Comma)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(CallExpr, CloseParen)
|
||||
|
||||
// A member access expression, such as `a.b` or
|
||||
// `GetObject().(Interface.member)`:
|
||||
// _external_: lhs expression
|
||||
// _external_: rhs expression
|
||||
// MemberAccessExpr
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MemberAccessExpr, 2, Period)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MemberAccessExpr, Period)
|
||||
|
||||
// A pointer member access expression, such as `a->b` or
|
||||
// `GetObject()->(Interface.member)`:
|
||||
// _external_: lhs expression
|
||||
// _external_: rhs expression
|
||||
// PointerMemberAccessExpr
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PointerMemberAccessExpr, 2, MinusGreater)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(PointerMemberAccessExpr, MinusGreater)
|
||||
|
||||
// A value literal.
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolLiteralFalse, False)
|
||||
@@ -589,10 +561,10 @@ CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Star)
|
||||
// ShortCircuitOperand(And|Or)
|
||||
// _external_: expression
|
||||
// ShortCircuitOperand(And|Or)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperandAnd, 1, And)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperandOr, 1, Or)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorAnd, 2, And)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorOr, 2, Or)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ShortCircuitOperandAnd, And)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ShortCircuitOperandOr, Or)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ShortCircuitOperatorAnd, And)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ShortCircuitOperatorOr, Or)
|
||||
|
||||
// `if` expression + `then` + `else`:
|
||||
// _external_: expression
|
||||
@@ -601,9 +573,9 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorOr, 2, Or)
|
||||
// IfExprThen
|
||||
// _external_: expression
|
||||
// IfExprElse
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprIf, 1, If)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprThen, 1, Then)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprElse, 3, CARBON_IF_VALID(Else))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfExprIf, If)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfExprThen, Then)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(IfExprElse, CARBON_IF_VALID(Else))
|
||||
|
||||
// Struct literals, such as `{.a = 0}`:
|
||||
// StructLiteralStart
|
||||
@@ -631,16 +603,14 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprElse, 3, CARBON_IF_VALID(Else))
|
||||
// When a valid StructTypeField or StructField cannot be formed, elements
|
||||
// may be replaced by InvalidParse, which may have a preceding sibling
|
||||
// StructFieldDesignator if one was successfully parsed.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructLiteralStart, 0, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructTypeLiteralStart, 0, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldDesignator, 1, Period)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructField, 2, Equal)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructTypeField, 2, Colon)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructComma, 0, Comma)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(StructLiteral, StructLiteralStart,
|
||||
CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(StructTypeLiteral, StructTypeLiteralStart,
|
||||
CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructLiteralStart, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructTypeLiteralStart, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructFieldDesignator, Period)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructField, Equal)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructTypeField, Colon)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructComma, Comma)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructLiteral, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(StructTypeLiteral, CloseCurlyBrace)
|
||||
|
||||
// Various modifiers. These are all a single token.
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Abstract)
|
||||
@@ -668,22 +638,18 @@ CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Virtual)
|
||||
// The above is the structure for a definition; for a declaration,
|
||||
// ClassDefinitionStart and later nodes are removed and replaced by
|
||||
// ClassDecl.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ClassIntroducer, 0, Class)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ClassDefinitionStart, ClassIntroducer,
|
||||
OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ClassDefinition, ClassDefinitionStart,
|
||||
CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ClassDecl, ClassIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ClassIntroducer, Class)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ClassDefinitionStart, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ClassDefinition, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ClassDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `adapt`:
|
||||
// AdaptIntroducer
|
||||
// _repeated_ _external_: modifier
|
||||
// _external_: expression
|
||||
// AdaptDecl
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(AdaptIntroducer, 0, Adapt)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(AdaptDecl, AdaptIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(AdaptIntroducer, Adapt)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(AdaptDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `base`:
|
||||
// BaseIntroducer
|
||||
@@ -691,9 +657,9 @@ CARBON_PARSE_NODE_KIND_BRACKET(AdaptDecl, AdaptIntroducer,
|
||||
// BaseColon
|
||||
// _external_: expression
|
||||
// BaseDecl
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BaseIntroducer, 0, Base)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BaseColon, 0, Colon)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(BaseDecl, BaseIntroducer, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BaseIntroducer, Base)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BaseColon, Colon)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(BaseDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `interface`:
|
||||
// InterfaceIntroducer
|
||||
@@ -708,13 +674,10 @@ CARBON_PARSE_NODE_KIND_BRACKET(BaseDecl, BaseIntroducer, CARBON_IF_VALID(Semi))
|
||||
// The above is the structure for a definition; for a declaration,
|
||||
// InterfaceDefinitionStart and later nodes are removed and replaced by
|
||||
// InterfaceDecl.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InterfaceIntroducer, 0, Interface)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDefinitionStart, InterfaceIntroducer,
|
||||
OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDefinition, InterfaceDefinitionStart,
|
||||
CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDecl, InterfaceIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InterfaceIntroducer, Interface)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InterfaceDefinitionStart, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InterfaceDefinition, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(InterfaceDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `impl ... as`:
|
||||
// ImplIntroducer
|
||||
@@ -730,24 +693,22 @@ CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDecl, InterfaceIntroducer,
|
||||
// The above is the structure for a definition; for a declaration,
|
||||
// ImplDefinitionStart and later nodes are removed and replaced by
|
||||
// ImplDecl.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplIntroducer, 0, Impl)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ImplDefinitionStart, ImplIntroducer,
|
||||
OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ImplDefinition, ImplDefinitionStart,
|
||||
CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ImplDecl, ImplIntroducer, CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplIntroducer, Impl)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplDefinitionStart, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplDefinition, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `forall ...`:
|
||||
// _external_: ImplicitParamList
|
||||
// ImplForall
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplForall, 1, Forall)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ImplForall, Forall)
|
||||
|
||||
// `... as`:
|
||||
// _external_: expression
|
||||
// TypeImplAs
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TypeImplAs, 1, As)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(TypeImplAs, As)
|
||||
// `as` without a type before it
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(DefaultSelfImplAs, 0, As)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(DefaultSelfImplAs, As)
|
||||
|
||||
// `constraint`:
|
||||
// NamedConstraintIntroducer
|
||||
@@ -762,13 +723,11 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(DefaultSelfImplAs, 0, As)
|
||||
// The above is the structure for a definition; for a declaration,
|
||||
// NamedConstraintDefinitionStart and later nodes are removed and replaced by
|
||||
// NamedConstraintDecl.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(NamedConstraintIntroducer, 0, Constraint)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDefinitionStart,
|
||||
NamedConstraintIntroducer, OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDefinition,
|
||||
NamedConstraintDefinitionStart, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDecl, NamedConstraintIntroducer,
|
||||
CARBON_IF_VALID(Semi))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(NamedConstraintIntroducer, Constraint)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(NamedConstraintDefinitionStart,
|
||||
OpenCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(NamedConstraintDefinition, CloseCurlyBrace)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(NamedConstraintDecl, CARBON_IF_VALID(Semi))
|
||||
|
||||
// `choice`:
|
||||
// ChoiceIntroducer
|
||||
@@ -776,11 +735,11 @@ CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDecl, NamedConstraintIntroducer,
|
||||
// ChoiceDefinitionStart
|
||||
// _optional_ _external_: ChoiceAlternativeList
|
||||
// ChoiceDefinition
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ChoiceIntroducer, 0, Choice)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ChoiceDefinitionStart, ChoiceIntroducer,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ChoiceDefinition, ChoiceDefinitionStart,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ChoiceIntroducer, Choice)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ChoiceDefinitionStart,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ChoiceDefinition,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
|
||||
// Choice alternative list:
|
||||
// _external_: IdentifierName
|
||||
@@ -788,7 +747,7 @@ CARBON_PARSE_NODE_KIND_BRACKET(ChoiceDefinition, ChoiceDefinitionStart,
|
||||
// _optional_: ChoiceAlternativeListComma
|
||||
// _repeated_
|
||||
// ChoiceAlternativeList
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ChoiceAlternativeListComma, 0, Comma)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(ChoiceAlternativeListComma, Comma)
|
||||
|
||||
// `match`:
|
||||
// MatchIntroducer
|
||||
@@ -799,15 +758,14 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(ChoiceAlternativeListComma, 0, Comma)
|
||||
// _repeated_ _external_: MatchCase
|
||||
// _optional_ _external_: MatchStatementDefault
|
||||
// MatchStatement
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchIntroducer, 0, Match)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchConditionStart, 0,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchCondition, MatchConditionStart,
|
||||
CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchStatementStart, MatchIntroducer,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchStatement, MatchStatementStart,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchIntroducer, Match)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchConditionStart,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCondition, CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchStatementStart,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchStatement,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
|
||||
// `case`:
|
||||
// MatchCaseIntroducer
|
||||
@@ -820,18 +778,16 @@ CARBON_PARSE_NODE_KIND_BRACKET(MatchStatement, MatchStatementStart,
|
||||
// MatchCaseStart
|
||||
// _repeated_ _external_: statement
|
||||
// MatchCase
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseIntroducer, 0, Case)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseGuardIntroducer, 0, If)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseGuardStart, 0,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchCaseGuard, MatchCaseGuardIntroducer,
|
||||
CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseEqualGreater, 0,
|
||||
CARBON_IF_VALID(EqualGreater))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchCaseStart, MatchCaseIntroducer,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchCase, MatchCaseStart,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCaseIntroducer, Case)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCaseGuardIntroducer, If)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCaseGuardStart,
|
||||
CARBON_IF_VALID(OpenParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCaseGuard, CARBON_IF_VALID(CloseParen))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCaseEqualGreater,
|
||||
CARBON_IF_VALID(EqualGreater))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCaseStart,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchCase, CARBON_IF_VALID(CloseCurlyBrace))
|
||||
|
||||
// `default`:
|
||||
// MatchDefaultIntroducer
|
||||
@@ -839,17 +795,16 @@ CARBON_PARSE_NODE_KIND_BRACKET(MatchCase, MatchCaseStart,
|
||||
// MatchDefaultStart
|
||||
// _repeated_ _external_: statement
|
||||
// MatchDefault
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchDefaultIntroducer, 0, Default)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchDefaultEqualGreater, 0,
|
||||
CARBON_IF_VALID(EqualGreater))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchDefaultStart, MatchDefaultIntroducer,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(MatchDefault, MatchDefaultStart,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchDefaultIntroducer, Default)
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchDefaultEqualGreater,
|
||||
CARBON_IF_VALID(EqualGreater))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchDefaultStart,
|
||||
CARBON_IF_VALID(OpenCurlyBrace))
|
||||
CARBON_PARSE_NODE_KIND_WITH_TOKEN(MatchDefault,
|
||||
CARBON_IF_VALID(CloseCurlyBrace))
|
||||
|
||||
#undef CARBON_PARSE_NODE_KIND
|
||||
#undef CARBON_PARSE_NODE_KIND_BRACKET
|
||||
#undef CARBON_PARSE_NODE_KIND_CHILD_COUNT
|
||||
#undef CARBON_PARSE_NODE_KIND_WITH_TOKEN
|
||||
#undef CARBON_PARSE_NODE_KIND_INFIX_OPERATOR
|
||||
#undef CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR
|
||||
#undef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR
|
||||
|
||||
+72
-10
@@ -33,7 +33,7 @@ enum class NodeCategory : uint32_t {
|
||||
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Statement)
|
||||
};
|
||||
|
||||
inline constexpr auto operator!(NodeCategory k) -> bool {
|
||||
constexpr auto operator!(NodeCategory k) -> bool {
|
||||
return !static_cast<uint32_t>(k);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,16 @@ CARBON_DEFINE_RAW_ENUM_CLASS(NodeKind, uint8_t) {
|
||||
|
||||
// A class wrapping an enumeration of the different kinds of nodes in the parse
|
||||
// tree.
|
||||
//
|
||||
// In order to allow the children of a node to be determined without relying on
|
||||
// the subtree size field in the parse node, each node kind must have one of:
|
||||
//
|
||||
// - a bracketing node kind, which is always the kind for the first child, and
|
||||
// is never the kind of any other child, or
|
||||
// - a fixed child count,
|
||||
//
|
||||
// or both. This is required even for nodes for which `Tree::node_has_errors`
|
||||
// returns `true`.
|
||||
class NodeKind : public CARBON_ENUM_BASE(NodeKind) {
|
||||
public:
|
||||
#define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CONSTANT_DECL(Name)
|
||||
@@ -57,15 +67,18 @@ class NodeKind : public CARBON_ENUM_BASE(NodeKind) {
|
||||
auto CheckMatchesTokenKind(Lex::TokenKind lex_token_kind, bool has_error)
|
||||
-> void;
|
||||
|
||||
// Returns true if the node is bracketed; otherwise, child_count is used.
|
||||
// Returns true if the node is bracketed.
|
||||
auto has_bracket() const -> bool;
|
||||
|
||||
// Returns the bracketing node kind for the current node kind. Requires that
|
||||
// has_bracket is true.
|
||||
auto bracket() const -> NodeKind;
|
||||
|
||||
// Returns true if the node is has a fixed child count.
|
||||
auto has_child_count() const -> bool;
|
||||
|
||||
// Returns the number of children that the node must have, often 0. Requires
|
||||
// that has_bracket is false.
|
||||
// that has_child_count is true.
|
||||
auto child_count() const -> int32_t;
|
||||
|
||||
// Returns which categories this node kind is in.
|
||||
@@ -78,11 +91,11 @@ class NodeKind : public CARBON_ENUM_BASE(NodeKind) {
|
||||
using EnumBase::Make;
|
||||
|
||||
class Definition;
|
||||
struct DefinitionArgs;
|
||||
|
||||
// Provides a definition for this parse node kind. Should only be called
|
||||
// once, to construct the kind as part of defining it in `typed_nodes.h`.
|
||||
constexpr auto Define(NodeCategory category = NodeCategory::None) const
|
||||
-> Definition;
|
||||
constexpr auto Define(DefinitionArgs args) const -> Definition;
|
||||
|
||||
private:
|
||||
// Looks up the definition for this instruction kind.
|
||||
@@ -107,6 +120,17 @@ static_assert(
|
||||
// We expect the parse node kind to fit compactly into 8 bits.
|
||||
static_assert(sizeof(NodeKind) == 1, "Kind objects include padding!");
|
||||
|
||||
// Optional arguments that can be supplied when defining a node kind. At least
|
||||
// one of `bracketed_by` and `child_count` is required.
|
||||
struct NodeKind::DefinitionArgs {
|
||||
// The category for the node.
|
||||
NodeCategory category = NodeCategory::None;
|
||||
// The kind of the bracketing node, which is the first child.
|
||||
std::optional<NodeKind> bracketed_by = std::nullopt;
|
||||
// The fixed child count.
|
||||
int32_t child_count = -1;
|
||||
};
|
||||
|
||||
// A definition of a parse node kind. This is a NodeKind value, plus
|
||||
// ancillary data such as the name to use for the node kind in LLVM IR. These
|
||||
// are not copyable, and only one instance of this type is expected to exist per
|
||||
@@ -118,20 +142,58 @@ class NodeKind::Definition : public NodeKind {
|
||||
Definition(const Definition&) = delete;
|
||||
auto operator=(const Definition&) -> Definition& = delete;
|
||||
|
||||
// Returns true if the node is bracketed.
|
||||
constexpr auto has_bracket() const -> bool { return bracket_ != *this; }
|
||||
|
||||
// Returns the bracketing node kind for the current node kind. Requires that
|
||||
// has_bracket is true.
|
||||
constexpr auto bracket() const -> NodeKind {
|
||||
CARBON_CHECK(has_bracket()) << *this;
|
||||
return bracket_;
|
||||
}
|
||||
|
||||
// Returns true if the node is has a fixed child count.
|
||||
constexpr auto has_child_count() const -> bool { return child_count_ >= 0; }
|
||||
|
||||
// Returns the number of children that the node must have, often 0. Requires
|
||||
// that has_child_count is true.
|
||||
constexpr auto child_count() const -> int32_t {
|
||||
CARBON_CHECK(has_child_count()) << *this;
|
||||
return child_count_;
|
||||
}
|
||||
|
||||
// Returns which categories this node kind is in.
|
||||
constexpr auto category() const -> NodeCategory { return category_; }
|
||||
|
||||
private:
|
||||
friend class NodeKind;
|
||||
|
||||
constexpr Definition(NodeKind kind, NodeCategory category)
|
||||
: NodeKind(kind), category_(category) {}
|
||||
// This is factored out and non-constexpr to improve the compile-time error
|
||||
// message if the check below fails.
|
||||
auto MustSpecifyEitherBracketingNodeOrChildCount() {
|
||||
CARBON_FATAL()
|
||||
<< "Must specify either bracketing node or fixed child count.";
|
||||
}
|
||||
|
||||
NodeCategory category_;
|
||||
constexpr explicit Definition(NodeKind kind, DefinitionArgs args)
|
||||
: NodeKind(kind),
|
||||
category_(args.category),
|
||||
bracket_(args.bracketed_by.value_or(kind)),
|
||||
child_count_(args.child_count) {
|
||||
if (!has_bracket() && !has_child_count()) {
|
||||
MustSpecifyEitherBracketingNodeOrChildCount();
|
||||
}
|
||||
}
|
||||
|
||||
NodeCategory category_ = NodeCategory::None;
|
||||
// Nodes are never self-bracketed, so we use *this to indicate that the node
|
||||
// is not bracketed.
|
||||
NodeKind bracket_ = *this;
|
||||
int32_t child_count_ = -1;
|
||||
};
|
||||
|
||||
constexpr auto NodeKind::Define(NodeCategory category) const -> Definition {
|
||||
return Definition(*this, category);
|
||||
constexpr auto NodeKind::Define(DefinitionArgs args) const -> Definition {
|
||||
return Definition(*this, args);
|
||||
}
|
||||
|
||||
// HasKindMember<T> is true if T has a `static const NodeKind::Definition Kind`
|
||||
|
||||
@@ -211,6 +211,7 @@ auto Tree::Verify() const -> ErrorOr<Success> {
|
||||
|
||||
int subtree_size = 1;
|
||||
if (n_impl.kind.has_bracket()) {
|
||||
int child_count = 0;
|
||||
while (true) {
|
||||
if (nodes.empty()) {
|
||||
return Error(
|
||||
@@ -220,7 +221,17 @@ auto Tree::Verify() const -> ErrorOr<Success> {
|
||||
}
|
||||
auto child_impl = node_impls_[nodes.pop_back_val().index];
|
||||
subtree_size += child_impl.subtree_size;
|
||||
++child_count;
|
||||
if (n_impl.kind.bracket() == child_impl.kind) {
|
||||
// If there's a bracketing node and a child count, verify the child
|
||||
// count too.
|
||||
if (n_impl.kind.has_child_count() &&
|
||||
child_count != n_impl.kind.child_count()) {
|
||||
return Error(llvm::formatv(
|
||||
"NodeId #{0} is a {1} with child_count {2}, but encountered "
|
||||
"{3} nodes before we reached the bracketing node.",
|
||||
n, n_impl.kind, n_impl.kind.child_count(), child_count));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+194
-108
@@ -29,7 +29,8 @@ using CommaSeparatedList = llvm::SmallVector<ListItem<Element, Comma>>;
|
||||
// This class provides a shorthand for defining parse node kinds for leaf nodes.
|
||||
template <const NodeKind& KindT, NodeCategory Category = NodeCategory::None>
|
||||
struct LeafNode {
|
||||
static constexpr auto Kind = KindT.Define(Category);
|
||||
static constexpr auto Kind =
|
||||
KindT.Define({.category = Category, .child_count = 0});
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -81,8 +82,9 @@ using InvalidParse =
|
||||
// An invalid subtree. Always has an error so can never be extracted.
|
||||
using InvalidParseStart = LeafNode<NodeKind::InvalidParseStart>;
|
||||
struct InvalidParseSubtree {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::InvalidParseSubtree.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::InvalidParseSubtree.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = InvalidParseStart::Kind});
|
||||
|
||||
InvalidParseStartId start;
|
||||
llvm::SmallVector<NodeIdNot<InvalidParseStart>> extra;
|
||||
@@ -139,7 +141,8 @@ struct NameAndParams {
|
||||
|
||||
// A name qualifier: `A.`, `A(T:! type).`, or `A[T:! type](N:! T).`.
|
||||
struct NameQualifier {
|
||||
static constexpr auto Kind = NodeKind::NameQualifier.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::NameQualifier.Define({.bracketed_by = IdentifierName::Kind});
|
||||
|
||||
NameAndParams name_and_params;
|
||||
};
|
||||
@@ -166,7 +169,8 @@ using PackageIntroducer = LeafNode<NodeKind::PackageIntroducer>;
|
||||
|
||||
// `library` in `package` or `import`.
|
||||
struct LibrarySpecifier {
|
||||
static constexpr auto Kind = NodeKind::LibrarySpecifier.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::LibrarySpecifier.Define({.child_count = 1});
|
||||
|
||||
NodeIdOneOf<LibraryName, DefaultLibrary> name;
|
||||
};
|
||||
@@ -174,7 +178,9 @@ struct LibrarySpecifier {
|
||||
// First line of the file, such as:
|
||||
// `impl package MyPackage library "MyLibrary";`
|
||||
struct PackageDecl {
|
||||
static constexpr auto Kind = NodeKind::PackageDecl.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind =
|
||||
NodeKind::PackageDecl.Define({.category = NodeCategory::Decl,
|
||||
.bracketed_by = PackageIntroducer::Kind});
|
||||
|
||||
PackageIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -185,7 +191,8 @@ struct PackageDecl {
|
||||
// `import TheirPackage library "TheirLibrary";`
|
||||
using ImportIntroducer = LeafNode<NodeKind::ImportIntroducer>;
|
||||
struct ImportDecl {
|
||||
static constexpr auto Kind = NodeKind::ImportDecl.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::ImportDecl.Define(
|
||||
{.category = NodeCategory::Decl, .bracketed_by = ImportIntroducer::Kind});
|
||||
|
||||
ImportIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -196,7 +203,9 @@ struct ImportDecl {
|
||||
// `library` as declaration.
|
||||
using LibraryIntroducer = LeafNode<NodeKind::LibraryIntroducer>;
|
||||
struct LibraryDecl {
|
||||
static constexpr auto Kind = NodeKind::LibraryDecl.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind =
|
||||
NodeKind::LibraryDecl.Define({.category = NodeCategory::Decl,
|
||||
.bracketed_by = LibraryIntroducer::Kind});
|
||||
|
||||
LibraryIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -206,7 +215,8 @@ struct LibraryDecl {
|
||||
// `export` as a declaration.
|
||||
using ExportIntroducer = LeafNode<NodeKind::ExportIntroducer>;
|
||||
struct ExportDecl {
|
||||
static constexpr auto Kind = NodeKind::ExportDecl.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::ExportDecl.Define(
|
||||
{.category = NodeCategory::Decl, .bracketed_by = ExportIntroducer::Kind});
|
||||
|
||||
ExportIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -220,7 +230,8 @@ using NamespaceStart = LeafNode<NodeKind::NamespaceStart>;
|
||||
|
||||
// A namespace: `namespace N;`.
|
||||
struct Namespace {
|
||||
static constexpr auto Kind = NodeKind::Namespace.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::Namespace.Define(
|
||||
{.category = NodeCategory::Decl, .bracketed_by = NamespaceStart::Kind});
|
||||
|
||||
NamespaceStartId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -232,8 +243,8 @@ struct Namespace {
|
||||
|
||||
// A pattern binding, such as `name: Type`.
|
||||
struct BindingPattern {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::BindingPattern.Define(NodeCategory::Pattern);
|
||||
static constexpr auto Kind = NodeKind::BindingPattern.Define(
|
||||
{.category = NodeCategory::Pattern, .child_count = 2});
|
||||
|
||||
NodeIdOneOf<IdentifierName, SelfValueName> name;
|
||||
AnyExprId type;
|
||||
@@ -241,8 +252,8 @@ struct BindingPattern {
|
||||
|
||||
// `name:! Type`
|
||||
struct CompileTimeBindingPattern {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::CompileTimeBindingPattern.Define(NodeCategory::Pattern);
|
||||
static constexpr auto Kind = NodeKind::CompileTimeBindingPattern.Define(
|
||||
{.category = NodeCategory::Pattern, .child_count = 2});
|
||||
|
||||
NodeIdOneOf<IdentifierName, SelfValueName> name;
|
||||
AnyExprId type;
|
||||
@@ -250,14 +261,16 @@ struct CompileTimeBindingPattern {
|
||||
|
||||
// An address-of binding: `addr self: Self*`.
|
||||
struct Addr {
|
||||
static constexpr auto Kind = NodeKind::Addr.Define(NodeCategory::Pattern);
|
||||
static constexpr auto Kind = NodeKind::Addr.Define(
|
||||
{.category = NodeCategory::Pattern, .child_count = 1});
|
||||
|
||||
AnyPatternId inner;
|
||||
};
|
||||
|
||||
// A template binding: `template T:! type`.
|
||||
struct Template {
|
||||
static constexpr auto Kind = NodeKind::Template.Define(NodeCategory::Pattern);
|
||||
static constexpr auto Kind = NodeKind::Template.Define(
|
||||
{.category = NodeCategory::Pattern, .child_count = 1});
|
||||
|
||||
// This is a CompileTimeBindingPatternId in any valid program.
|
||||
// TODO: Should the parser enforce that?
|
||||
@@ -270,7 +283,8 @@ using PatternListComma = LeafNode<NodeKind::PatternListComma>;
|
||||
// A parameter list or tuple pattern: `(a: i32, b: i32)`.
|
||||
struct TuplePattern {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::TuplePattern.Define(NodeCategory::Pattern);
|
||||
NodeKind::TuplePattern.Define({.category = NodeCategory::Pattern,
|
||||
.bracketed_by = TuplePatternStart::Kind});
|
||||
|
||||
TuplePatternStartId left_paren;
|
||||
CommaSeparatedList<AnyPatternId, PatternListCommaId> params;
|
||||
@@ -280,7 +294,8 @@ using ImplicitParamListStart = LeafNode<NodeKind::ImplicitParamListStart>;
|
||||
|
||||
// An implicit parameter list: `[T:! type, self: Self]`.
|
||||
struct ImplicitParamList {
|
||||
static constexpr auto Kind = NodeKind::ImplicitParamList.Define();
|
||||
static constexpr auto Kind = NodeKind::ImplicitParamList.Define(
|
||||
{.bracketed_by = ImplicitParamListStart::Kind});
|
||||
|
||||
ImplicitParamListStartId left_square;
|
||||
CommaSeparatedList<AnyPatternId, PatternListCommaId> params;
|
||||
@@ -293,7 +308,7 @@ using FunctionIntroducer = LeafNode<NodeKind::FunctionIntroducer>;
|
||||
|
||||
// A return type: `-> i32`.
|
||||
struct ReturnType {
|
||||
static constexpr auto Kind = NodeKind::ReturnType.Define();
|
||||
static constexpr auto Kind = NodeKind::ReturnType.Define({.child_count = 1});
|
||||
|
||||
AnyExprId type;
|
||||
};
|
||||
@@ -301,7 +316,8 @@ struct ReturnType {
|
||||
// A function signature: `fn F() -> i32`.
|
||||
template <const NodeKind& KindT, NodeCategory Category>
|
||||
struct FunctionSignature {
|
||||
static constexpr auto Kind = KindT.Define(Category);
|
||||
static constexpr auto Kind = KindT.Define(
|
||||
{.category = Category, .bracketed_by = FunctionIntroducer::Kind});
|
||||
|
||||
FunctionIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -316,8 +332,9 @@ using FunctionDefinitionStart =
|
||||
|
||||
// A function definition: `fn F() -> i32 { ... }`.
|
||||
struct FunctionDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::FunctionDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::FunctionDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = FunctionDefinitionStart::Kind});
|
||||
|
||||
FunctionDefinitionStartId signature;
|
||||
llvm::SmallVector<AnyStatementId> body;
|
||||
@@ -330,8 +347,9 @@ using BuiltinName = LeafNode<NodeKind::BuiltinName>;
|
||||
|
||||
// A builtin function definition: `fn F() -> i32 = "builtin name";`
|
||||
struct BuiltinFunctionDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::BuiltinFunctionDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::BuiltinFunctionDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = BuiltinFunctionDefinitionStart::Kind});
|
||||
|
||||
BuiltinFunctionDefinitionStartId signature;
|
||||
BuiltinNameId builtin_name;
|
||||
@@ -345,8 +363,9 @@ using AliasInitializer = LeafNode<NodeKind::AliasInitializer>;
|
||||
|
||||
// An `alias` declaration: `alias a = b;`.
|
||||
struct Alias {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::Alias.Define(NodeCategory::Decl | NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::Alias.Define(
|
||||
{.category = NodeCategory::Decl | NodeCategory::Statement,
|
||||
.bracketed_by = AliasIntroducer::Kind});
|
||||
|
||||
AliasIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -363,8 +382,9 @@ using LetInitializer = LeafNode<NodeKind::LetInitializer>;
|
||||
|
||||
// A `let` declaration: `let a: i32 = 5;`.
|
||||
struct LetDecl {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::LetDecl.Define(NodeCategory::Decl | NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::LetDecl.Define(
|
||||
{.category = NodeCategory::Decl | NodeCategory::Statement,
|
||||
.bracketed_by = LetIntroducer::Kind});
|
||||
|
||||
LetIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -387,7 +407,8 @@ using VariableInitializer = LeafNode<NodeKind::VariableInitializer>;
|
||||
// A `var` declaration: `var a: i32;` or `var a: i32 = 5;`.
|
||||
struct VariableDecl {
|
||||
static constexpr auto Kind = NodeKind::VariableDecl.Define(
|
||||
NodeCategory::Decl | NodeCategory::Statement);
|
||||
{.category = NodeCategory::Decl | NodeCategory::Statement,
|
||||
.bracketed_by = VariableIntroducer::Kind});
|
||||
|
||||
VariableIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -408,7 +429,8 @@ using CodeBlockStart = LeafNode<NodeKind::CodeBlockStart>;
|
||||
|
||||
// A code block: `{ statement; statement; ... }`.
|
||||
struct CodeBlock {
|
||||
static constexpr auto Kind = NodeKind::CodeBlock.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::CodeBlock.Define({.bracketed_by = CodeBlockStart::Kind});
|
||||
|
||||
CodeBlockStartId left_brace;
|
||||
llvm::SmallVector<AnyStatementId> statements;
|
||||
@@ -416,8 +438,8 @@ struct CodeBlock {
|
||||
|
||||
// An expression statement: `F(x);`.
|
||||
struct ExprStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ExprStatement.Define(NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::ExprStatement.Define(
|
||||
{.category = NodeCategory::Statement, .child_count = 1});
|
||||
|
||||
AnyExprId expr;
|
||||
};
|
||||
@@ -426,8 +448,10 @@ using BreakStatementStart = LeafNode<NodeKind::BreakStatementStart>;
|
||||
|
||||
// A break statement: `break;`.
|
||||
struct BreakStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::BreakStatement.Define(NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::BreakStatement.Define(
|
||||
{.category = NodeCategory::Statement,
|
||||
.bracketed_by = BreakStatementStart::Kind,
|
||||
.child_count = 1});
|
||||
|
||||
BreakStatementStartId introducer;
|
||||
};
|
||||
@@ -436,8 +460,10 @@ using ContinueStatementStart = LeafNode<NodeKind::ContinueStatementStart>;
|
||||
|
||||
// A continue statement: `continue;`.
|
||||
struct ContinueStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ContinueStatement.Define(NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::ContinueStatement.Define(
|
||||
{.category = NodeCategory::Statement,
|
||||
.bracketed_by = ContinueStatementStart::Kind,
|
||||
.child_count = 1});
|
||||
|
||||
ContinueStatementStartId introducer;
|
||||
};
|
||||
@@ -447,8 +473,9 @@ using ReturnVarModifier = LeafNode<NodeKind::ReturnVarModifier>;
|
||||
|
||||
// A return statement: `return;` or `return expr;` or `return var;`.
|
||||
struct ReturnStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ReturnStatement.Define(NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::ReturnStatement.Define(
|
||||
{.category = NodeCategory::Statement,
|
||||
.bracketed_by = ReturnStatementStart::Kind});
|
||||
|
||||
ReturnStatementStartId introducer;
|
||||
std::optional<AnyExprId> expr;
|
||||
@@ -459,7 +486,8 @@ using ForHeaderStart = LeafNode<NodeKind::ForHeaderStart>;
|
||||
|
||||
// The `var ... in` portion of a `for` statement.
|
||||
struct ForIn {
|
||||
static constexpr auto Kind = NodeKind::ForIn.Define();
|
||||
static constexpr auto Kind = NodeKind::ForIn.Define(
|
||||
{.bracketed_by = VariableIntroducer::Kind, .child_count = 2});
|
||||
|
||||
VariableIntroducerId introducer;
|
||||
AnyPatternId pattern;
|
||||
@@ -467,7 +495,8 @@ struct ForIn {
|
||||
|
||||
// The `for (var ... in ...)` portion of a `for` statement.
|
||||
struct ForHeader {
|
||||
static constexpr auto Kind = NodeKind::ForHeader.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ForHeader.Define({.bracketed_by = ForHeaderStart::Kind});
|
||||
|
||||
ForHeaderStartId introducer;
|
||||
ForInId var;
|
||||
@@ -477,7 +506,9 @@ struct ForHeader {
|
||||
// A complete `for (...) { ... }` statement.
|
||||
struct ForStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ForStatement.Define(NodeCategory::Statement);
|
||||
NodeKind::ForStatement.Define({.category = NodeCategory::Statement,
|
||||
.bracketed_by = ForHeader::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
ForHeaderId header;
|
||||
CodeBlockId body;
|
||||
@@ -487,7 +518,8 @@ using IfConditionStart = LeafNode<NodeKind::IfConditionStart>;
|
||||
|
||||
// The condition portion of an `if` statement: `(expr)`.
|
||||
struct IfCondition {
|
||||
static constexpr auto Kind = NodeKind::IfCondition.Define();
|
||||
static constexpr auto Kind = NodeKind::IfCondition.Define(
|
||||
{.bracketed_by = IfConditionStart::Kind, .child_count = 2});
|
||||
|
||||
IfConditionStartId left_paren;
|
||||
AnyExprId condition;
|
||||
@@ -497,8 +529,8 @@ using IfStatementElse = LeafNode<NodeKind::IfStatementElse>;
|
||||
|
||||
// An `if` statement: `if (expr) { ... } else { ... }`.
|
||||
struct IfStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::IfStatement.Define(NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::IfStatement.Define(
|
||||
{.category = NodeCategory::Statement, .bracketed_by = IfCondition::Kind});
|
||||
|
||||
IfConditionId head;
|
||||
CodeBlockId then;
|
||||
@@ -514,7 +546,8 @@ using WhileConditionStart = LeafNode<NodeKind::WhileConditionStart>;
|
||||
|
||||
// The condition portion of a `while` statement: `(expr)`.
|
||||
struct WhileCondition {
|
||||
static constexpr auto Kind = NodeKind::WhileCondition.Define();
|
||||
static constexpr auto Kind = NodeKind::WhileCondition.Define(
|
||||
{.bracketed_by = WhileConditionStart::Kind, .child_count = 2});
|
||||
|
||||
WhileConditionStartId left_paren;
|
||||
AnyExprId condition;
|
||||
@@ -523,7 +556,9 @@ struct WhileCondition {
|
||||
// A `while` statement: `while (expr) { ... }`.
|
||||
struct WhileStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::WhileStatement.Define(NodeCategory::Statement);
|
||||
NodeKind::WhileStatement.Define({.category = NodeCategory::Statement,
|
||||
.bracketed_by = WhileCondition::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
WhileConditionId head;
|
||||
CodeBlockId body;
|
||||
@@ -532,7 +567,8 @@ struct WhileStatement {
|
||||
using MatchConditionStart = LeafNode<NodeKind::MatchConditionStart>;
|
||||
|
||||
struct MatchCondition {
|
||||
static constexpr auto Kind = NodeKind::MatchCondition.Define();
|
||||
static constexpr auto Kind = NodeKind::MatchCondition.Define(
|
||||
{.bracketed_by = MatchConditionStart::Kind, .child_count = 2});
|
||||
|
||||
MatchConditionStartId left_paren;
|
||||
AnyExprId condition;
|
||||
@@ -540,7 +576,8 @@ struct MatchCondition {
|
||||
|
||||
using MatchIntroducer = LeafNode<NodeKind::MatchIntroducer>;
|
||||
struct MatchStatementStart {
|
||||
static constexpr auto Kind = NodeKind::MatchStatementStart.Define();
|
||||
static constexpr auto Kind = NodeKind::MatchStatementStart.Define(
|
||||
{.bracketed_by = MatchIntroducer::Kind, .child_count = 2});
|
||||
|
||||
MatchIntroducerId introducer;
|
||||
MatchConditionId left_brace;
|
||||
@@ -551,7 +588,9 @@ using MatchCaseGuardIntroducer = LeafNode<NodeKind::MatchCaseGuardIntroducer>;
|
||||
using MatchCaseGuardStart = LeafNode<NodeKind::MatchCaseGuardStart>;
|
||||
|
||||
struct MatchCaseGuard {
|
||||
static constexpr auto Kind = NodeKind::MatchCaseGuard.Define();
|
||||
static constexpr auto Kind = NodeKind::MatchCaseGuard.Define(
|
||||
{.bracketed_by = MatchCaseGuardIntroducer::Kind, .child_count = 3});
|
||||
|
||||
MatchCaseGuardIntroducerId introducer;
|
||||
MatchCaseGuardStartId left_paren;
|
||||
AnyExprId condition;
|
||||
@@ -560,7 +599,9 @@ struct MatchCaseGuard {
|
||||
using MatchCaseEqualGreater = LeafNode<NodeKind::MatchCaseEqualGreater>;
|
||||
|
||||
struct MatchCaseStart {
|
||||
static constexpr auto Kind = NodeKind::MatchCaseStart.Define();
|
||||
static constexpr auto Kind = NodeKind::MatchCaseStart.Define(
|
||||
{.bracketed_by = MatchCaseIntroducer::Kind});
|
||||
|
||||
MatchCaseIntroducerId introducer;
|
||||
AnyPatternId pattern;
|
||||
std::optional<MatchCaseGuardId> guard;
|
||||
@@ -568,7 +609,9 @@ struct MatchCaseStart {
|
||||
};
|
||||
|
||||
struct MatchCase {
|
||||
static constexpr auto Kind = NodeKind::MatchCase.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::MatchCase.Define({.bracketed_by = MatchCaseStart::Kind});
|
||||
|
||||
MatchCaseStartId head;
|
||||
llvm::SmallVector<AnyStatementId> statements;
|
||||
};
|
||||
@@ -577,13 +620,16 @@ using MatchDefaultIntroducer = LeafNode<NodeKind::MatchDefaultIntroducer>;
|
||||
using MatchDefaultEqualGreater = LeafNode<NodeKind::MatchDefaultEqualGreater>;
|
||||
|
||||
struct MatchDefaultStart {
|
||||
static constexpr auto Kind = NodeKind::MatchDefaultStart.Define();
|
||||
static constexpr auto Kind = NodeKind::MatchDefaultStart.Define(
|
||||
{.bracketed_by = MatchDefaultIntroducer::Kind, .child_count = 2});
|
||||
|
||||
MatchDefaultIntroducerId introducer;
|
||||
MatchDefaultEqualGreaterId equal_greater_token;
|
||||
};
|
||||
|
||||
struct MatchDefault {
|
||||
static constexpr auto Kind = NodeKind::MatchDefault.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::MatchDefault.Define({.bracketed_by = MatchDefaultStart::Kind});
|
||||
|
||||
MatchDefaultStartId introducer;
|
||||
llvm::SmallVector<AnyStatementId> statements;
|
||||
@@ -591,8 +637,9 @@ struct MatchDefault {
|
||||
|
||||
// A `match` statement: `match (expr) { case (...) => {...} default => {...}}`.
|
||||
struct MatchStatement {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::MatchStatement.Define(NodeCategory::Statement);
|
||||
static constexpr auto Kind = NodeKind::MatchStatement.Define(
|
||||
{.category = NodeCategory::Statement,
|
||||
.bracketed_by = MatchStatementStart::Kind});
|
||||
|
||||
MatchStatementStartId head;
|
||||
|
||||
@@ -609,7 +656,8 @@ using ArrayExprStart = LeafNode<NodeKind::ArrayExprStart>;
|
||||
//
|
||||
// TODO: Consider flattening this into `ArrayExpr`.
|
||||
struct ArrayExprSemi {
|
||||
static constexpr auto Kind = NodeKind::ArrayExprSemi.Define();
|
||||
static constexpr auto Kind = NodeKind::ArrayExprSemi.Define(
|
||||
{.bracketed_by = ArrayExprStart::Kind, .child_count = 2});
|
||||
|
||||
ArrayExprStartId left_square;
|
||||
AnyExprId type;
|
||||
@@ -617,7 +665,8 @@ struct ArrayExprSemi {
|
||||
|
||||
// An array type, such as `[i32; 3]` or `[i32;]`.
|
||||
struct ArrayExpr {
|
||||
static constexpr auto Kind = NodeKind::ArrayExpr.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::ArrayExpr.Define(
|
||||
{.category = NodeCategory::Expr, .bracketed_by = ArrayExprSemi::Kind});
|
||||
|
||||
ArrayExprSemiId start;
|
||||
std::optional<AnyExprId> bound;
|
||||
@@ -627,14 +676,18 @@ struct ArrayExpr {
|
||||
//
|
||||
// TODO: Consider flattening this into `IndexExpr`.
|
||||
struct IndexExprStart {
|
||||
static constexpr auto Kind = NodeKind::IndexExprStart.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::IndexExprStart.Define({.child_count = 1});
|
||||
|
||||
AnyExprId sequence;
|
||||
};
|
||||
|
||||
// An indexing expression, such as `a[1]`.
|
||||
struct IndexExpr {
|
||||
static constexpr auto Kind = NodeKind::IndexExpr.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind =
|
||||
NodeKind::IndexExpr.Define({.category = NodeCategory::Expr,
|
||||
.bracketed_by = IndexExprStart::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
IndexExprStartId start;
|
||||
AnyExprId index;
|
||||
@@ -644,8 +697,10 @@ using ParenExprStart = LeafNode<NodeKind::ParenExprStart>;
|
||||
|
||||
// A parenthesized expression: `(a)`.
|
||||
struct ParenExpr {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ParenExpr.Define(NodeCategory::Expr | NodeCategory::MemberExpr);
|
||||
static constexpr auto Kind = NodeKind::ParenExpr.Define(
|
||||
{.category = NodeCategory::Expr | NodeCategory::MemberExpr,
|
||||
.bracketed_by = ParenExprStart::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
ParenExprStartId start;
|
||||
AnyExprId expr;
|
||||
@@ -657,7 +712,8 @@ using TupleLiteralComma = LeafNode<NodeKind::TupleLiteralComma>;
|
||||
// A tuple literal: `()`, `(a, b, c)`, or `(a,)`.
|
||||
struct TupleLiteral {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::TupleLiteral.Define(NodeCategory::Expr);
|
||||
NodeKind::TupleLiteral.Define({.category = NodeCategory::Expr,
|
||||
.bracketed_by = TupleLiteralStart::Kind});
|
||||
|
||||
TupleLiteralStartId start;
|
||||
CommaSeparatedList<AnyExprId, TupleLiteralCommaId> elements;
|
||||
@@ -667,7 +723,8 @@ struct TupleLiteral {
|
||||
//
|
||||
// TODO: Consider flattening this into `CallExpr`.
|
||||
struct CallExprStart {
|
||||
static constexpr auto Kind = NodeKind::CallExprStart.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::CallExprStart.Define({.child_count = 1});
|
||||
|
||||
AnyExprId callee;
|
||||
};
|
||||
@@ -676,7 +733,8 @@ using CallExprComma = LeafNode<NodeKind::CallExprComma>;
|
||||
|
||||
// A call expression: `F(a, b, c)`.
|
||||
struct CallExpr {
|
||||
static constexpr auto Kind = NodeKind::CallExpr.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::CallExpr.Define(
|
||||
{.category = NodeCategory::Expr, .bracketed_by = CallExprStart::Kind});
|
||||
|
||||
CallExprStartId start;
|
||||
CommaSeparatedList<AnyExprId, CallExprCommaId> arguments;
|
||||
@@ -684,8 +742,8 @@ struct CallExpr {
|
||||
|
||||
// A member access expression: `a.b` or `a.(b)`.
|
||||
struct MemberAccessExpr {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::MemberAccessExpr.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::MemberAccessExpr.Define(
|
||||
{.category = NodeCategory::Expr, .child_count = 2});
|
||||
|
||||
AnyExprId lhs;
|
||||
AnyMemberNameOrMemberExprId rhs;
|
||||
@@ -693,8 +751,8 @@ struct MemberAccessExpr {
|
||||
|
||||
// An indirect member access expression: `a->b` or `a->(b)`.
|
||||
struct PointerMemberAccessExpr {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::PointerMemberAccessExpr.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::PointerMemberAccessExpr.Define(
|
||||
{.category = NodeCategory::Expr, .child_count = 2});
|
||||
|
||||
AnyExprId lhs;
|
||||
AnyMemberNameOrMemberExprId rhs;
|
||||
@@ -703,7 +761,8 @@ struct PointerMemberAccessExpr {
|
||||
// A prefix operator expression.
|
||||
template <const NodeKind& KindT>
|
||||
struct PrefixOperator {
|
||||
static constexpr auto Kind = KindT.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind =
|
||||
KindT.Define({.category = NodeCategory::Expr, .child_count = 1});
|
||||
|
||||
AnyExprId operand;
|
||||
};
|
||||
@@ -711,7 +770,8 @@ struct PrefixOperator {
|
||||
// An infix operator expression.
|
||||
template <const NodeKind& KindT>
|
||||
struct InfixOperator {
|
||||
static constexpr auto Kind = KindT.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind =
|
||||
KindT.Define({.category = NodeCategory::Expr, .child_count = 2});
|
||||
|
||||
AnyExprId lhs;
|
||||
AnyExprId rhs;
|
||||
@@ -720,7 +780,8 @@ struct InfixOperator {
|
||||
// A postfix operator expression.
|
||||
template <const NodeKind& KindT>
|
||||
struct PostfixOperator {
|
||||
static constexpr auto Kind = KindT.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind =
|
||||
KindT.Define({.category = NodeCategory::Expr, .child_count = 1});
|
||||
|
||||
AnyExprId operand;
|
||||
};
|
||||
@@ -748,28 +809,34 @@ struct PostfixOperator {
|
||||
// TODO: Make this be a template if we ever need to write generic code to cover
|
||||
// both cases at once, say in check.
|
||||
struct ShortCircuitOperandAnd {
|
||||
static constexpr auto Kind = NodeKind::ShortCircuitOperandAnd.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ShortCircuitOperandAnd.Define({.child_count = 1});
|
||||
|
||||
AnyExprId operand;
|
||||
};
|
||||
|
||||
struct ShortCircuitOperandOr {
|
||||
static constexpr auto Kind = NodeKind::ShortCircuitOperandOr.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ShortCircuitOperandOr.Define({.child_count = 1});
|
||||
|
||||
AnyExprId operand;
|
||||
};
|
||||
|
||||
struct ShortCircuitOperatorAnd {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ShortCircuitOperatorAnd.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::ShortCircuitOperatorAnd.Define(
|
||||
{.category = NodeCategory::Expr,
|
||||
.bracketed_by = ShortCircuitOperandAnd::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
ShortCircuitOperandAndId lhs;
|
||||
AnyExprId rhs;
|
||||
};
|
||||
|
||||
struct ShortCircuitOperatorOr {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ShortCircuitOperatorOr.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::ShortCircuitOperatorOr.Define(
|
||||
{.category = NodeCategory::Expr,
|
||||
.bracketed_by = ShortCircuitOperandOr::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
ShortCircuitOperandOrId lhs;
|
||||
AnyExprId rhs;
|
||||
@@ -777,21 +844,24 @@ struct ShortCircuitOperatorOr {
|
||||
|
||||
// The `if` portion of an `if` expression: `if expr`.
|
||||
struct IfExprIf {
|
||||
static constexpr auto Kind = NodeKind::IfExprIf.Define();
|
||||
static constexpr auto Kind = NodeKind::IfExprIf.Define({.child_count = 1});
|
||||
|
||||
AnyExprId condition;
|
||||
};
|
||||
|
||||
// The `then` portion of an `if` expression: `then expr`.
|
||||
struct IfExprThen {
|
||||
static constexpr auto Kind = NodeKind::IfExprThen.Define();
|
||||
static constexpr auto Kind = NodeKind::IfExprThen.Define({.child_count = 1});
|
||||
|
||||
AnyExprId result;
|
||||
};
|
||||
|
||||
// A full `if` expression: `if expr then expr else expr`.
|
||||
struct IfExprElse {
|
||||
static constexpr auto Kind = NodeKind::IfExprElse.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind =
|
||||
NodeKind::IfExprElse.Define({.category = NodeCategory::Expr,
|
||||
.bracketed_by = IfExprIf::Kind,
|
||||
.child_count = 3});
|
||||
|
||||
IfExprIfId start;
|
||||
IfExprThenId then;
|
||||
@@ -804,8 +874,8 @@ struct IfExprElse {
|
||||
using ChoiceIntroducer = LeafNode<NodeKind::ChoiceIntroducer>;
|
||||
|
||||
struct ChoiceSignature {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ChoiceDefinitionStart.Define(NodeCategory::None);
|
||||
static constexpr auto Kind = NodeKind::ChoiceDefinitionStart.Define(
|
||||
{.category = NodeCategory::None, .bracketed_by = ChoiceIntroducer::Kind});
|
||||
|
||||
ChoiceIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -818,8 +888,9 @@ using ChoiceAlternativeListComma =
|
||||
LeafNode<NodeKind::ChoiceAlternativeListComma>;
|
||||
|
||||
struct ChoiceDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ChoiceDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::ChoiceDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = ChoiceDefinitionStart::Kind});
|
||||
|
||||
ChoiceDefinitionStartId signature;
|
||||
struct Alternative {
|
||||
@@ -840,14 +911,16 @@ using StructComma = LeafNode<NodeKind::StructComma>;
|
||||
|
||||
// `.a`
|
||||
struct StructFieldDesignator {
|
||||
static constexpr auto Kind = NodeKind::StructFieldDesignator.Define();
|
||||
static constexpr auto Kind =
|
||||
NodeKind::StructFieldDesignator.Define({.child_count = 1});
|
||||
|
||||
NodeIdOneOf<IdentifierName, BaseName> name;
|
||||
};
|
||||
|
||||
// `.a = 0`
|
||||
struct StructField {
|
||||
static constexpr auto Kind = NodeKind::StructField.Define();
|
||||
static constexpr auto Kind = NodeKind::StructField.Define(
|
||||
{.bracketed_by = StructFieldDesignator::Kind, .child_count = 2});
|
||||
|
||||
StructFieldDesignatorId designator;
|
||||
AnyExprId expr;
|
||||
@@ -855,7 +928,8 @@ struct StructField {
|
||||
|
||||
// `.a: i32`
|
||||
struct StructTypeField {
|
||||
static constexpr auto Kind = NodeKind::StructTypeField.Define();
|
||||
static constexpr auto Kind = NodeKind::StructTypeField.Define(
|
||||
{.bracketed_by = StructFieldDesignator::Kind, .child_count = 2});
|
||||
|
||||
StructFieldDesignatorId designator;
|
||||
AnyExprId type_expr;
|
||||
@@ -863,8 +937,9 @@ struct StructTypeField {
|
||||
|
||||
// Struct literals, such as `{.a = 0}`.
|
||||
struct StructLiteral {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::StructLiteral.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::StructLiteral.Define(
|
||||
{.category = NodeCategory::Expr,
|
||||
.bracketed_by = StructLiteralStart::Kind});
|
||||
|
||||
StructLiteralStartId start;
|
||||
CommaSeparatedList<StructFieldId, StructCommaId> fields;
|
||||
@@ -872,8 +947,9 @@ struct StructLiteral {
|
||||
|
||||
// Struct type literals, such as `{.a: i32}`.
|
||||
struct StructTypeLiteral {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::StructTypeLiteral.Define(NodeCategory::Expr);
|
||||
static constexpr auto Kind = NodeKind::StructTypeLiteral.Define(
|
||||
{.category = NodeCategory::Expr,
|
||||
.bracketed_by = StructTypeLiteralStart::Kind});
|
||||
|
||||
StructTypeLiteralStartId start;
|
||||
CommaSeparatedList<StructTypeFieldId, StructCommaId> fields;
|
||||
@@ -888,7 +964,8 @@ using ClassIntroducer = LeafNode<NodeKind::ClassIntroducer>;
|
||||
// A class signature `class C`
|
||||
template <const NodeKind& KindT, NodeCategory Category>
|
||||
struct ClassSignature {
|
||||
static constexpr auto Kind = KindT.Define(Category);
|
||||
static constexpr auto Kind = KindT.Define(
|
||||
{.category = Category, .bracketed_by = ClassIntroducer::Kind});
|
||||
|
||||
ClassIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -903,8 +980,9 @@ using ClassDefinitionStart =
|
||||
|
||||
// `class C { ... }`
|
||||
struct ClassDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ClassDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::ClassDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = ClassDefinitionStart::Kind});
|
||||
|
||||
ClassDefinitionStartId signature;
|
||||
llvm::SmallVector<AnyDeclId> members;
|
||||
@@ -917,7 +995,8 @@ struct ClassDefinition {
|
||||
using AdaptIntroducer = LeafNode<NodeKind::AdaptIntroducer>;
|
||||
// `adapt SomeType;`
|
||||
struct AdaptDecl {
|
||||
static constexpr auto Kind = NodeKind::AdaptDecl.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::AdaptDecl.Define(
|
||||
{.category = NodeCategory::Decl, .bracketed_by = AdaptIntroducer::Kind});
|
||||
|
||||
AdaptIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -932,7 +1011,8 @@ using BaseIntroducer = LeafNode<NodeKind::BaseIntroducer>;
|
||||
using BaseColon = LeafNode<NodeKind::BaseColon>;
|
||||
// `extend base: BaseClass;`
|
||||
struct BaseDecl {
|
||||
static constexpr auto Kind = NodeKind::BaseDecl.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::BaseDecl.Define(
|
||||
{.category = NodeCategory::Decl, .bracketed_by = BaseIntroducer::Kind});
|
||||
|
||||
BaseIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -949,7 +1029,8 @@ using InterfaceIntroducer = LeafNode<NodeKind::InterfaceIntroducer>;
|
||||
// `interface I`
|
||||
template <const NodeKind& KindT, NodeCategory Category>
|
||||
struct InterfaceSignature {
|
||||
static constexpr auto Kind = KindT.Define(Category);
|
||||
static constexpr auto Kind = KindT.Define(
|
||||
{.category = Category, .bracketed_by = InterfaceIntroducer::Kind});
|
||||
|
||||
InterfaceIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -965,8 +1046,9 @@ using InterfaceDefinitionStart =
|
||||
|
||||
// `interface I { ... }`
|
||||
struct InterfaceDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::InterfaceDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::InterfaceDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = InterfaceDefinitionStart::Kind});
|
||||
|
||||
InterfaceDefinitionStartId signature;
|
||||
llvm::SmallVector<AnyDeclId> members;
|
||||
@@ -980,7 +1062,7 @@ using ImplIntroducer = LeafNode<NodeKind::ImplIntroducer>;
|
||||
|
||||
// `forall [...]`
|
||||
struct ImplForall {
|
||||
static constexpr auto Kind = NodeKind::ImplForall.Define();
|
||||
static constexpr auto Kind = NodeKind::ImplForall.Define({.child_count = 1});
|
||||
|
||||
ImplicitParamListId params;
|
||||
};
|
||||
@@ -991,8 +1073,8 @@ using DefaultSelfImplAs =
|
||||
|
||||
// `<type> as`
|
||||
struct TypeImplAs {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::TypeImplAs.Define(NodeCategory::ImplAs);
|
||||
static constexpr auto Kind = NodeKind::TypeImplAs.Define(
|
||||
{.category = NodeCategory::ImplAs, .child_count = 1});
|
||||
|
||||
AnyExprId type_expr;
|
||||
};
|
||||
@@ -1000,7 +1082,8 @@ struct TypeImplAs {
|
||||
// `impl T as I`
|
||||
template <const NodeKind& KindT, NodeCategory Category>
|
||||
struct ImplSignature {
|
||||
static constexpr auto Kind = KindT.Define(Category);
|
||||
static constexpr auto Kind = KindT.Define(
|
||||
{.category = Category, .bracketed_by = ImplIntroducer::Kind});
|
||||
|
||||
ImplIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -1017,8 +1100,9 @@ using ImplDefinitionStart =
|
||||
|
||||
// `impl T as I { ... }`
|
||||
struct ImplDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::ImplDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::ImplDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = ImplDefinitionStart::Kind});
|
||||
|
||||
ImplDefinitionStartId signature;
|
||||
llvm::SmallVector<AnyDeclId> members;
|
||||
@@ -1033,7 +1117,8 @@ using NamedConstraintIntroducer = LeafNode<NodeKind::NamedConstraintIntroducer>;
|
||||
// `constraint NC`
|
||||
template <const NodeKind& KindT, NodeCategory Category>
|
||||
struct NamedConstraintSignature {
|
||||
static constexpr auto Kind = KindT.Define(Category);
|
||||
static constexpr auto Kind = KindT.Define(
|
||||
{.category = Category, .bracketed_by = NamedConstraintIntroducer::Kind});
|
||||
|
||||
NamedConstraintIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
@@ -1050,8 +1135,9 @@ using NamedConstraintDefinitionStart =
|
||||
|
||||
// `constraint NC { ... }`
|
||||
struct NamedConstraintDefinition {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::NamedConstraintDefinition.Define(NodeCategory::Decl);
|
||||
static constexpr auto Kind = NodeKind::NamedConstraintDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = NamedConstraintDefinitionStart::Kind});
|
||||
|
||||
NamedConstraintDefinitionStartId signature;
|
||||
llvm::SmallVector<AnyDeclId> members;
|
||||
|
||||
Reference in New Issue
Block a user