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:
Richard Smith
2024-05-29 20:57:51 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins Carbon Infra Bot
parent 512583d744
commit 419d2e39d8
5 changed files with 475 additions and 385 deletions
+16 -40
View File
@@ -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
View File
@@ -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
View File
@@ -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`
+11
View File
@@ -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
View File
@@ -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;