diff --git a/packages/cxx-frontend/src/AST.ts b/packages/cxx-frontend/src/AST.ts index 06981b32..439e0f67 100644 --- a/packages/cxx-frontend/src/AST.ts +++ b/packages/cxx-frontend/src/AST.ts @@ -7974,6 +7974,58 @@ export class AssignmentExpressionAST extends ExpressionAST { } } +/** + * CompoundAssignmentExpressionAST node. + */ +export class CompoundAssignmentExpressionAST extends ExpressionAST { + /** + * Traverse this node using the given visitor. + * @param visitor the visitor. + * @param context the context. + * @returns the result of the visit. + */ + accept( + visitor: ASTVisitor, + context: Context, + ): Result { + return visitor.visitCompoundAssignmentExpression(this, context); + } + + /** + * Returns the leftExpression of this node + */ + getLeftExpression(): ExpressionAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 0), + this.parser, + ); + } + + /** + * Returns the location of the op token in this node + */ + getOpToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 1), this.parser); + } + + /** + * Returns the rightExpression of this node + */ + getRightExpression(): ExpressionAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 2), + this.parser, + ); + } + + /** + * Returns the op attribute of this node + */ + getOp(): TokenKind { + return cxx.getASTSlot(this.getHandle(), 3); + } +} + /** * PackExpansionExpressionAST node. */ @@ -13376,6 +13428,7 @@ const AST_CONSTRUCTORS: Array< YieldExpressionAST, ThrowExpressionAST, AssignmentExpressionAST, + CompoundAssignmentExpressionAST, PackExpansionExpressionAST, DesignatedInitializerClauseAST, TypeTraitExpressionAST, diff --git a/packages/cxx-frontend/src/ASTKind.ts b/packages/cxx-frontend/src/ASTKind.ts index 79ec2479..fe58d81b 100644 --- a/packages/cxx-frontend/src/ASTKind.ts +++ b/packages/cxx-frontend/src/ASTKind.ts @@ -159,6 +159,7 @@ export enum ASTKind { YieldExpression, ThrowExpression, AssignmentExpression, + CompoundAssignmentExpression, PackExpansionExpression, DesignatedInitializerClause, TypeTraitExpression, diff --git a/packages/cxx-frontend/src/ASTVisitor.ts b/packages/cxx-frontend/src/ASTVisitor.ts index 377cce14..64edbecc 100644 --- a/packages/cxx-frontend/src/ASTVisitor.ts +++ b/packages/cxx-frontend/src/ASTVisitor.ts @@ -1550,6 +1550,18 @@ export abstract class ASTVisitor { context: Context, ): Result; + /** + * Visit CompoundAssignmentExpression node. + * + * @param node The node to visit. + * @param context The context. + * @returns The result of the visit. + */ + abstract visitCompoundAssignmentExpression( + node: ast.CompoundAssignmentExpressionAST, + context: Context, + ): Result; + /** * Visit PackExpansionExpression node. * diff --git a/packages/cxx-frontend/src/RecursiveASTVisitor.ts b/packages/cxx-frontend/src/RecursiveASTVisitor.ts index f702158b..a54793d6 100644 --- a/packages/cxx-frontend/src/RecursiveASTVisitor.ts +++ b/packages/cxx-frontend/src/RecursiveASTVisitor.ts @@ -1721,6 +1721,20 @@ export class RecursiveASTVisitor extends ASTVisitor { this.accept(node.getRightExpression(), context); } + /** + * Visit a CompoundAssignmentExpression node. + * + * @param node The node to visit. + * @param context The context. + */ + visitCompoundAssignmentExpression( + node: ast.CompoundAssignmentExpressionAST, + context: Context, + ): void { + this.accept(node.getLeftExpression(), context); + this.accept(node.getRightExpression(), context); + } + /** * Visit a PackExpansionExpression node. * diff --git a/packages/cxx-gen-ast/src/gen_token_fwd_h.ts b/packages/cxx-gen-ast/src/gen_token_fwd_h.ts index 2fb16a95..2ea50f9a 100644 --- a/packages/cxx-gen-ast/src/gen_token_fwd_h.ts +++ b/packages/cxx-gen-ast/src/gen_token_fwd_h.ts @@ -62,6 +62,7 @@ ${cpy_header} #pragma once #include +#include #include namespace cxx { @@ -93,6 +94,33 @@ enum class BuiltinTypeTraitKind { #undef TOKEN_ALIAS_ENUM // clang-format on +[[nodiscard]] inline auto get_underlying_binary_op(TokenKind op) -> TokenKind { + switch (op) { + case TokenKind::T_STAR_EQUAL: + return TokenKind::T_STAR; + case TokenKind::T_SLASH_EQUAL: + return TokenKind::T_SLASH; + case TokenKind::T_PERCENT_EQUAL: + return TokenKind::T_PERCENT; + case TokenKind::T_PLUS_EQUAL: + return TokenKind::T_PLUS; + case TokenKind::T_MINUS_EQUAL: + return TokenKind::T_MINUS; + case TokenKind::T_LESS_LESS_EQUAL: + return TokenKind::T_LESS_LESS; + case TokenKind::T_AMP_EQUAL: + return TokenKind::T_AMP; + case TokenKind::T_CARET_EQUAL: + return TokenKind::T_CARET; + case TokenKind::T_BAR_EQUAL: + return TokenKind::T_BAR; + case TokenKind::T_GREATER_GREATER_EQUAL: + return TokenKind::T_GREATER_GREATER; + default: + return TokenKind::T_EOF_SYMBOL; + } // switch +} + } // namespace cxx `; diff --git a/src/mlir/cxx/mlir/codegen_declarations.cc b/src/mlir/cxx/mlir/codegen_declarations.cc index 9ed2a670..faee4375 100644 --- a/src/mlir/cxx/mlir/codegen_declarations.cc +++ b/src/mlir/cxx/mlir/codegen_declarations.cc @@ -363,8 +363,6 @@ auto Codegen::DeclarationVisitor::operator()(FunctionDefinitionAST* ast) auto exitValueType = gen.convertType(returnType); auto ptrType = gen.builder_.getType(exitValueType); exitValue = gen.builder_.create(exitValueLoc, ptrType); - - exitBlock->addArgument(ptrType, exitValueLoc); } // restore state diff --git a/src/mlir/cxx/mlir/codegen_expressions.cc b/src/mlir/cxx/mlir/codegen_expressions.cc index 4b49b1da..75aaf1ea 100644 --- a/src/mlir/cxx/mlir/codegen_expressions.cc +++ b/src/mlir/cxx/mlir/codegen_expressions.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace cxx { @@ -89,6 +90,7 @@ struct Codegen::ExpressionVisitor { auto operator()(YieldExpressionAST* ast) -> ExpressionResult; auto operator()(ThrowExpressionAST* ast) -> ExpressionResult; auto operator()(AssignmentExpressionAST* ast) -> ExpressionResult; + auto operator()(CompoundAssignmentExpressionAST* ast) -> ExpressionResult; auto operator()(PackExpansionExpressionAST* ast) -> ExpressionResult; auto operator()(DesignatedInitializerClauseAST* ast) -> ExpressionResult; auto operator()(TypeTraitExpressionAST* ast) -> ExpressionResult; @@ -809,6 +811,13 @@ auto Codegen::ExpressionVisitor::operator()(ImplicitCastExpressionAST* ast) auto Codegen::ExpressionVisitor::operator()(BinaryExpressionAST* ast) -> ExpressionResult { + if (ast->op == TokenKind::T_COMMA) { + // For the comma operator, we evaluate the left expression for its side + // effects and then return the right expression as the result. + (void)gen.expression(ast->leftExpression, ExpressionFormat::kSideEffect); + return gen.expression(ast->rightExpression, format); + } + auto op = gen.emitTodoExpr(ast->firstSourceLocation(), to_string(ast->kind())); @@ -872,9 +881,7 @@ auto Codegen::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) auto rightExpressionResult = gen.expression(ast->rightExpression); // Generate a store operation - auto loc = gen.getLocation(ast->opLoc); - - auto resultType = gen.convertType(ast->leftExpression->type); + const auto loc = gen.getLocation(ast->opLoc); gen.builder_.create(loc, rightExpressionResult.value, leftExpressionResult.value); @@ -883,6 +890,18 @@ auto Codegen::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) return {}; } + if (gen.unit_->language() == LanguageKind::kC) { + // in C mode the result of the assignment is an rvalue + auto resultLoc = gen.getLocation(ast->firstSourceLocation()); + auto resultType = gen.convertType(ast->leftExpression->type); + + // generate a load + auto op = gen.builder_.create( + resultLoc, resultType, leftExpressionResult.value); + + return {op}; + } + return leftExpressionResult; } @@ -897,6 +916,19 @@ auto Codegen::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) return {op}; } +auto Codegen::ExpressionVisitor::operator()( + CompoundAssignmentExpressionAST* ast) -> ExpressionResult { + auto op = + gen.emitTodoExpr(ast->firstSourceLocation(), to_string(ast->kind())); + +#if false + auto leftExpressionResult = gen.expression(ast->leftExpression); + auto rightExpressionResult = gen.expression(ast->rightExpression); +#endif + + return {op}; +} + auto Codegen::ExpressionVisitor::operator()(PackExpansionExpressionAST* ast) -> ExpressionResult { auto op = diff --git a/src/mlir/cxx/mlir/codegen_statements.cc b/src/mlir/cxx/mlir/codegen_statements.cc index 0f192390..79944777 100644 --- a/src/mlir/cxx/mlir/codegen_statements.cc +++ b/src/mlir/cxx/mlir/codegen_statements.cc @@ -195,26 +195,16 @@ void Codegen::StatementVisitor::operator()(ContinueStatementAST* ast) { } void Codegen::StatementVisitor::operator()(ReturnStatementAST* ast) { - // (void)gen.emitTodoStmt(ast->firstSourceLocation(), to_string(ast->kind())); - auto value = gen.expression(ast->expression); -#if false - auto expressionResult = gen.expression(ast->expression); -#endif - auto loc = gen.getLocation(ast->firstSourceLocation()); - mlir::SmallVector results; - if (gen.exitValue_) { gen.builder_.create(loc, value.value, gen.exitValue_.getResult()); - - results.push_back(gen.exitValue_); } - gen.builder_.create(loc, results, gen.exitBlock_); + gen.builder_.create(loc, gen.exitBlock_); } void Codegen::StatementVisitor::operator()(CoroutineReturnStatementAST* ast) { diff --git a/src/parser/cxx/ast.cc b/src/parser/cxx/ast.cc index c16f6a36..94a69993 100644 --- a/src/parser/cxx/ast.cc +++ b/src/parser/cxx/ast.cc @@ -559,6 +559,376 @@ auto AsmGotoLabelAST::lastSourceLocation() -> SourceLocation { return {}; } +auto SplicerAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(secondColonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; + return {}; +} + +auto SplicerAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(secondColonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; + return {}; +} + +auto GlobalModuleFragmentAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(moduleLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(declarationList)) return loc; + return {}; +} + +auto GlobalModuleFragmentAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(declarationList)) return loc; + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(moduleLoc)) return loc; + return {}; +} + +auto PrivateModuleFragmentAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(moduleLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(privateLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(declarationList)) return loc; + return {}; +} + +auto PrivateModuleFragmentAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(declarationList)) return loc; + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(privateLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(moduleLoc)) return loc; + return {}; +} + +auto ModuleDeclarationAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(exportLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(moduleLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(moduleName)) return loc; + if (auto loc = cxx::firstSourceLocation(modulePartition)) return loc; + if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; + return {}; +} + +auto ModuleDeclarationAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; + if (auto loc = cxx::lastSourceLocation(modulePartition)) return loc; + if (auto loc = cxx::lastSourceLocation(moduleName)) return loc; + if (auto loc = cxx::lastSourceLocation(moduleLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(exportLoc)) return loc; + return {}; +} + +auto ModuleNameAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(moduleQualifier)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + return {}; +} + +auto ModuleNameAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(moduleQualifier)) return loc; + return {}; +} + +auto ModuleQualifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(moduleQualifier)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(dotLoc)) return loc; + return {}; +} + +auto ModuleQualifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(dotLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(moduleQualifier)) return loc; + return {}; +} + +auto ModulePartitionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(moduleName)) return loc; + return {}; +} + +auto ModulePartitionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(moduleName)) return loc; + if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; + return {}; +} + +auto ImportNameAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(headerLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(modulePartition)) return loc; + if (auto loc = cxx::firstSourceLocation(moduleName)) return loc; + return {}; +} + +auto ImportNameAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(moduleName)) return loc; + if (auto loc = cxx::lastSourceLocation(modulePartition)) return loc; + if (auto loc = cxx::lastSourceLocation(headerLoc)) return loc; + return {}; +} + +auto InitDeclaratorAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(declarator)) return loc; + if (auto loc = cxx::firstSourceLocation(requiresClause)) return loc; + if (auto loc = cxx::firstSourceLocation(initializer)) return loc; + return {}; +} + +auto InitDeclaratorAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(initializer)) return loc; + if (auto loc = cxx::lastSourceLocation(requiresClause)) return loc; + if (auto loc = cxx::lastSourceLocation(declarator)) return loc; + return {}; +} + +auto DeclaratorAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(ptrOpList)) return loc; + if (auto loc = cxx::firstSourceLocation(coreDeclarator)) return loc; + if (auto loc = cxx::firstSourceLocation(declaratorChunkList)) return loc; + return {}; +} + +auto DeclaratorAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(declaratorChunkList)) return loc; + if (auto loc = cxx::lastSourceLocation(coreDeclarator)) return loc; + if (auto loc = cxx::lastSourceLocation(ptrOpList)) return loc; + return {}; +} + +auto UsingDeclaratorAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typenameLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + return {}; +} + +auto UsingDeclaratorAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::lastSourceLocation(typenameLoc)) return loc; + return {}; +} + +auto EnumeratorAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; + if (auto loc = cxx::firstSourceLocation(equalLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + return {}; +} + +auto EnumeratorAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(equalLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + return {}; +} + +auto TypeIdAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeSpecifierList)) return loc; + if (auto loc = cxx::firstSourceLocation(declarator)) return loc; + return {}; +} + +auto TypeIdAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(declarator)) return loc; + if (auto loc = cxx::lastSourceLocation(typeSpecifierList)) return loc; + return {}; +} + +auto HandlerAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(catchLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(exceptionDeclaration)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(statement)) return loc; + return {}; +} + +auto HandlerAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(statement)) return loc; + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(exceptionDeclaration)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(catchLoc)) return loc; + return {}; +} + +auto BaseSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; + if (auto loc = cxx::firstSourceLocation(virtualOrAccessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(otherVirtualOrAccessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + return {}; +} + +auto BaseSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; + if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::lastSourceLocation(otherVirtualOrAccessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(virtualOrAccessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; + return {}; +} + +auto RequiresClauseAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(requiresLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + return {}; +} + +auto RequiresClauseAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(requiresLoc)) return loc; + return {}; +} + +auto ParameterDeclarationClauseAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(parameterDeclarationList)) return loc; + if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + return {}; +} + +auto ParameterDeclarationClauseAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(parameterDeclarationList)) return loc; + return {}; +} + +auto TrailingReturnTypeAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(minusGreaterLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + return {}; +} + +auto TrailingReturnTypeAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(minusGreaterLoc)) return loc; + return {}; +} + +auto LambdaSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(specifierLoc)) return loc; + return {}; +} + +auto LambdaSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(specifierLoc)) return loc; + return {}; +} + +auto TypeConstraintAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(templateArgumentList)) return loc; + if (auto loc = cxx::firstSourceLocation(greaterLoc)) return loc; + return {}; +} + +auto TypeConstraintAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(greaterLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(templateArgumentList)) return loc; + if (auto loc = cxx::lastSourceLocation(lessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + return {}; +} + +auto AttributeArgumentClauseAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + return {}; +} + +auto AttributeArgumentClauseAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + return {}; +} + +auto AttributeAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(attributeToken)) return loc; + if (auto loc = cxx::firstSourceLocation(attributeArgumentClause)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + return {}; +} + +auto AttributeAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeArgumentClause)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeToken)) return loc; + return {}; +} + +auto AttributeUsingPrefixAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(usingLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(attributeNamespaceLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; + return {}; +} + +auto AttributeUsingPrefixAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeNamespaceLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(usingLoc)) return loc; + return {}; +} + +auto NewPlacementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + return {}; +} + +auto NewPlacementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + return {}; +} + +auto NestedNamespaceSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(inlineLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + return {}; +} + +auto NestedNamespaceSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(inlineLoc)) return loc; + return {}; +} + auto LabeledStatementAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; @@ -761,1473 +1131,1117 @@ auto ForStatementAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(statement)) return loc; - return {}; -} - -auto ForStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(statement)) return loc; - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(condition)) return loc; - if (auto loc = cxx::lastSourceLocation(initializer)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(forLoc)) return loc; - return {}; -} - -auto BreakStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(breakLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - return {}; -} - -auto BreakStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(breakLoc)) return loc; - return {}; -} - -auto ContinueStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(continueLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - return {}; -} - -auto ContinueStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(continueLoc)) return loc; - return {}; -} - -auto ReturnStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(returnLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - return {}; -} - -auto ReturnStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(returnLoc)) return loc; - return {}; -} - -auto CoroutineReturnStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(coreturnLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - return {}; -} - -auto CoroutineReturnStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(coreturnLoc)) return loc; - return {}; -} - -auto GotoStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(gotoLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(starLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - return {}; -} - -auto GotoStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(starLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(gotoLoc)) return loc; - return {}; -} - -auto DeclarationStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(declaration)) return loc; - return {}; -} - -auto DeclarationStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(declaration)) return loc; - return {}; -} - -auto TryBlockStatementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(tryLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(statement)) return loc; - if (auto loc = cxx::firstSourceLocation(handlerList)) return loc; - return {}; -} - -auto TryBlockStatementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(handlerList)) return loc; - if (auto loc = cxx::lastSourceLocation(statement)) return loc; - if (auto loc = cxx::lastSourceLocation(tryLoc)) return loc; - return {}; -} - -auto GeneratedLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto GeneratedLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto CharLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto CharLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto BoolLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto BoolLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto IntLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto IntLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto FloatLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto FloatLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto NullptrLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto NullptrLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto StringLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto StringLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto UserDefinedStringLiteralExpressionAST::firstSourceLocation() - -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; - return {}; -} - -auto UserDefinedStringLiteralExpressionAST::lastSourceLocation() - -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; - return {}; -} - -auto ObjectLiteralExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(bracedInitList)) return loc; - return {}; -} - -auto ObjectLiteralExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(bracedInitList)) return loc; - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - return {}; -} - -auto ThisExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(thisLoc)) return loc; - return {}; -} - -auto ThisExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(thisLoc)) return loc; - return {}; -} - -auto GenericSelectionExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(genericLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(genericAssociationList)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - return {}; -} - -auto GenericSelectionExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(genericAssociationList)) return loc; - if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(genericLoc)) return loc; - return {}; -} - -auto NestedStatementExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(statement)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - return {}; -} - -auto NestedStatementExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(statement)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - return {}; -} - -auto NestedExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(statement)) return loc; return {}; } -auto NestedExpressionAST::lastSourceLocation() -> SourceLocation { +auto ForStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(statement)) return loc; if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(condition)) return loc; + if (auto loc = cxx::lastSourceLocation(initializer)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(forLoc)) return loc; return {}; } -auto IdExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; +auto BreakStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(breakLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; return {}; } -auto IdExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; - if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; +auto BreakStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(breakLoc)) return loc; return {}; } -auto LambdaExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(captureDefaultLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(captureList)) return loc; - if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(templateParameterList)) return loc; - if (auto loc = cxx::firstSourceLocation(greaterLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(templateRequiresClause)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(parameterDeclarationClause)) - return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(gnuAtributeList)) return loc; - if (auto loc = cxx::firstSourceLocation(lambdaSpecifierList)) return loc; - if (auto loc = cxx::firstSourceLocation(exceptionSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; - if (auto loc = cxx::firstSourceLocation(trailingReturnType)) return loc; - if (auto loc = cxx::firstSourceLocation(requiresClause)) return loc; - if (auto loc = cxx::firstSourceLocation(statement)) return loc; +auto ContinueStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(continueLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; return {}; } -auto LambdaExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(statement)) return loc; - if (auto loc = cxx::lastSourceLocation(requiresClause)) return loc; - if (auto loc = cxx::lastSourceLocation(trailingReturnType)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; - if (auto loc = cxx::lastSourceLocation(exceptionSpecifier)) return loc; - if (auto loc = cxx::lastSourceLocation(lambdaSpecifierList)) return loc; - if (auto loc = cxx::lastSourceLocation(gnuAtributeList)) return loc; - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(parameterDeclarationClause)) - return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(templateRequiresClause)) return loc; - if (auto loc = cxx::lastSourceLocation(greaterLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(templateParameterList)) return loc; - if (auto loc = cxx::lastSourceLocation(lessLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(captureList)) return loc; - if (auto loc = cxx::lastSourceLocation(captureDefaultLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; +auto ContinueStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(continueLoc)) return loc; return {}; } -auto FoldExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(foldOpLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto ReturnStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(returnLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; return {}; } -auto FoldExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(foldOpLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; +auto ReturnStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(returnLoc)) return loc; return {}; } -auto RightFoldExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; +auto CoroutineReturnStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(coreturnLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; return {}; } -auto RightFoldExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; +auto CoroutineReturnStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(coreturnLoc)) return loc; return {}; } -auto LeftFoldExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto GotoStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(gotoLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(starLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; return {}; } -auto LeftFoldExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; +auto GotoStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(starLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(gotoLoc)) return loc; return {}; } -auto RequiresExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(requiresLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(parameterDeclarationClause)) - return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lbraceLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(requirementList)) return loc; - if (auto loc = cxx::firstSourceLocation(rbraceLoc)) return loc; +auto DeclarationStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(declaration)) return loc; return {}; } -auto RequiresExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rbraceLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(requirementList)) return loc; - if (auto loc = cxx::lastSourceLocation(lbraceLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(parameterDeclarationClause)) - return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(requiresLoc)) return loc; +auto DeclarationStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(declaration)) return loc; return {}; } -auto VaArgExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(vaArgLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto TryBlockStatementAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(tryLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(statement)) return loc; + if (auto loc = cxx::firstSourceLocation(handlerList)) return loc; return {}; } -auto VaArgExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(vaArgLoc)) return loc; +auto TryBlockStatementAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(handlerList)) return loc; + if (auto loc = cxx::lastSourceLocation(statement)) return loc; + if (auto loc = cxx::lastSourceLocation(tryLoc)) return loc; return {}; } -auto SubscriptExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(indexExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; +auto GeneratedLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto SubscriptExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(indexExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; +auto GeneratedLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto CallExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto CharLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto CallExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; +auto CharLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto TypeConstructionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typeSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto BoolLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto TypeConstructionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeSpecifier)) return loc; +auto BoolLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto BracedTypeConstructionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typeSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(bracedInitList)) return loc; +auto IntLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto BracedTypeConstructionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(bracedInitList)) return loc; - if (auto loc = cxx::lastSourceLocation(typeSpecifier)) return loc; +auto IntLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto SpliceMemberExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(accessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(splicer)) return loc; +auto FloatLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto SpliceMemberExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(splicer)) return loc; - if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(accessLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; +auto FloatLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto MemberExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(accessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; +auto NullptrLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto MemberExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; - if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::lastSourceLocation(accessLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; +auto NullptrLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto PostIncrExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; +auto StringLiteralExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto PostIncrExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; +auto StringLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto CppCastExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(castLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(greaterLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto UserDefinedStringLiteralExpressionAST::firstSourceLocation() + -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(literalLoc)) return loc; return {}; } -auto CppCastExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(greaterLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(lessLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(castLoc)) return loc; +auto UserDefinedStringLiteralExpressionAST::lastSourceLocation() + -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(literalLoc)) return loc; return {}; } -auto BuiltinBitCastExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(castLoc)) return loc; +auto ObjectLiteralExpressionAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(bracedInitList)) return loc; return {}; } -auto BuiltinBitCastExpressionAST::lastSourceLocation() -> SourceLocation { +auto ObjectLiteralExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(bracedInitList)) return loc; if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; if (auto loc = cxx::lastSourceLocation(typeId)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(castLoc)) return loc; return {}; } -auto BuiltinOffsetofExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(offsetofLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto ThisExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(thisLoc)) return loc; return {}; } -auto BuiltinOffsetofExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(offsetofLoc)) return loc; +auto ThisExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(thisLoc)) return loc; return {}; } -auto TypeidExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typeidLoc)) return loc; +auto GenericSelectionExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(genericLoc)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(genericAssociationList)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto TypeidExpressionAST::lastSourceLocation() -> SourceLocation { +auto GenericSelectionExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(genericAssociationList)) return loc; + if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeidLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(genericLoc)) return loc; return {}; } -auto TypeidOfTypeExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typeidLoc)) return loc; +auto NestedStatementExpressionAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(statement)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto TypeidOfTypeExpressionAST::lastSourceLocation() -> SourceLocation { +auto NestedStatementExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(statement)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeidLoc)) return loc; return {}; } -auto SpliceExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(splicer)) return loc; +auto NestedExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto SpliceExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(splicer)) return loc; +auto NestedExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; return {}; } -auto GlobalScopeReflectExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; +auto IdExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; return {}; } -auto GlobalScopeReflectExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; +auto IdExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; + if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; return {}; } -auto NamespaceReflectExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; +auto LambdaExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(captureDefaultLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(captureList)) return loc; + if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(templateParameterList)) return loc; + if (auto loc = cxx::firstSourceLocation(greaterLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(templateRequiresClause)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(parameterDeclarationClause)) + return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(gnuAtributeList)) return loc; + if (auto loc = cxx::firstSourceLocation(lambdaSpecifierList)) return loc; + if (auto loc = cxx::firstSourceLocation(exceptionSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; + if (auto loc = cxx::firstSourceLocation(trailingReturnType)) return loc; + if (auto loc = cxx::firstSourceLocation(requiresClause)) return loc; + if (auto loc = cxx::firstSourceLocation(statement)) return loc; return {}; } -auto NamespaceReflectExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; +auto LambdaExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(statement)) return loc; + if (auto loc = cxx::lastSourceLocation(requiresClause)) return loc; + if (auto loc = cxx::lastSourceLocation(trailingReturnType)) return loc; + if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; + if (auto loc = cxx::lastSourceLocation(exceptionSpecifier)) return loc; + if (auto loc = cxx::lastSourceLocation(lambdaSpecifierList)) return loc; + if (auto loc = cxx::lastSourceLocation(gnuAtributeList)) return loc; + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(parameterDeclarationClause)) + return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(templateRequiresClause)) return loc; + if (auto loc = cxx::lastSourceLocation(greaterLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(templateParameterList)) return loc; + if (auto loc = cxx::lastSourceLocation(lessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(captureList)) return loc; + if (auto loc = cxx::lastSourceLocation(captureDefaultLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; return {}; } -auto TypeIdReflectExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; +auto FoldExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(foldOpLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto TypeIdReflectExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; +auto FoldExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(foldOpLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; return {}; } -auto ReflectExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; +auto RightFoldExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto ReflectExpressionAST::lastSourceLocation() -> SourceLocation { +auto RightFoldExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; return {}; } -auto LabelAddressExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(ampAmpLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; +auto LeftFoldExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto LabelAddressExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(ampAmpLoc)) return loc; +auto LeftFoldExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; return {}; } -auto UnaryExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; +auto RequiresExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(requiresLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(parameterDeclarationClause)) + return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lbraceLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(requirementList)) return loc; + if (auto loc = cxx::firstSourceLocation(rbraceLoc)) return loc; return {}; } -auto UnaryExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; +auto RequiresExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rbraceLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(requirementList)) return loc; + if (auto loc = cxx::lastSourceLocation(lbraceLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(parameterDeclarationClause)) + return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(requiresLoc)) return loc; return {}; } -auto AwaitExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(awaitLoc)) return loc; +auto VaArgExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(vaArgLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto AwaitExpressionAST::lastSourceLocation() -> SourceLocation { +auto VaArgExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(awaitLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(vaArgLoc)) return loc; return {}; } -auto SizeofExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(sizeofLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; +auto SubscriptExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(indexExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; return {}; } -auto SizeofExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(sizeofLoc)) return loc; +auto SubscriptExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(indexExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; return {}; } -auto SizeofTypeExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(sizeofLoc)) return loc; +auto CallExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto SizeofTypeExpressionAST::lastSourceLocation() -> SourceLocation { +auto CallExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(sizeofLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; return {}; } -auto SizeofPackExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(sizeofLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; +auto TypeConstructionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeSpecifier)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto SizeofPackExpressionAST::lastSourceLocation() -> SourceLocation { +auto TypeConstructionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(sizeofLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeSpecifier)) return loc; return {}; } -auto AlignofTypeExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(alignofLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto BracedTypeConstructionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(bracedInitList)) return loc; return {}; } -auto AlignofTypeExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(alignofLoc)) return loc; +auto BracedTypeConstructionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(bracedInitList)) return loc; + if (auto loc = cxx::lastSourceLocation(typeSpecifier)) return loc; return {}; } -auto AlignofExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(alignofLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; +auto SpliceMemberExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(accessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(splicer)) return loc; return {}; } -auto AlignofExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(alignofLoc)) return loc; +auto SpliceMemberExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(splicer)) return loc; + if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(accessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; return {}; } -auto NoexceptExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(noexceptLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto MemberExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(accessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; return {}; } -auto NoexceptExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(noexceptLoc)) return loc; +auto MemberExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; + if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::lastSourceLocation(accessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; return {}; } -auto NewExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(newLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(newPlacement)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeSpecifierList)) return loc; - if (auto loc = cxx::firstSourceLocation(declarator)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(newInitalizer)) return loc; +auto PostIncrExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(baseExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; return {}; } -auto NewExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(newInitalizer)) return loc; - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(declarator)) return loc; - if (auto loc = cxx::lastSourceLocation(typeSpecifierList)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(newPlacement)) return loc; - if (auto loc = cxx::lastSourceLocation(newLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; +auto PostIncrExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(baseExpression)) return loc; return {}; } -auto DeleteExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(deleteLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; +auto CppCastExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(castLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lessLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(greaterLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto DeleteExpressionAST::lastSourceLocation() -> SourceLocation { +auto CppCastExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(deleteLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(greaterLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(lessLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(castLoc)) return loc; return {}; } -auto CastExpressionAST::firstSourceLocation() -> SourceLocation { +auto BuiltinBitCastExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(castLoc)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto CastExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; +auto BuiltinBitCastExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; if (auto loc = cxx::lastSourceLocation(typeId)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(castLoc)) return loc; return {}; } -auto ImplicitCastExpressionAST::firstSourceLocation() -> SourceLocation { +auto BuiltinOffsetofExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(offsetofLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto ImplicitCastExpressionAST::lastSourceLocation() -> SourceLocation { +auto BuiltinOffsetofExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(offsetofLoc)) return loc; return {}; } -auto BinaryExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; +auto TypeidExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeidLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto BinaryExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; +auto TypeidExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeidLoc)) return loc; return {}; } -auto ConditionalExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(condition)) return loc; - if (auto loc = cxx::firstSourceLocation(questionLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(iftrueExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(iffalseExpression)) return loc; +auto TypeidOfTypeExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeidLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto ConditionalExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(iffalseExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(iftrueExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(questionLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(condition)) return loc; +auto TypeidOfTypeExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeidLoc)) return loc; return {}; } -auto YieldExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(yieldLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; +auto SpliceExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(splicer)) return loc; return {}; } -auto YieldExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(yieldLoc)) return loc; +auto SpliceExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(splicer)) return loc; return {}; } -auto ThrowExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(throwLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; +auto GlobalScopeReflectExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; return {}; } -auto ThrowExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(throwLoc)) return loc; +auto GlobalScopeReflectExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; return {}; } -auto AssignmentExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; - if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; +auto NamespaceReflectExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; return {}; } -auto AssignmentExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; - if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; +auto NamespaceReflectExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; return {}; } -auto PackExpansionExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; +auto TypeIdReflectExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; return {}; } -auto PackExpansionExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expression)) return loc; +auto TypeIdReflectExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; return {}; } - -auto DesignatedInitializerClauseAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(designatorList)) return loc; - if (auto loc = cxx::firstSourceLocation(initializer)) return loc; + +auto ReflectExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(caretLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto DesignatedInitializerClauseAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(initializer)) return loc; - if (auto loc = cxx::lastSourceLocation(designatorList)) return loc; +auto ReflectExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(caretLoc)) return loc; return {}; } -auto TypeTraitExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typeTraitLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeIdList)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto LabelAddressExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(ampAmpLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; return {}; } -auto TypeTraitExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeIdList)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(typeTraitLoc)) return loc; +auto LabelAddressExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(ampAmpLoc)) return loc; return {}; } -auto ConditionExpressionAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; - if (auto loc = cxx::firstSourceLocation(declSpecifierList)) return loc; - if (auto loc = cxx::firstSourceLocation(declarator)) return loc; - if (auto loc = cxx::firstSourceLocation(initializer)) return loc; +auto UnaryExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto ConditionExpressionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(initializer)) return loc; - if (auto loc = cxx::lastSourceLocation(declarator)) return loc; - if (auto loc = cxx::lastSourceLocation(declSpecifierList)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; +auto UnaryExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; return {}; } -auto EqualInitializerAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(equalLoc)) return loc; +auto AwaitExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(awaitLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto EqualInitializerAST::lastSourceLocation() -> SourceLocation { +auto AwaitExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(equalLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(awaitLoc)) return loc; return {}; } -auto BracedInitListAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lbraceLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; - if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rbraceLoc)) return loc; +auto SizeofExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(sizeofLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto BracedInitListAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rbraceLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; - if (auto loc = cxx::lastSourceLocation(lbraceLoc)) return loc; +auto SizeofExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(sizeofLoc)) return loc; return {}; } -auto ParenInitializerAST::firstSourceLocation() -> SourceLocation { +auto SizeofTypeExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(sizeofLoc)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto ParenInitializerAST::lastSourceLocation() -> SourceLocation { +auto SizeofTypeExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(sizeofLoc)) return loc; return {}; } -auto DefaultGenericAssociationAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(defaultLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; +auto SizeofPackExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(sizeofLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto DefaultGenericAssociationAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(defaultLoc)) return loc; +auto SizeofPackExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(sizeofLoc)) return loc; return {}; } -auto TypeGenericAssociationAST::firstSourceLocation() -> SourceLocation { +auto AlignofTypeExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(alignofLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto TypeGenericAssociationAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; +auto AlignofTypeExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(alignofLoc)) return loc; return {}; } -auto DotDesignatorAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(dotLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; - return {}; -} - -auto DotDesignatorAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(dotLoc)) return loc; - return {}; -} - -auto SubscriptDesignatorAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; +auto AlignofExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(alignofLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; return {}; } -auto SubscriptDesignatorAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; +auto AlignofExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(alignofLoc)) return loc; return {}; } -auto SplicerAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; +auto NoexceptExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(noexceptLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; - if (auto loc = cxx::firstSourceLocation(secondColonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto SplicerAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(secondColonLoc)) return loc; +auto NoexceptExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(noexceptLoc)) return loc; return {}; } -auto GlobalModuleFragmentAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(moduleLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(declarationList)) return loc; +auto NewExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(newLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(newPlacement)) return loc; + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeSpecifierList)) return loc; + if (auto loc = cxx::firstSourceLocation(declarator)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(newInitalizer)) return loc; return {}; } -auto GlobalModuleFragmentAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(declarationList)) return loc; - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(moduleLoc)) return loc; +auto NewExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(newInitalizer)) return loc; + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(declarator)) return loc; + if (auto loc = cxx::lastSourceLocation(typeSpecifierList)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(newPlacement)) return loc; + if (auto loc = cxx::lastSourceLocation(newLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; return {}; } -auto PrivateModuleFragmentAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(moduleLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(privateLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(declarationList)) return loc; +auto DeleteExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(deleteLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto PrivateModuleFragmentAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(declarationList)) return loc; - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(privateLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(moduleLoc)) return loc; +auto DeleteExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(deleteLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; return {}; } -auto ModuleDeclarationAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(exportLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(moduleLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(moduleName)) return loc; - if (auto loc = cxx::firstSourceLocation(modulePartition)) return loc; - if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; - if (auto loc = cxx::firstSourceLocation(semicolonLoc)) return loc; +auto CastExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; + if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto ModuleDeclarationAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(semicolonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; - if (auto loc = cxx::lastSourceLocation(modulePartition)) return loc; - if (auto loc = cxx::lastSourceLocation(moduleName)) return loc; - if (auto loc = cxx::lastSourceLocation(moduleLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(exportLoc)) return loc; +auto CastExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; + if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; return {}; } -auto ModuleNameAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(moduleQualifier)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; +auto ImplicitCastExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto ModuleNameAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(moduleQualifier)) return loc; +auto ImplicitCastExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; return {}; } -auto ModuleQualifierAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(moduleQualifier)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(dotLoc)) return loc; +auto BinaryExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; return {}; } -auto ModuleQualifierAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(dotLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(moduleQualifier)) return loc; +auto BinaryExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; return {}; } -auto ModulePartitionAST::firstSourceLocation() -> SourceLocation { +auto ConditionalExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(condition)) return loc; + if (auto loc = cxx::firstSourceLocation(questionLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(iftrueExpression)) return loc; if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(moduleName)) return loc; + if (auto loc = cxx::firstSourceLocation(iffalseExpression)) return loc; return {}; } -auto ModulePartitionAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(moduleName)) return loc; +auto ConditionalExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(iffalseExpression)) return loc; if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(iftrueExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(questionLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(condition)) return loc; return {}; } -auto ImportNameAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(headerLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(modulePartition)) return loc; - if (auto loc = cxx::firstSourceLocation(moduleName)) return loc; +auto YieldExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(yieldLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto ImportNameAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(moduleName)) return loc; - if (auto loc = cxx::lastSourceLocation(modulePartition)) return loc; - if (auto loc = cxx::lastSourceLocation(headerLoc)) return loc; +auto YieldExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(yieldLoc)) return loc; return {}; } -auto InitDeclaratorAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(declarator)) return loc; - if (auto loc = cxx::firstSourceLocation(requiresClause)) return loc; - if (auto loc = cxx::firstSourceLocation(initializer)) return loc; +auto ThrowExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(throwLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto InitDeclaratorAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(initializer)) return loc; - if (auto loc = cxx::lastSourceLocation(requiresClause)) return loc; - if (auto loc = cxx::lastSourceLocation(declarator)) return loc; +auto ThrowExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(throwLoc)) return loc; return {}; } -auto DeclaratorAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(ptrOpList)) return loc; - if (auto loc = cxx::firstSourceLocation(coreDeclarator)) return loc; - if (auto loc = cxx::firstSourceLocation(declaratorChunkList)) return loc; +auto AssignmentExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; return {}; } -auto DeclaratorAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(declaratorChunkList)) return loc; - if (auto loc = cxx::lastSourceLocation(coreDeclarator)) return loc; - if (auto loc = cxx::lastSourceLocation(ptrOpList)) return loc; +auto AssignmentExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; return {}; } -auto UsingDeclaratorAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typenameLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; +auto CompoundAssignmentExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(leftExpression)) return loc; + if (auto loc = cxx::firstSourceLocation(opLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rightExpression)) return loc; return {}; } -auto UsingDeclaratorAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; - if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::lastSourceLocation(typenameLoc)) return loc; +auto CompoundAssignmentExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rightExpression)) return loc; + if (auto loc = cxx::lastSourceLocation(opLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(leftExpression)) return loc; return {}; } -auto EnumeratorAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; - if (auto loc = cxx::firstSourceLocation(equalLoc)) return loc; +auto PackExpansionExpressionAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; return {}; } -auto EnumeratorAST::lastSourceLocation() -> SourceLocation { +auto PackExpansionExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(equalLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; return {}; } -auto TypeIdAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(typeSpecifierList)) return loc; - if (auto loc = cxx::firstSourceLocation(declarator)) return loc; +auto DesignatedInitializerClauseAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(designatorList)) return loc; + if (auto loc = cxx::firstSourceLocation(initializer)) return loc; return {}; } -auto TypeIdAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(declarator)) return loc; - if (auto loc = cxx::lastSourceLocation(typeSpecifierList)) return loc; +auto DesignatedInitializerClauseAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(initializer)) return loc; + if (auto loc = cxx::lastSourceLocation(designatorList)) return loc; return {}; } -auto HandlerAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(catchLoc)) return loc; +auto TypeTraitExpressionAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeTraitLoc)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(exceptionDeclaration)) return loc; + if (auto loc = cxx::firstSourceLocation(typeIdList)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(statement)) return loc; return {}; } -auto HandlerAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(statement)) return loc; +auto TypeTraitExpressionAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(exceptionDeclaration)) return loc; + if (auto loc = cxx::lastSourceLocation(typeIdList)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(catchLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeTraitLoc)) return loc; return {}; } -auto BaseSpecifierAST::firstSourceLocation() -> SourceLocation { +auto ConditionExpressionAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(attributeList)) return loc; - if (auto loc = cxx::firstSourceLocation(virtualOrAccessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(otherVirtualOrAccessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(unqualifiedId)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(declSpecifierList)) return loc; + if (auto loc = cxx::firstSourceLocation(declarator)) return loc; + if (auto loc = cxx::firstSourceLocation(initializer)) return loc; return {}; } -auto BaseSpecifierAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(unqualifiedId)) return loc; - if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::lastSourceLocation(otherVirtualOrAccessLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(virtualOrAccessLoc)) return loc; +auto ConditionExpressionAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(initializer)) return loc; + if (auto loc = cxx::lastSourceLocation(declarator)) return loc; + if (auto loc = cxx::lastSourceLocation(declSpecifierList)) return loc; if (auto loc = cxx::lastSourceLocation(attributeList)) return loc; return {}; } -auto RequiresClauseAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(requiresLoc)) return loc; +auto EqualInitializerAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(equalLoc)) return loc; if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto RequiresClauseAST::lastSourceLocation() -> SourceLocation { +auto EqualInitializerAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(expression)) return loc; - if (auto loc = cxx::lastSourceLocation(requiresLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(equalLoc)) return loc; return {}; } -auto ParameterDeclarationClauseAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(parameterDeclarationList)) return loc; +auto BracedInitListAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lbraceLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; if (auto loc = cxx::firstSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(rbraceLoc)) return loc; return {}; } -auto ParameterDeclarationClauseAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; +auto BracedInitListAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rbraceLoc)) return loc; if (auto loc = cxx::lastSourceLocation(commaLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(parameterDeclarationList)) return loc; - return {}; -} - -auto TrailingReturnTypeAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(minusGreaterLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(typeId)) return loc; - return {}; -} - -auto TrailingReturnTypeAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(typeId)) return loc; - if (auto loc = cxx::lastSourceLocation(minusGreaterLoc)) return loc; - return {}; -} - -auto LambdaSpecifierAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(specifierLoc)) return loc; - return {}; -} - -auto LambdaSpecifierAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(specifierLoc)) return loc; - return {}; -} - -auto TypeConstraintAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(lessLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(templateArgumentList)) return loc; - if (auto loc = cxx::firstSourceLocation(greaterLoc)) return loc; - return {}; -} - -auto TypeConstraintAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(greaterLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(templateArgumentList)) return loc; - if (auto loc = cxx::lastSourceLocation(lessLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; + if (auto loc = cxx::lastSourceLocation(lbraceLoc)) return loc; return {}; } -auto AttributeArgumentClauseAST::firstSourceLocation() -> SourceLocation { +auto ParenInitializerAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; return {}; } -auto AttributeArgumentClauseAST::lastSourceLocation() -> SourceLocation { +auto ParenInitializerAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; return {}; } -auto AttributeAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(attributeToken)) return loc; - if (auto loc = cxx::firstSourceLocation(attributeArgumentClause)) return loc; - if (auto loc = cxx::firstSourceLocation(ellipsisLoc)) return loc; +auto DefaultGenericAssociationAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(defaultLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto AttributeAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(ellipsisLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeArgumentClause)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeToken)) return loc; +auto DefaultGenericAssociationAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(defaultLoc)) return loc; return {}; } -auto AttributeUsingPrefixAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(usingLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(attributeNamespaceLoc)) return loc; +auto TypeGenericAssociationAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(typeId)) return loc; if (auto loc = cxx::firstSourceLocation(colonLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; return {}; } -auto AttributeUsingPrefixAST::lastSourceLocation() -> SourceLocation { +auto TypeGenericAssociationAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(expression)) return loc; if (auto loc = cxx::lastSourceLocation(colonLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(attributeNamespaceLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(usingLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(typeId)) return loc; return {}; } -auto NewPlacementAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(expressionList)) return loc; - if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; +auto DotDesignatorAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(dotLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; return {}; } -auto NewPlacementAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(expressionList)) return loc; - if (auto loc = cxx::lastSourceLocation(lparenLoc)) return loc; +auto DotDesignatorAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(dotLoc)) return loc; return {}; } -auto NestedNamespaceSpecifierAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(inlineLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; +auto SubscriptDesignatorAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(lbracketLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(expression)) return loc; + if (auto loc = cxx::firstSourceLocation(rbracketLoc)) return loc; return {}; } -auto NestedNamespaceSpecifierAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; - if (auto loc = cxx::lastSourceLocation(inlineLoc)) return loc; +auto SubscriptDesignatorAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(rbracketLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(expression)) return loc; + if (auto loc = cxx::lastSourceLocation(lbracketLoc)) return loc; return {}; } @@ -3695,6 +3709,7 @@ std::string_view kASTKindNames[] = { "yield-expression", "throw-expression", "assignment-expression", + "compound-assignment-expression", "pack-expansion-expression", "designated-initializer-clause", "type-trait-expression", diff --git a/src/parser/cxx/ast.fbs b/src/parser/cxx/ast.fbs index b707d7f0..77e631ae 100644 --- a/src/parser/cxx/ast.fbs +++ b/src/parser/cxx/ast.fbs @@ -182,6 +182,7 @@ union Expression { YieldExpression, ThrowExpression, AssignmentExpression, + CompoundAssignmentExpression, PackExpansionExpression, DesignatedInitializerClause, TypeTraitExpression, @@ -1250,6 +1251,13 @@ table AssignmentExpression /* ExpressionAST */ { op_loc: uint32; } +table CompoundAssignmentExpression /* ExpressionAST */ { + left_expression: Expression; + right_expression: Expression; + op: uint32; + op_loc: uint32; +} + table PackExpansionExpression /* ExpressionAST */ { expression: Expression; ellipsis_loc: uint32; diff --git a/src/parser/cxx/ast.h b/src/parser/cxx/ast.h index db6ed99e..2f6877bb 100644 --- a/src/parser/cxx/ast.h +++ b/src/parser/cxx/ast.h @@ -2556,6 +2556,25 @@ class AssignmentExpressionAST final : public ExpressionAST { auto lastSourceLocation() -> SourceLocation override; }; +class CompoundAssignmentExpressionAST final : public ExpressionAST { + public: + static constexpr ASTKind Kind = ASTKind::CompoundAssignmentExpression; + + CompoundAssignmentExpressionAST() : ExpressionAST(Kind) {} + + ExpressionAST* leftExpression = nullptr; + SourceLocation opLoc; + ExpressionAST* rightExpression = nullptr; + TokenKind op = TokenKind::T_EOF_SYMBOL; + ImplicitCastKind leftCastKind = ImplicitCastKind::kIdentity; + const Type* leftCastType = nullptr; + + void accept(ASTVisitor* visitor) override { visitor->visit(this); } + + auto firstSourceLocation() -> SourceLocation override; + auto lastSourceLocation() -> SourceLocation override; +}; + class PackExpansionExpressionAST final : public ExpressionAST { public: static constexpr ASTKind Kind = ASTKind::PackExpansionExpression; @@ -4717,6 +4736,9 @@ auto visit(Visitor&& visitor, ExpressionAST* ast) { case AssignmentExpressionAST::Kind: return std::invoke(std::forward(visitor), static_cast(ast)); + case CompoundAssignmentExpressionAST::Kind: + return std::invoke(std::forward(visitor), + static_cast(ast)); case PackExpansionExpressionAST::Kind: return std::invoke(std::forward(visitor), static_cast(ast)); @@ -4802,6 +4824,7 @@ template <> case YieldExpressionAST::Kind: case ThrowExpressionAST::Kind: case AssignmentExpressionAST::Kind: + case CompoundAssignmentExpressionAST::Kind: case PackExpansionExpressionAST::Kind: case DesignatedInitializerClauseAST::Kind: case TypeTraitExpressionAST::Kind: diff --git a/src/parser/cxx/ast_fwd.h b/src/parser/cxx/ast_fwd.h index a5ca7644..4e4f7882 100644 --- a/src/parser/cxx/ast_fwd.h +++ b/src/parser/cxx/ast_fwd.h @@ -219,6 +219,7 @@ class ConditionalExpressionAST; class YieldExpressionAST; class ThrowExpressionAST; class AssignmentExpressionAST; +class CompoundAssignmentExpressionAST; class PackExpansionExpressionAST; class DesignatedInitializerClauseAST; class TypeTraitExpressionAST; diff --git a/src/parser/cxx/ast_interpreter.cc b/src/parser/cxx/ast_interpreter.cc index 0676dae1..d260ebdc 100644 --- a/src/parser/cxx/ast_interpreter.cc +++ b/src/parser/cxx/ast_interpreter.cc @@ -803,6 +803,9 @@ struct ASTInterpreter::ExpressionVisitor { [[nodiscard]] auto operator()(AssignmentExpressionAST* ast) -> ExpressionResult; + [[nodiscard]] auto operator()(CompoundAssignmentExpressionAST* ast) + -> ExpressionResult; + [[nodiscard]] auto operator()(PackExpansionExpressionAST* ast) -> ExpressionResult; @@ -2567,6 +2570,14 @@ auto ASTInterpreter::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) return ExpressionResult{std::nullopt}; } +auto ASTInterpreter::ExpressionVisitor::operator()( + CompoundAssignmentExpressionAST* ast) -> ExpressionResult { + auto leftExpressionResult = accept(ast->leftExpression); + auto rightExpressionResult = accept(ast->rightExpression); + + return ExpressionResult{std::nullopt}; +} + auto ASTInterpreter::ExpressionVisitor::operator()( PackExpansionExpressionAST* ast) -> ExpressionResult { auto expressionResult = accept(ast->expression); diff --git a/src/parser/cxx/ast_kind.h b/src/parser/cxx/ast_kind.h index ccbfd9f1..b1468538 100644 --- a/src/parser/cxx/ast_kind.h +++ b/src/parser/cxx/ast_kind.h @@ -164,6 +164,7 @@ enum class ASTKind { YieldExpression, ThrowExpression, AssignmentExpression, + CompoundAssignmentExpression, PackExpansionExpression, DesignatedInitializerClause, TypeTraitExpression, diff --git a/src/parser/cxx/ast_pretty_printer.cc b/src/parser/cxx/ast_pretty_printer.cc index 824c5a9b..3ec9d128 100644 --- a/src/parser/cxx/ast_pretty_printer.cc +++ b/src/parser/cxx/ast_pretty_printer.cc @@ -285,6 +285,8 @@ struct ASTPrettyPrinter::ExpressionVisitor { void operator()(AssignmentExpressionAST* ast); + void operator()(CompoundAssignmentExpressionAST* ast); + void operator()(PackExpansionExpressionAST* ast); void operator()(DesignatedInitializerClauseAST* ast); @@ -3068,6 +3070,19 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( accept(ast->rightExpression); } +void ASTPrettyPrinter::ExpressionVisitor::operator()( + CompoundAssignmentExpressionAST* ast) { + accept(ast->leftExpression); + if (ast->opLoc) { + space(); + keepSpace(); + accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); + } + accept(ast->rightExpression); +} + void ASTPrettyPrinter::ExpressionVisitor::operator()( PackExpansionExpressionAST* ast) { accept(ast->expression); diff --git a/src/parser/cxx/ast_printer.cc b/src/parser/cxx/ast_printer.cc index 5c59a9ed..50ff63ec 100644 --- a/src/parser/cxx/ast_printer.cc +++ b/src/parser/cxx/ast_printer.cc @@ -1784,6 +1784,27 @@ void ASTPrinter::visit(AssignmentExpressionAST* ast) { accept(ast->rightExpression, "right-expression"); } +void ASTPrinter::visit(CompoundAssignmentExpressionAST* ast) { + out_ << "compound-assignment-expression"; + if (ast->type) { + out_ << std::format(" [{} {}]", to_string(ast->valueCategory), + to_string(ast->type)); + } + out_ << "\n"; + if (ast->op != TokenKind::T_EOF_SYMBOL) { + ++indent_; + out_ << std::format("{:{}}", "", indent_ * 2); + out_ << std::format("op: {}\n", Token::spell(ast->op)); + --indent_; + } + ++indent_; + out_ << std::format("{:{}}", "", indent_ * 2); + out_ << std::format("left-cast-kind: {}\n", to_string(ast->leftCastKind)); + --indent_; + accept(ast->leftExpression, "left-expression"); + accept(ast->rightExpression, "right-expression"); +} + void ASTPrinter::visit(PackExpansionExpressionAST* ast) { out_ << "pack-expansion-expression"; if (ast->type) { diff --git a/src/parser/cxx/ast_printer.h b/src/parser/cxx/ast_printer.h index 4ef31822..e1df2739 100644 --- a/src/parser/cxx/ast_printer.h +++ b/src/parser/cxx/ast_printer.h @@ -177,6 +177,7 @@ class ASTPrinter : ASTVisitor { void visit(YieldExpressionAST* ast) override; void visit(ThrowExpressionAST* ast) override; void visit(AssignmentExpressionAST* ast) override; + void visit(CompoundAssignmentExpressionAST* ast) override; void visit(PackExpansionExpressionAST* ast) override; void visit(DesignatedInitializerClauseAST* ast) override; void visit(TypeTraitExpressionAST* ast) override; diff --git a/src/parser/cxx/ast_rewriter.cc b/src/parser/cxx/ast_rewriter.cc index bf4bbfc3..c84fbfe4 100644 --- a/src/parser/cxx/ast_rewriter.cc +++ b/src/parser/cxx/ast_rewriter.cc @@ -364,6 +364,9 @@ struct ASTRewriter::ExpressionVisitor { [[nodiscard]] auto operator()(AssignmentExpressionAST* ast) -> ExpressionAST*; + [[nodiscard]] auto operator()(CompoundAssignmentExpressionAST* ast) + -> ExpressionAST*; + [[nodiscard]] auto operator()(PackExpansionExpressionAST* ast) -> ExpressionAST*; @@ -3275,6 +3278,22 @@ auto ASTRewriter::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) return copy; } +auto ASTRewriter::ExpressionVisitor::operator()( + CompoundAssignmentExpressionAST* ast) -> ExpressionAST* { + auto copy = make_node(arena()); + + copy->valueCategory = ast->valueCategory; + copy->type = ast->type; + copy->leftExpression = rewrite(ast->leftExpression); + copy->opLoc = ast->opLoc; + copy->rightExpression = rewrite(ast->rightExpression); + copy->op = ast->op; + copy->leftCastKind = ast->leftCastKind; + copy->leftCastType = ast->leftCastType; + + return copy; +} + auto ASTRewriter::ExpressionVisitor::operator()(PackExpansionExpressionAST* ast) -> ExpressionAST* { auto copy = make_node(arena()); diff --git a/src/parser/cxx/ast_slot.cc b/src/parser/cxx/ast_slot.cc index 19e62e1f..f757bf16 100644 --- a/src/parser/cxx/ast_slot.cc +++ b/src/parser/cxx/ast_slot.cc @@ -4010,6 +4010,33 @@ void ASTSlot::visit(AssignmentExpressionAST* ast) { slotCount_ = 4; } +void ASTSlot::visit(CompoundAssignmentExpressionAST* ast) { + switch (slot_) { + case 0: // leftExpression + value_ = reinterpret_cast(ast->leftExpression); + slotKind_ = ASTSlotKind::kNode; + slotNameIndex_ = SlotNameIndex{129}; + break; + case 1: // opLoc + value_ = ast->opLoc.index(); + slotKind_ = ASTSlotKind::kToken; + slotNameIndex_ = SlotNameIndex{155}; + break; + case 2: // rightExpression + value_ = reinterpret_cast(ast->rightExpression); + slotKind_ = ASTSlotKind::kNode; + slotNameIndex_ = SlotNameIndex{183}; + break; + case 3: // op + value_ = std::intptr_t(ast->op); + slotKind_ = ASTSlotKind::kIntAttribute; + slotNameIndex_ = SlotNameIndex{154}; + break; + } // switch + + slotCount_ = 4; +} + void ASTSlot::visit(PackExpansionExpressionAST* ast) { switch (slot_) { case 0: // expression diff --git a/src/parser/cxx/ast_slot.h b/src/parser/cxx/ast_slot.h index 74dc29ca..da31d9d1 100644 --- a/src/parser/cxx/ast_slot.h +++ b/src/parser/cxx/ast_slot.h @@ -188,6 +188,7 @@ class ASTSlot final : ASTVisitor { void visit(YieldExpressionAST* ast) override; void visit(ThrowExpressionAST* ast) override; void visit(AssignmentExpressionAST* ast) override; + void visit(CompoundAssignmentExpressionAST* ast) override; void visit(PackExpansionExpressionAST* ast) override; void visit(DesignatedInitializerClauseAST* ast) override; void visit(TypeTraitExpressionAST* ast) override; diff --git a/src/parser/cxx/ast_visitor.cc b/src/parser/cxx/ast_visitor.cc index db9d935c..bde88bde 100644 --- a/src/parser/cxx/ast_visitor.cc +++ b/src/parser/cxx/ast_visitor.cc @@ -655,6 +655,11 @@ void ASTVisitor::visit(AssignmentExpressionAST* ast) { accept(ast->rightExpression); } +void ASTVisitor::visit(CompoundAssignmentExpressionAST* ast) { + accept(ast->leftExpression); + accept(ast->rightExpression); +} + void ASTVisitor::visit(PackExpansionExpressionAST* ast) { accept(ast->expression); } diff --git a/src/parser/cxx/ast_visitor.h b/src/parser/cxx/ast_visitor.h index 7cb27a93..5ba0d994 100644 --- a/src/parser/cxx/ast_visitor.h +++ b/src/parser/cxx/ast_visitor.h @@ -173,6 +173,7 @@ class ASTVisitor { virtual void visit(YieldExpressionAST* ast); virtual void visit(ThrowExpressionAST* ast); virtual void visit(AssignmentExpressionAST* ast); + virtual void visit(CompoundAssignmentExpressionAST* ast); virtual void visit(PackExpansionExpressionAST* ast); virtual void visit(DesignatedInitializerClauseAST* ast); virtual void visit(TypeTraitExpressionAST* ast); diff --git a/src/parser/cxx/flatbuffers/ast_decoder.cc b/src/parser/cxx/flatbuffers/ast_decoder.cc index f09da715..7e8368bf 100644 --- a/src/parser/cxx/flatbuffers/ast_decoder.cc +++ b/src/parser/cxx/flatbuffers/ast_decoder.cc @@ -372,6 +372,9 @@ auto ASTDecoder::decodeExpression(const void* ptr, io::Expression type) case io::Expression_AssignmentExpression: return decodeAssignmentExpression( reinterpret_cast(ptr)); + case io::Expression_CompoundAssignmentExpression: + return decodeCompoundAssignmentExpression( + reinterpret_cast(ptr)); case io::Expression_PackExpansionExpression: return decodePackExpansionExpression( reinterpret_cast(ptr)); @@ -3041,6 +3044,21 @@ auto ASTDecoder::decodeAssignmentExpression( return ast; } +auto ASTDecoder::decodeCompoundAssignmentExpression( + const io::CompoundAssignmentExpression* node) + -> CompoundAssignmentExpressionAST* { + if (!node) return nullptr; + + auto ast = new (pool_) CompoundAssignmentExpressionAST(); + ast->leftExpression = + decodeExpression(node->left_expression(), node->left_expression_type()); + ast->opLoc = SourceLocation(node->op_loc()); + ast->rightExpression = + decodeExpression(node->right_expression(), node->right_expression_type()); + ast->op = static_cast(node->op()); + return ast; +} + auto ASTDecoder::decodePackExpansionExpression( const io::PackExpansionExpression* node) -> PackExpansionExpressionAST* { if (!node) return nullptr; diff --git a/src/parser/cxx/flatbuffers/ast_encoder.cc b/src/parser/cxx/flatbuffers/ast_encoder.cc index a67833f9..3973538e 100644 --- a/src/parser/cxx/flatbuffers/ast_encoder.cc +++ b/src/parser/cxx/flatbuffers/ast_encoder.cc @@ -3369,6 +3369,27 @@ void ASTEncoder::visit(AssignmentExpressionAST* ast) { type_ = io::Expression_AssignmentExpression; } +void ASTEncoder::visit(CompoundAssignmentExpressionAST* ast) { + const auto [leftExpression, leftExpressionType] = + acceptExpression(ast->leftExpression); + + const auto [rightExpression, rightExpressionType] = + acceptExpression(ast->rightExpression); + + io::CompoundAssignmentExpression::Builder builder{fbb_}; + builder.add_left_expression(leftExpression); + builder.add_left_expression_type( + static_cast(leftExpressionType)); + builder.add_op_loc(ast->opLoc.index()); + builder.add_right_expression(rightExpression); + builder.add_right_expression_type( + static_cast(rightExpressionType)); + builder.add_op(static_cast(ast->op)); + + offset_ = builder.Finish().Union(); + type_ = io::Expression_CompoundAssignmentExpression; +} + void ASTEncoder::visit(PackExpansionExpressionAST* ast) { const auto [expression, expressionType] = acceptExpression(ast->expression); diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index afc2e7b8..df0e7cbf 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -3095,15 +3095,24 @@ auto Parser::parse_maybe_assignment_expression(ExpressionAST*& yyast, parse_error("expected an expression"); } - auto ast = make_node(pool_); - ast->leftExpression = yyast; - ast->opLoc = opLoc; - ast->rightExpression = expression; - ast->op = op; + if (op == TokenKind::T_EQUAL) { + auto ast = make_node(pool_); - check(ast); + ast->leftExpression = yyast; + ast->opLoc = opLoc; + ast->rightExpression = expression; + ast->op = op; + yyast = ast; + } else { + auto ast = make_node(pool_); + ast->leftExpression = yyast; + ast->opLoc = opLoc; + ast->rightExpression = expression; + ast->op = op; + yyast = ast; + } - yyast = ast; + check(yyast); } return true; diff --git a/src/parser/cxx/private/ast_decoder.h b/src/parser/cxx/private/ast_decoder.h index 2302f910..6525bee4 100644 --- a/src/parser/cxx/private/ast_decoder.h +++ b/src/parser/cxx/private/ast_decoder.h @@ -334,6 +334,9 @@ class ASTDecoder { -> ThrowExpressionAST*; auto decodeAssignmentExpression(const io::AssignmentExpression* node) -> AssignmentExpressionAST*; + auto decodeCompoundAssignmentExpression( + const io::CompoundAssignmentExpression* node) + -> CompoundAssignmentExpressionAST*; auto decodePackExpansionExpression(const io::PackExpansionExpression* node) -> PackExpansionExpressionAST*; auto decodeDesignatedInitializerClause( diff --git a/src/parser/cxx/private/ast_encoder.h b/src/parser/cxx/private/ast_encoder.h index 08d9b0c9..a5710f16 100644 --- a/src/parser/cxx/private/ast_encoder.h +++ b/src/parser/cxx/private/ast_encoder.h @@ -262,6 +262,7 @@ class ASTEncoder : ASTVisitor { void visit(YieldExpressionAST* ast) override; void visit(ThrowExpressionAST* ast) override; void visit(AssignmentExpressionAST* ast) override; + void visit(CompoundAssignmentExpressionAST* ast) override; void visit(PackExpansionExpressionAST* ast) override; void visit(DesignatedInitializerClauseAST* ast) override; void visit(TypeTraitExpressionAST* ast) override; diff --git a/src/parser/cxx/token_fwd.h b/src/parser/cxx/token_fwd.h index 8b4f97a0..666e8e68 100644 --- a/src/parser/cxx/token_fwd.h +++ b/src/parser/cxx/token_fwd.h @@ -24,6 +24,7 @@ #include #include +#include namespace cxx { @@ -323,4 +324,31 @@ enum class BuiltinTypeTraitKind { #undef TOKEN_ALIAS_ENUM // clang-format on +[[nodiscard]] inline auto get_underlying_binary_op(TokenKind op) -> TokenKind { + switch (op) { + case TokenKind::T_STAR_EQUAL: + return TokenKind::T_STAR; + case TokenKind::T_SLASH_EQUAL: + return TokenKind::T_SLASH; + case TokenKind::T_PERCENT_EQUAL: + return TokenKind::T_PERCENT; + case TokenKind::T_PLUS_EQUAL: + return TokenKind::T_PLUS; + case TokenKind::T_MINUS_EQUAL: + return TokenKind::T_MINUS; + case TokenKind::T_LESS_LESS_EQUAL: + return TokenKind::T_LESS_LESS; + case TokenKind::T_AMP_EQUAL: + return TokenKind::T_AMP; + case TokenKind::T_CARET_EQUAL: + return TokenKind::T_CARET; + case TokenKind::T_BAR_EQUAL: + return TokenKind::T_BAR; + case TokenKind::T_GREATER_GREATER_EQUAL: + return TokenKind::T_GREATER_GREATER; + default: + return TokenKind::T_EOF_SYMBOL; + } // switch +} + } // namespace cxx diff --git a/src/parser/cxx/type_checker.cc b/src/parser/cxx/type_checker.cc index 0b4ce931..4e985020 100644 --- a/src/parser/cxx/type_checker.cc +++ b/src/parser/cxx/type_checker.cc @@ -205,6 +205,7 @@ struct TypeChecker::Visitor { void operator()(YieldExpressionAST* ast); void operator()(ThrowExpressionAST* ast); void operator()(AssignmentExpressionAST* ast); + void operator()(CompoundAssignmentExpressionAST* ast); void operator()(PackExpansionExpressionAST* ast); void operator()(DesignatedInitializerClauseAST* ast); void operator()(TypeTraitExpressionAST* ast); @@ -1194,12 +1195,113 @@ void TypeChecker::Visitor::operator()(AssignmentExpressionAST* ast) { if (!ast->leftExpression) return; if (!ast->rightExpression) return; + if (!is_lvalue(ast->leftExpression)) { + error(ast->opLoc, std::format("cannot assign to an rvalue of type '{}'", + to_string(ast->leftExpression->type))); + return; + } + ast->type = ast->leftExpression->type; - ast->valueCategory = ast->leftExpression->valueCategory; + + if (is_parsing_c()) { + ast->valueCategory = ValueCategory::kPrValue; + } else { + ast->valueCategory = ast->leftExpression->valueCategory; + } (void)implicit_conversion(ast->rightExpression, ast->type); } +void TypeChecker::Visitor::operator()(CompoundAssignmentExpressionAST* ast) { + if (!ast->leftExpression) return; + if (!ast->rightExpression) return; + + if (!is_lvalue(ast->leftExpression)) { + error(ast->opLoc, std::format("cannot assign to an rvalue of type '{}'", + to_string(ast->leftExpression->type))); + return; + } + + if ((ast->op == TokenKind::T_PLUS_EQUAL || + ast->op == TokenKind::T_MINUS_EQUAL) && + control()->is_pointer(ast->leftExpression->type) && + control()->is_integral_or_unscoped_enum(ast->rightExpression->type)) { + // pointer addition/subtraction + (void)ensure_prvalue(ast->rightExpression); + adjust_cv(ast->rightExpression); + + (void)integral_promotion(ast->rightExpression); + ast->type = ast->leftExpression->type; + + ast->leftCastKind = ImplicitCastKind::kIdentity; + ast->leftCastType = ast->leftExpression->type; + + if (is_parsing_cxx()) { + ast->valueCategory = ValueCategory::kLValue; + } else { + ast->valueCategory = ValueCategory::kPrValue; + } + + return; + } + + auto lhs = ast->leftExpression; + + auto targetType = usual_arithmetic_conversion(lhs, ast->rightExpression); + + if (!targetType) { + error( + ast->opLoc, + std::format("invalid compound assignment operator '{}' for types '{}' " + "and '{}'", + Token::spell(ast->op), to_string(lhs->type), + to_string(ast->rightExpression->type))); + return; + } + + if (auto leftCastExpr = ast_cast(lhs)) { + ast->leftCastKind = leftCastExpr->castKind; + ast->leftCastType = leftCastExpr->type; + } + + // todo: clean up and generalize + switch (ast->op) { + case TokenKind::T_PLUS_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_MINUS_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_STAR_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_SLASH_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_PERCENT_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_LESS_LESS_EQUAL: + ast->type = ast->leftExpression->type; + break; + case TokenKind::T_GREATER_GREATER_EQUAL: + ast->type = ast->leftExpression->type; + break; + case TokenKind::T_AMP_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_CARET_EQUAL: + ast->type = targetType; + break; + case TokenKind::T_BAR_EQUAL: + ast->type = targetType; + break; + + default: + error(ast->opLoc, "invalid compound assignment operator"); + } // switch +} + void TypeChecker::Visitor::operator()(PackExpansionExpressionAST* ast) {} void TypeChecker::Visitor::operator()(DesignatedInitializerClauseAST* ast) {} @@ -2209,7 +2311,8 @@ auto TypeChecker::Visitor::check_member_access(MemberExpressionAST* ast) if (symbol->isEnumerator()) { ast->valueCategory = ValueCategory::kPrValue; } else { - if (is_lvalue(ast->baseExpression)) { + if (is_lvalue(ast->baseExpression) || + ast->accessOp == TokenKind::T_MINUS_GREATER) { ast->valueCategory = ValueCategory::kLValue; } else { ast->valueCategory = ValueCategory::kXValue;