10b57cec5SDimitry Andric //===- BuildTree.cpp ------------------------------------------*- C++ -*-=====// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric #include "clang/Tooling/Syntax/BuildTree.h" 95ffd83dbSDimitry Andric #include "clang/AST/ASTFwd.h" 10480093f4SDimitry Andric #include "clang/AST/Decl.h" 11480093f4SDimitry Andric #include "clang/AST/DeclBase.h" 125ffd83dbSDimitry Andric #include "clang/AST/DeclCXX.h" 135ffd83dbSDimitry Andric #include "clang/AST/DeclarationName.h" 145ffd83dbSDimitry Andric #include "clang/AST/Expr.h" 155ffd83dbSDimitry Andric #include "clang/AST/ExprCXX.h" 16e8d8bef9SDimitry Andric #include "clang/AST/IgnoreExpr.h" 17e8d8bef9SDimitry Andric #include "clang/AST/OperationKinds.h" 180b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h" 190b57cec5SDimitry Andric #include "clang/AST/Stmt.h" 205ffd83dbSDimitry Andric #include "clang/AST/TypeLoc.h" 215ffd83dbSDimitry Andric #include "clang/AST/TypeLocVisitor.h" 220b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 230b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 240b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 255ffd83dbSDimitry Andric #include "clang/Basic/Specifiers.h" 260b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.h" 270b57cec5SDimitry Andric #include "clang/Lex/Lexer.h" 285ffd83dbSDimitry Andric #include "clang/Lex/LiteralSupport.h" 290b57cec5SDimitry Andric #include "clang/Tooling/Syntax/Nodes.h" 30fcaf7f86SDimitry Andric #include "clang/Tooling/Syntax/TokenBufferTokenManager.h" 310b57cec5SDimitry Andric #include "clang/Tooling/Syntax/Tokens.h" 320b57cec5SDimitry Andric #include "clang/Tooling/Syntax/Tree.h" 330b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 345ffd83dbSDimitry Andric #include "llvm/ADT/DenseMap.h" 355ffd83dbSDimitry Andric #include "llvm/ADT/PointerUnion.h" 360b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 375ffd83dbSDimitry Andric #include "llvm/ADT/ScopeExit.h" 380b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 390b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 400b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 41480093f4SDimitry Andric #include "llvm/Support/Compiler.h" 420b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h" 43480093f4SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 440b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 455ffd83dbSDimitry Andric #include <cstddef> 460b57cec5SDimitry Andric #include <map> 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric using namespace clang; 490b57cec5SDimitry Andric 50e8d8bef9SDimitry Andric // Ignores the implicit `CXXConstructExpr` for copy/move constructor calls 51e8d8bef9SDimitry Andric // generated by the compiler, as well as in implicit conversions like the one 52e8d8bef9SDimitry Andric // wrapping `1` in `X x = 1;`. 53e8d8bef9SDimitry Andric static Expr *IgnoreImplicitConstructorSingleStep(Expr *E) { 54e8d8bef9SDimitry Andric if (auto *C = dyn_cast<CXXConstructExpr>(E)) { 55e8d8bef9SDimitry Andric auto NumArgs = C->getNumArgs(); 56e8d8bef9SDimitry Andric if (NumArgs == 1 || (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) { 57e8d8bef9SDimitry Andric Expr *A = C->getArg(0); 58e8d8bef9SDimitry Andric if (C->getParenOrBraceRange().isInvalid()) 59e8d8bef9SDimitry Andric return A; 60e8d8bef9SDimitry Andric } 61e8d8bef9SDimitry Andric } 62e8d8bef9SDimitry Andric return E; 63e8d8bef9SDimitry Andric } 64e8d8bef9SDimitry Andric 65e8d8bef9SDimitry Andric // In: 66e8d8bef9SDimitry Andric // struct X { 67e8d8bef9SDimitry Andric // X(int) 68e8d8bef9SDimitry Andric // }; 69e8d8bef9SDimitry Andric // X x = X(1); 70e8d8bef9SDimitry Andric // Ignores the implicit `CXXFunctionalCastExpr` that wraps 71e8d8bef9SDimitry Andric // `CXXConstructExpr X(1)`. 72e8d8bef9SDimitry Andric static Expr *IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E) { 73e8d8bef9SDimitry Andric if (auto *F = dyn_cast<CXXFunctionalCastExpr>(E)) { 74e8d8bef9SDimitry Andric if (F->getCastKind() == CK_ConstructorConversion) 75e8d8bef9SDimitry Andric return F->getSubExpr(); 76e8d8bef9SDimitry Andric } 77e8d8bef9SDimitry Andric return E; 78e8d8bef9SDimitry Andric } 79e8d8bef9SDimitry Andric 80e8d8bef9SDimitry Andric static Expr *IgnoreImplicit(Expr *E) { 81e8d8bef9SDimitry Andric return IgnoreExprNodes(E, IgnoreImplicitSingleStep, 82e8d8bef9SDimitry Andric IgnoreImplicitConstructorSingleStep, 83e8d8bef9SDimitry Andric IgnoreCXXFunctionalCastExprWrappingConstructor); 84e8d8bef9SDimitry Andric } 85e8d8bef9SDimitry Andric 86480093f4SDimitry Andric LLVM_ATTRIBUTE_UNUSED 87e8d8bef9SDimitry Andric static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; } 88480093f4SDimitry Andric 895ffd83dbSDimitry Andric namespace { 905ffd83dbSDimitry Andric /// Get start location of the Declarator from the TypeLoc. 915ffd83dbSDimitry Andric /// E.g.: 925ffd83dbSDimitry Andric /// loc of `(` in `int (a)` 935ffd83dbSDimitry Andric /// loc of `*` in `int *(a)` 945ffd83dbSDimitry Andric /// loc of the first `(` in `int (*a)(int)` 955ffd83dbSDimitry Andric /// loc of the `*` in `int *(a)(int)` 965ffd83dbSDimitry Andric /// loc of the first `*` in `const int *const *volatile a;` 975ffd83dbSDimitry Andric /// 985ffd83dbSDimitry Andric /// It is non-trivial to get the start location because TypeLocs are stored 995ffd83dbSDimitry Andric /// inside out. In the example above `*volatile` is the TypeLoc returned 1005ffd83dbSDimitry Andric /// by `Decl.getTypeSourceInfo()`, and `*const` is what `.getPointeeLoc()` 1015ffd83dbSDimitry Andric /// returns. 1025ffd83dbSDimitry Andric struct GetStartLoc : TypeLocVisitor<GetStartLoc, SourceLocation> { 1035ffd83dbSDimitry Andric SourceLocation VisitParenTypeLoc(ParenTypeLoc T) { 1045ffd83dbSDimitry Andric auto L = Visit(T.getInnerLoc()); 1055ffd83dbSDimitry Andric if (L.isValid()) 1065ffd83dbSDimitry Andric return L; 1075ffd83dbSDimitry Andric return T.getLParenLoc(); 1085ffd83dbSDimitry Andric } 1095ffd83dbSDimitry Andric 1105ffd83dbSDimitry Andric // Types spelled in the prefix part of the declarator. 1115ffd83dbSDimitry Andric SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) { 1125ffd83dbSDimitry Andric return HandlePointer(T); 1135ffd83dbSDimitry Andric } 1145ffd83dbSDimitry Andric 1155ffd83dbSDimitry Andric SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) { 1165ffd83dbSDimitry Andric return HandlePointer(T); 1175ffd83dbSDimitry Andric } 1185ffd83dbSDimitry Andric 1195ffd83dbSDimitry Andric SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) { 1205ffd83dbSDimitry Andric return HandlePointer(T); 1215ffd83dbSDimitry Andric } 1225ffd83dbSDimitry Andric 1235ffd83dbSDimitry Andric SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) { 1245ffd83dbSDimitry Andric return HandlePointer(T); 1255ffd83dbSDimitry Andric } 1265ffd83dbSDimitry Andric 1275ffd83dbSDimitry Andric SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) { 1285ffd83dbSDimitry Andric return HandlePointer(T); 1295ffd83dbSDimitry Andric } 1305ffd83dbSDimitry Andric 1315ffd83dbSDimitry Andric // All other cases are not important, as they are either part of declaration 1325ffd83dbSDimitry Andric // specifiers (e.g. inheritors of TypeSpecTypeLoc) or introduce modifiers on 1335ffd83dbSDimitry Andric // existing declarators (e.g. QualifiedTypeLoc). They cannot start the 1345ffd83dbSDimitry Andric // declarator themselves, but their underlying type can. 1355ffd83dbSDimitry Andric SourceLocation VisitTypeLoc(TypeLoc T) { 1365ffd83dbSDimitry Andric auto N = T.getNextTypeLoc(); 1375ffd83dbSDimitry Andric if (!N) 1385ffd83dbSDimitry Andric return SourceLocation(); 1395ffd83dbSDimitry Andric return Visit(N); 1405ffd83dbSDimitry Andric } 1415ffd83dbSDimitry Andric 1425ffd83dbSDimitry Andric SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) { 1435ffd83dbSDimitry Andric if (T.getTypePtr()->hasTrailingReturn()) 1445ffd83dbSDimitry Andric return SourceLocation(); // avoid recursing into the suffix of declarator. 1455ffd83dbSDimitry Andric return VisitTypeLoc(T); 1465ffd83dbSDimitry Andric } 1475ffd83dbSDimitry Andric 1485ffd83dbSDimitry Andric private: 1495ffd83dbSDimitry Andric template <class PtrLoc> SourceLocation HandlePointer(PtrLoc T) { 1505ffd83dbSDimitry Andric auto L = Visit(T.getPointeeLoc()); 1515ffd83dbSDimitry Andric if (L.isValid()) 1525ffd83dbSDimitry Andric return L; 1535ffd83dbSDimitry Andric return T.getLocalSourceRange().getBegin(); 1545ffd83dbSDimitry Andric } 1555ffd83dbSDimitry Andric }; 1565ffd83dbSDimitry Andric } // namespace 1575ffd83dbSDimitry Andric 158e8d8bef9SDimitry Andric static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args) { 159349cc55cSDimitry Andric auto FirstDefaultArg = 160349cc55cSDimitry Andric llvm::find_if(Args, [](auto It) { return isa<CXXDefaultArgExpr>(It); }); 161e8d8bef9SDimitry Andric return llvm::make_range(Args.begin(), FirstDefaultArg); 162e8d8bef9SDimitry Andric } 163e8d8bef9SDimitry Andric 1645ffd83dbSDimitry Andric static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) { 1655ffd83dbSDimitry Andric switch (E.getOperator()) { 1665ffd83dbSDimitry Andric // Comparison 1675ffd83dbSDimitry Andric case OO_EqualEqual: 1685ffd83dbSDimitry Andric case OO_ExclaimEqual: 1695ffd83dbSDimitry Andric case OO_Greater: 1705ffd83dbSDimitry Andric case OO_GreaterEqual: 1715ffd83dbSDimitry Andric case OO_Less: 1725ffd83dbSDimitry Andric case OO_LessEqual: 1735ffd83dbSDimitry Andric case OO_Spaceship: 1745ffd83dbSDimitry Andric // Assignment 1755ffd83dbSDimitry Andric case OO_Equal: 1765ffd83dbSDimitry Andric case OO_SlashEqual: 1775ffd83dbSDimitry Andric case OO_PercentEqual: 1785ffd83dbSDimitry Andric case OO_CaretEqual: 1795ffd83dbSDimitry Andric case OO_PipeEqual: 1805ffd83dbSDimitry Andric case OO_LessLessEqual: 1815ffd83dbSDimitry Andric case OO_GreaterGreaterEqual: 1825ffd83dbSDimitry Andric case OO_PlusEqual: 1835ffd83dbSDimitry Andric case OO_MinusEqual: 1845ffd83dbSDimitry Andric case OO_StarEqual: 1855ffd83dbSDimitry Andric case OO_AmpEqual: 1865ffd83dbSDimitry Andric // Binary computation 1875ffd83dbSDimitry Andric case OO_Slash: 1885ffd83dbSDimitry Andric case OO_Percent: 1895ffd83dbSDimitry Andric case OO_Caret: 1905ffd83dbSDimitry Andric case OO_Pipe: 1915ffd83dbSDimitry Andric case OO_LessLess: 1925ffd83dbSDimitry Andric case OO_GreaterGreater: 1935ffd83dbSDimitry Andric case OO_AmpAmp: 1945ffd83dbSDimitry Andric case OO_PipePipe: 1955ffd83dbSDimitry Andric case OO_ArrowStar: 1965ffd83dbSDimitry Andric case OO_Comma: 1975ffd83dbSDimitry Andric return syntax::NodeKind::BinaryOperatorExpression; 1985ffd83dbSDimitry Andric case OO_Tilde: 1995ffd83dbSDimitry Andric case OO_Exclaim: 2005ffd83dbSDimitry Andric return syntax::NodeKind::PrefixUnaryOperatorExpression; 2015ffd83dbSDimitry Andric // Prefix/Postfix increment/decrement 2025ffd83dbSDimitry Andric case OO_PlusPlus: 2035ffd83dbSDimitry Andric case OO_MinusMinus: 2045ffd83dbSDimitry Andric switch (E.getNumArgs()) { 2055ffd83dbSDimitry Andric case 1: 2065ffd83dbSDimitry Andric return syntax::NodeKind::PrefixUnaryOperatorExpression; 2075ffd83dbSDimitry Andric case 2: 2085ffd83dbSDimitry Andric return syntax::NodeKind::PostfixUnaryOperatorExpression; 2095ffd83dbSDimitry Andric default: 2105ffd83dbSDimitry Andric llvm_unreachable("Invalid number of arguments for operator"); 2115ffd83dbSDimitry Andric } 2125ffd83dbSDimitry Andric // Operators that can be unary or binary 2135ffd83dbSDimitry Andric case OO_Plus: 2145ffd83dbSDimitry Andric case OO_Minus: 2155ffd83dbSDimitry Andric case OO_Star: 2165ffd83dbSDimitry Andric case OO_Amp: 2175ffd83dbSDimitry Andric switch (E.getNumArgs()) { 2185ffd83dbSDimitry Andric case 1: 2195ffd83dbSDimitry Andric return syntax::NodeKind::PrefixUnaryOperatorExpression; 2205ffd83dbSDimitry Andric case 2: 2215ffd83dbSDimitry Andric return syntax::NodeKind::BinaryOperatorExpression; 2225ffd83dbSDimitry Andric default: 2235ffd83dbSDimitry Andric llvm_unreachable("Invalid number of arguments for operator"); 2245ffd83dbSDimitry Andric } 2255ffd83dbSDimitry Andric return syntax::NodeKind::BinaryOperatorExpression; 2265ffd83dbSDimitry Andric // Not yet supported by SyntaxTree 2275ffd83dbSDimitry Andric case OO_New: 2285ffd83dbSDimitry Andric case OO_Delete: 2295ffd83dbSDimitry Andric case OO_Array_New: 2305ffd83dbSDimitry Andric case OO_Array_Delete: 2315ffd83dbSDimitry Andric case OO_Coawait: 2325ffd83dbSDimitry Andric case OO_Subscript: 2335ffd83dbSDimitry Andric case OO_Arrow: 2345ffd83dbSDimitry Andric return syntax::NodeKind::UnknownExpression; 235e8d8bef9SDimitry Andric case OO_Call: 236e8d8bef9SDimitry Andric return syntax::NodeKind::CallExpression; 2375ffd83dbSDimitry Andric case OO_Conditional: // not overloadable 2385ffd83dbSDimitry Andric case NUM_OVERLOADED_OPERATORS: 2395ffd83dbSDimitry Andric case OO_None: 2405ffd83dbSDimitry Andric llvm_unreachable("Not an overloadable operator"); 2415ffd83dbSDimitry Andric } 2425ffd83dbSDimitry Andric llvm_unreachable("Unknown OverloadedOperatorKind enum"); 2435ffd83dbSDimitry Andric } 2445ffd83dbSDimitry Andric 245e8d8bef9SDimitry Andric /// Get the start of the qualified name. In the examples below it gives the 246e8d8bef9SDimitry Andric /// location of the `^`: 247e8d8bef9SDimitry Andric /// `int ^a;` 248e8d8bef9SDimitry Andric /// `int *^a;` 249e8d8bef9SDimitry Andric /// `int ^a::S::f(){}` 250e8d8bef9SDimitry Andric static SourceLocation getQualifiedNameStart(NamedDecl *D) { 251e8d8bef9SDimitry Andric assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) && 252e8d8bef9SDimitry Andric "only DeclaratorDecl and TypedefNameDecl are supported."); 253e8d8bef9SDimitry Andric 254e8d8bef9SDimitry Andric auto DN = D->getDeclName(); 255e8d8bef9SDimitry Andric bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo(); 256e8d8bef9SDimitry Andric if (IsAnonymous) 257e8d8bef9SDimitry Andric return SourceLocation(); 258e8d8bef9SDimitry Andric 259e8d8bef9SDimitry Andric if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) { 260e8d8bef9SDimitry Andric if (DD->getQualifierLoc()) { 261e8d8bef9SDimitry Andric return DD->getQualifierLoc().getBeginLoc(); 262e8d8bef9SDimitry Andric } 263e8d8bef9SDimitry Andric } 264e8d8bef9SDimitry Andric 265e8d8bef9SDimitry Andric return D->getLocation(); 266e8d8bef9SDimitry Andric } 267e8d8bef9SDimitry Andric 268e8d8bef9SDimitry Andric /// Gets the range of the initializer inside an init-declarator C++ [dcl.decl]. 269e8d8bef9SDimitry Andric /// `int a;` -> range of ``, 270e8d8bef9SDimitry Andric /// `int *a = nullptr` -> range of `= nullptr`. 271e8d8bef9SDimitry Andric /// `int a{}` -> range of `{}`. 272e8d8bef9SDimitry Andric /// `int a()` -> range of `()`. 273e8d8bef9SDimitry Andric static SourceRange getInitializerRange(Decl *D) { 274e8d8bef9SDimitry Andric if (auto *V = dyn_cast<VarDecl>(D)) { 275e8d8bef9SDimitry Andric auto *I = V->getInit(); 276e8d8bef9SDimitry Andric // Initializers in range-based-for are not part of the declarator 277e8d8bef9SDimitry Andric if (I && !V->isCXXForRangeDecl()) 278e8d8bef9SDimitry Andric return I->getSourceRange(); 279e8d8bef9SDimitry Andric } 280e8d8bef9SDimitry Andric 281e8d8bef9SDimitry Andric return SourceRange(); 282e8d8bef9SDimitry Andric } 283e8d8bef9SDimitry Andric 2845ffd83dbSDimitry Andric /// Gets the range of declarator as defined by the C++ grammar. E.g. 2855ffd83dbSDimitry Andric /// `int a;` -> range of `a`, 2865ffd83dbSDimitry Andric /// `int *a;` -> range of `*a`, 2875ffd83dbSDimitry Andric /// `int a[10];` -> range of `a[10]`, 2885ffd83dbSDimitry Andric /// `int a[1][2][3];` -> range of `a[1][2][3]`, 2895ffd83dbSDimitry Andric /// `int *a = nullptr` -> range of `*a = nullptr`. 290e8d8bef9SDimitry Andric /// `int S::f(){}` -> range of `S::f()`. 291e8d8bef9SDimitry Andric /// FIXME: \p Name must be a source range. 2925ffd83dbSDimitry Andric static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T, 2935ffd83dbSDimitry Andric SourceLocation Name, 2945ffd83dbSDimitry Andric SourceRange Initializer) { 2955ffd83dbSDimitry Andric SourceLocation Start = GetStartLoc().Visit(T); 296e8d8bef9SDimitry Andric SourceLocation End = T.getEndLoc(); 2975ffd83dbSDimitry Andric if (Name.isValid()) { 2985ffd83dbSDimitry Andric if (Start.isInvalid()) 2995ffd83dbSDimitry Andric Start = Name; 300fe6060f1SDimitry Andric // End of TypeLoc could be invalid if the type is invalid, fallback to the 301fe6060f1SDimitry Andric // NameLoc. 302fe6060f1SDimitry Andric if (End.isInvalid() || SM.isBeforeInTranslationUnit(End, Name)) 3035ffd83dbSDimitry Andric End = Name; 3045ffd83dbSDimitry Andric } 3055ffd83dbSDimitry Andric if (Initializer.isValid()) { 3065ffd83dbSDimitry Andric auto InitializerEnd = Initializer.getEnd(); 3075ffd83dbSDimitry Andric assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) || 3085ffd83dbSDimitry Andric End == InitializerEnd); 3095ffd83dbSDimitry Andric End = InitializerEnd; 3105ffd83dbSDimitry Andric } 3115ffd83dbSDimitry Andric return SourceRange(Start, End); 3125ffd83dbSDimitry Andric } 3135ffd83dbSDimitry Andric 3145ffd83dbSDimitry Andric namespace { 3155ffd83dbSDimitry Andric /// All AST hierarchy roots that can be represented as pointers. 3165ffd83dbSDimitry Andric using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>; 3175ffd83dbSDimitry Andric /// Maintains a mapping from AST to syntax tree nodes. This class will get more 3185ffd83dbSDimitry Andric /// complicated as we support more kinds of AST nodes, e.g. TypeLocs. 3195ffd83dbSDimitry Andric /// FIXME: expose this as public API. 3205ffd83dbSDimitry Andric class ASTToSyntaxMapping { 3215ffd83dbSDimitry Andric public: 3225ffd83dbSDimitry Andric void add(ASTPtr From, syntax::Tree *To) { 3235ffd83dbSDimitry Andric assert(To != nullptr); 3245ffd83dbSDimitry Andric assert(!From.isNull()); 3255ffd83dbSDimitry Andric 3265ffd83dbSDimitry Andric bool Added = Nodes.insert({From, To}).second; 3275ffd83dbSDimitry Andric (void)Added; 3285ffd83dbSDimitry Andric assert(Added && "mapping added twice"); 3295ffd83dbSDimitry Andric } 3305ffd83dbSDimitry Andric 331e8d8bef9SDimitry Andric void add(NestedNameSpecifierLoc From, syntax::Tree *To) { 332e8d8bef9SDimitry Andric assert(To != nullptr); 333e8d8bef9SDimitry Andric assert(From.hasQualifier()); 334e8d8bef9SDimitry Andric 335e8d8bef9SDimitry Andric bool Added = NNSNodes.insert({From, To}).second; 336e8d8bef9SDimitry Andric (void)Added; 337e8d8bef9SDimitry Andric assert(Added && "mapping added twice"); 338e8d8bef9SDimitry Andric } 339e8d8bef9SDimitry Andric 3405ffd83dbSDimitry Andric syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); } 3415ffd83dbSDimitry Andric 342e8d8bef9SDimitry Andric syntax::Tree *find(NestedNameSpecifierLoc P) const { 343e8d8bef9SDimitry Andric return NNSNodes.lookup(P); 344e8d8bef9SDimitry Andric } 345e8d8bef9SDimitry Andric 3465ffd83dbSDimitry Andric private: 3475ffd83dbSDimitry Andric llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes; 348e8d8bef9SDimitry Andric llvm::DenseMap<NestedNameSpecifierLoc, syntax::Tree *> NNSNodes; 3495ffd83dbSDimitry Andric }; 3505ffd83dbSDimitry Andric } // namespace 3515ffd83dbSDimitry Andric 3520b57cec5SDimitry Andric /// A helper class for constructing the syntax tree while traversing a clang 3530b57cec5SDimitry Andric /// AST. 3540b57cec5SDimitry Andric /// 3550b57cec5SDimitry Andric /// At each point of the traversal we maintain a list of pending nodes. 3560b57cec5SDimitry Andric /// Initially all tokens are added as pending nodes. When processing a clang AST 3570b57cec5SDimitry Andric /// node, the clients need to: 3580b57cec5SDimitry Andric /// - create a corresponding syntax node, 3590b57cec5SDimitry Andric /// - assign roles to all pending child nodes with 'markChild' and 3600b57cec5SDimitry Andric /// 'markChildToken', 3610b57cec5SDimitry Andric /// - replace the child nodes with the new syntax node in the pending list 3620b57cec5SDimitry Andric /// with 'foldNode'. 3630b57cec5SDimitry Andric /// 3640b57cec5SDimitry Andric /// Note that all children are expected to be processed when building a node. 3650b57cec5SDimitry Andric /// 3660b57cec5SDimitry Andric /// Call finalize() to finish building the tree and consume the root node. 3670b57cec5SDimitry Andric class syntax::TreeBuilder { 3680b57cec5SDimitry Andric public: 369fcaf7f86SDimitry Andric TreeBuilder(syntax::Arena &Arena, TokenBufferTokenManager& TBTM) 370fcaf7f86SDimitry Andric : Arena(Arena), 371fcaf7f86SDimitry Andric TBTM(TBTM), 372fcaf7f86SDimitry Andric Pending(Arena, TBTM.tokenBuffer()) { 373fcaf7f86SDimitry Andric for (const auto &T : TBTM.tokenBuffer().expandedTokens()) 374e8d8bef9SDimitry Andric LocationToToken.insert({T.location(), &T}); 375480093f4SDimitry Andric } 3760b57cec5SDimitry Andric 377e8d8bef9SDimitry Andric llvm::BumpPtrAllocator &allocator() { return Arena.getAllocator(); } 378e8d8bef9SDimitry Andric const SourceManager &sourceManager() const { 379fcaf7f86SDimitry Andric return TBTM.sourceManager(); 380e8d8bef9SDimitry Andric } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric /// Populate children for \p New node, assuming it covers tokens from \p 3830b57cec5SDimitry Andric /// Range. 384e8d8bef9SDimitry Andric void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, ASTPtr From) { 3855ffd83dbSDimitry Andric assert(New); 386fcaf7f86SDimitry Andric Pending.foldChildren(TBTM.tokenBuffer(), Range, New); 3875ffd83dbSDimitry Andric if (From) 3885ffd83dbSDimitry Andric Mapping.add(From, New); 3895ffd83dbSDimitry Andric } 390e8d8bef9SDimitry Andric 391e8d8bef9SDimitry Andric void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, TypeLoc L) { 3925ffd83dbSDimitry Andric // FIXME: add mapping for TypeLocs 3935ffd83dbSDimitry Andric foldNode(Range, New, nullptr); 3945ffd83dbSDimitry Andric } 395480093f4SDimitry Andric 396e8d8bef9SDimitry Andric void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New, 397e8d8bef9SDimitry Andric NestedNameSpecifierLoc From) { 398e8d8bef9SDimitry Andric assert(New); 399fcaf7f86SDimitry Andric Pending.foldChildren(TBTM.tokenBuffer(), Range, New); 400e8d8bef9SDimitry Andric if (From) 401e8d8bef9SDimitry Andric Mapping.add(From, New); 402e8d8bef9SDimitry Andric } 403e8d8bef9SDimitry Andric 404e8d8bef9SDimitry Andric /// Populate children for \p New list, assuming it covers tokens from a 405e8d8bef9SDimitry Andric /// subrange of \p SuperRange. 406e8d8bef9SDimitry Andric void foldList(ArrayRef<syntax::Token> SuperRange, syntax::List *New, 407e8d8bef9SDimitry Andric ASTPtr From) { 408e8d8bef9SDimitry Andric assert(New); 409e8d8bef9SDimitry Andric auto ListRange = Pending.shrinkToFitList(SuperRange); 410fcaf7f86SDimitry Andric Pending.foldChildren(TBTM.tokenBuffer(), ListRange, New); 411e8d8bef9SDimitry Andric if (From) 412e8d8bef9SDimitry Andric Mapping.add(From, New); 413e8d8bef9SDimitry Andric } 414e8d8bef9SDimitry Andric 415480093f4SDimitry Andric /// Notifies that we should not consume trailing semicolon when computing 416480093f4SDimitry Andric /// token range of \p D. 4175ffd83dbSDimitry Andric void noticeDeclWithoutSemicolon(Decl *D); 418480093f4SDimitry Andric 419480093f4SDimitry Andric /// Mark the \p Child node with a corresponding \p Role. All marked children 420480093f4SDimitry Andric /// should be consumed by foldNode. 4215ffd83dbSDimitry Andric /// When called on expressions (clang::Expr is derived from clang::Stmt), 422480093f4SDimitry Andric /// wraps expressions into expression statement. 423480093f4SDimitry Andric void markStmtChild(Stmt *Child, NodeRole Role); 424480093f4SDimitry Andric /// Should be called for expressions in non-statement position to avoid 425480093f4SDimitry Andric /// wrapping into expression statement. 426480093f4SDimitry Andric void markExprChild(Expr *Child, NodeRole Role); 4270b57cec5SDimitry Andric /// Set role for a token starting at \p Loc. 428480093f4SDimitry Andric void markChildToken(SourceLocation Loc, NodeRole R); 4295ffd83dbSDimitry Andric /// Set role for \p T. 4305ffd83dbSDimitry Andric void markChildToken(const syntax::Token *T, NodeRole R); 4315ffd83dbSDimitry Andric 4325ffd83dbSDimitry Andric /// Set role for \p N. 4335ffd83dbSDimitry Andric void markChild(syntax::Node *N, NodeRole R); 4345ffd83dbSDimitry Andric /// Set role for the syntax node matching \p N. 4355ffd83dbSDimitry Andric void markChild(ASTPtr N, NodeRole R); 436e8d8bef9SDimitry Andric /// Set role for the syntax node matching \p N. 437e8d8bef9SDimitry Andric void markChild(NestedNameSpecifierLoc N, NodeRole R); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric /// Finish building the tree and consume the root node. 4400b57cec5SDimitry Andric syntax::TranslationUnit *finalize() && { 441fcaf7f86SDimitry Andric auto Tokens = TBTM.tokenBuffer().expandedTokens(); 442a7dea167SDimitry Andric assert(!Tokens.empty()); 443a7dea167SDimitry Andric assert(Tokens.back().kind() == tok::eof); 444a7dea167SDimitry Andric 4450b57cec5SDimitry Andric // Build the root of the tree, consuming all the children. 446fcaf7f86SDimitry Andric Pending.foldChildren(TBTM.tokenBuffer(), Tokens.drop_back(), 447e8d8bef9SDimitry Andric new (Arena.getAllocator()) syntax::TranslationUnit); 4480b57cec5SDimitry Andric 449480093f4SDimitry Andric auto *TU = cast<syntax::TranslationUnit>(std::move(Pending).finalize()); 450480093f4SDimitry Andric TU->assertInvariantsRecursive(); 451480093f4SDimitry Andric return TU; 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4545ffd83dbSDimitry Andric /// Finds a token starting at \p L. The token must exist if \p L is valid. 4555ffd83dbSDimitry Andric const syntax::Token *findToken(SourceLocation L) const; 4565ffd83dbSDimitry Andric 4575ffd83dbSDimitry Andric /// Finds the syntax tokens corresponding to the \p SourceRange. 458e8d8bef9SDimitry Andric ArrayRef<syntax::Token> getRange(SourceRange Range) const { 4595ffd83dbSDimitry Andric assert(Range.isValid()); 4605ffd83dbSDimitry Andric return getRange(Range.getBegin(), Range.getEnd()); 4615ffd83dbSDimitry Andric } 4625ffd83dbSDimitry Andric 4635ffd83dbSDimitry Andric /// Finds the syntax tokens corresponding to the passed source locations. 4640b57cec5SDimitry Andric /// \p First is the start position of the first token and \p Last is the start 4650b57cec5SDimitry Andric /// position of the last token. 466e8d8bef9SDimitry Andric ArrayRef<syntax::Token> getRange(SourceLocation First, 4670b57cec5SDimitry Andric SourceLocation Last) const { 4680b57cec5SDimitry Andric assert(First.isValid()); 4690b57cec5SDimitry Andric assert(Last.isValid()); 4700b57cec5SDimitry Andric assert(First == Last || 471fcaf7f86SDimitry Andric TBTM.sourceManager().isBeforeInTranslationUnit(First, Last)); 472bdd1243dSDimitry Andric return llvm::ArrayRef(findToken(First), std::next(findToken(Last))); 4730b57cec5SDimitry Andric } 4745ffd83dbSDimitry Andric 475e8d8bef9SDimitry Andric ArrayRef<syntax::Token> 4765ffd83dbSDimitry Andric getTemplateRange(const ClassTemplateSpecializationDecl *D) const { 4775ffd83dbSDimitry Andric auto Tokens = getRange(D->getSourceRange()); 4785ffd83dbSDimitry Andric return maybeAppendSemicolon(Tokens, D); 4790b57cec5SDimitry Andric } 4805ffd83dbSDimitry Andric 4815ffd83dbSDimitry Andric /// Returns true if \p D is the last declarator in a chain and is thus 4825ffd83dbSDimitry Andric /// reponsible for creating SimpleDeclaration for the whole chain. 483e8d8bef9SDimitry Andric bool isResponsibleForCreatingDeclaration(const Decl *D) const { 484e8d8bef9SDimitry Andric assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) && 4855ffd83dbSDimitry Andric "only DeclaratorDecl and TypedefNameDecl are supported."); 4865ffd83dbSDimitry Andric 4875ffd83dbSDimitry Andric const Decl *Next = D->getNextDeclInContext(); 4885ffd83dbSDimitry Andric 4895ffd83dbSDimitry Andric // There's no next sibling, this one is responsible. 4905ffd83dbSDimitry Andric if (Next == nullptr) { 4915ffd83dbSDimitry Andric return true; 4925ffd83dbSDimitry Andric } 4935ffd83dbSDimitry Andric 4945ffd83dbSDimitry Andric // Next sibling is not the same type, this one is responsible. 495e8d8bef9SDimitry Andric if (D->getKind() != Next->getKind()) { 4965ffd83dbSDimitry Andric return true; 4975ffd83dbSDimitry Andric } 4985ffd83dbSDimitry Andric // Next sibling doesn't begin at the same loc, it must be a different 4995ffd83dbSDimitry Andric // declaration, so this declarator is responsible. 500e8d8bef9SDimitry Andric if (Next->getBeginLoc() != D->getBeginLoc()) { 5015ffd83dbSDimitry Andric return true; 5025ffd83dbSDimitry Andric } 5035ffd83dbSDimitry Andric 5045ffd83dbSDimitry Andric // NextT is a member of the same declaration, and we need the last member to 5055ffd83dbSDimitry Andric // create declaration. This one is not responsible. 5065ffd83dbSDimitry Andric return false; 5075ffd83dbSDimitry Andric } 5085ffd83dbSDimitry Andric 509e8d8bef9SDimitry Andric ArrayRef<syntax::Token> getDeclarationRange(Decl *D) { 510e8d8bef9SDimitry Andric ArrayRef<syntax::Token> Tokens; 5115ffd83dbSDimitry Andric // We want to drop the template parameters for specializations. 512e8d8bef9SDimitry Andric if (const auto *S = dyn_cast<TagDecl>(D)) 5135ffd83dbSDimitry Andric Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc()); 5145ffd83dbSDimitry Andric else 5155ffd83dbSDimitry Andric Tokens = getRange(D->getSourceRange()); 5165ffd83dbSDimitry Andric return maybeAppendSemicolon(Tokens, D); 5175ffd83dbSDimitry Andric } 5185ffd83dbSDimitry Andric 519e8d8bef9SDimitry Andric ArrayRef<syntax::Token> getExprRange(const Expr *E) const { 5205ffd83dbSDimitry Andric return getRange(E->getSourceRange()); 521480093f4SDimitry Andric } 5225ffd83dbSDimitry Andric 523480093f4SDimitry Andric /// Find the adjusted range for the statement, consuming the trailing 524480093f4SDimitry Andric /// semicolon when needed. 525e8d8bef9SDimitry Andric ArrayRef<syntax::Token> getStmtRange(const Stmt *S) const { 5265ffd83dbSDimitry Andric auto Tokens = getRange(S->getSourceRange()); 527480093f4SDimitry Andric if (isa<CompoundStmt>(S)) 528480093f4SDimitry Andric return Tokens; 529480093f4SDimitry Andric 530480093f4SDimitry Andric // Some statements miss a trailing semicolon, e.g. 'return', 'continue' and 531480093f4SDimitry Andric // all statements that end with those. Consume this semicolon here. 532480093f4SDimitry Andric if (Tokens.back().kind() == tok::semi) 533480093f4SDimitry Andric return Tokens; 534480093f4SDimitry Andric return withTrailingSemicolon(Tokens); 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric private: 538e8d8bef9SDimitry Andric ArrayRef<syntax::Token> maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens, 5395ffd83dbSDimitry Andric const Decl *D) const { 540e8d8bef9SDimitry Andric if (isa<NamespaceDecl>(D)) 5415ffd83dbSDimitry Andric return Tokens; 5425ffd83dbSDimitry Andric if (DeclsWithoutSemicolons.count(D)) 5435ffd83dbSDimitry Andric return Tokens; 5445ffd83dbSDimitry Andric // FIXME: do not consume trailing semicolon on function definitions. 5455ffd83dbSDimitry Andric // Most declarations own a semicolon in syntax trees, but not in clang AST. 5465ffd83dbSDimitry Andric return withTrailingSemicolon(Tokens); 5475ffd83dbSDimitry Andric } 5485ffd83dbSDimitry Andric 549e8d8bef9SDimitry Andric ArrayRef<syntax::Token> 550e8d8bef9SDimitry Andric withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const { 551480093f4SDimitry Andric assert(!Tokens.empty()); 552480093f4SDimitry Andric assert(Tokens.back().kind() != tok::eof); 5535ffd83dbSDimitry Andric // We never consume 'eof', so looking at the next token is ok. 554480093f4SDimitry Andric if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi) 555bdd1243dSDimitry Andric return llvm::ArrayRef(Tokens.begin(), Tokens.end() + 1); 556480093f4SDimitry Andric return Tokens; 557480093f4SDimitry Andric } 558480093f4SDimitry Andric 5595ffd83dbSDimitry Andric void setRole(syntax::Node *N, NodeRole R) { 560e8d8bef9SDimitry Andric assert(N->getRole() == NodeRole::Detached); 5615ffd83dbSDimitry Andric N->setRole(R); 5625ffd83dbSDimitry Andric } 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric /// A collection of trees covering the input tokens. 5650b57cec5SDimitry Andric /// When created, each tree corresponds to a single token in the file. 5660b57cec5SDimitry Andric /// Clients call 'foldChildren' to attach one or more subtrees to a parent 5670b57cec5SDimitry Andric /// node and update the list of trees accordingly. 5680b57cec5SDimitry Andric /// 5690b57cec5SDimitry Andric /// Ensures that added nodes properly nest and cover the whole token stream. 5700b57cec5SDimitry Andric struct Forest { 571fcaf7f86SDimitry Andric Forest(syntax::Arena &A, const syntax::TokenBuffer &TB) { 572fcaf7f86SDimitry Andric assert(!TB.expandedTokens().empty()); 573fcaf7f86SDimitry Andric assert(TB.expandedTokens().back().kind() == tok::eof); 5740b57cec5SDimitry Andric // Create all leaf nodes. 575a7dea167SDimitry Andric // Note that we do not have 'eof' in the tree. 576fcaf7f86SDimitry Andric for (const auto &T : TB.expandedTokens().drop_back()) { 577fcaf7f86SDimitry Andric auto *L = new (A.getAllocator()) 578fcaf7f86SDimitry Andric syntax::Leaf(reinterpret_cast<TokenManager::Key>(&T)); 579480093f4SDimitry Andric L->Original = true; 580fcaf7f86SDimitry Andric L->CanModify = TB.spelledForExpanded(T).has_value(); 5815ffd83dbSDimitry Andric Trees.insert(Trees.end(), {&T, L}); 5820b57cec5SDimitry Andric } 583480093f4SDimitry Andric } 584480093f4SDimitry Andric 585e8d8bef9SDimitry Andric void assignRole(ArrayRef<syntax::Token> Range, syntax::NodeRole Role) { 5860b57cec5SDimitry Andric assert(!Range.empty()); 5870b57cec5SDimitry Andric auto It = Trees.lower_bound(Range.begin()); 5880b57cec5SDimitry Andric assert(It != Trees.end() && "no node found"); 5890b57cec5SDimitry Andric assert(It->first == Range.begin() && "no child with the specified range"); 5900b57cec5SDimitry Andric assert((std::next(It) == Trees.end() || 5910b57cec5SDimitry Andric std::next(It)->first == Range.end()) && 5920b57cec5SDimitry Andric "no child with the specified range"); 593e8d8bef9SDimitry Andric assert(It->second->getRole() == NodeRole::Detached && 5945ffd83dbSDimitry Andric "re-assigning role for a child"); 5955ffd83dbSDimitry Andric It->second->setRole(Role); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 598e8d8bef9SDimitry Andric /// Shrink \p Range to a subrange that only contains tokens of a list. 599e8d8bef9SDimitry Andric /// List elements and delimiters should already have correct roles. 600e8d8bef9SDimitry Andric ArrayRef<syntax::Token> shrinkToFitList(ArrayRef<syntax::Token> Range) { 601e8d8bef9SDimitry Andric auto BeginChildren = Trees.lower_bound(Range.begin()); 602e8d8bef9SDimitry Andric assert((BeginChildren == Trees.end() || 603e8d8bef9SDimitry Andric BeginChildren->first == Range.begin()) && 604e8d8bef9SDimitry Andric "Range crosses boundaries of existing subtrees"); 605e8d8bef9SDimitry Andric 606e8d8bef9SDimitry Andric auto EndChildren = Trees.lower_bound(Range.end()); 607e8d8bef9SDimitry Andric assert( 608e8d8bef9SDimitry Andric (EndChildren == Trees.end() || EndChildren->first == Range.end()) && 609e8d8bef9SDimitry Andric "Range crosses boundaries of existing subtrees"); 610e8d8bef9SDimitry Andric 611e8d8bef9SDimitry Andric auto BelongsToList = [](decltype(Trees)::value_type KV) { 612e8d8bef9SDimitry Andric auto Role = KV.second->getRole(); 613e8d8bef9SDimitry Andric return Role == syntax::NodeRole::ListElement || 614e8d8bef9SDimitry Andric Role == syntax::NodeRole::ListDelimiter; 615e8d8bef9SDimitry Andric }; 616e8d8bef9SDimitry Andric 617e8d8bef9SDimitry Andric auto BeginListChildren = 618e8d8bef9SDimitry Andric std::find_if(BeginChildren, EndChildren, BelongsToList); 619e8d8bef9SDimitry Andric 620e8d8bef9SDimitry Andric auto EndListChildren = 621e8d8bef9SDimitry Andric std::find_if_not(BeginListChildren, EndChildren, BelongsToList); 622e8d8bef9SDimitry Andric 623e8d8bef9SDimitry Andric return ArrayRef<syntax::Token>(BeginListChildren->first, 624e8d8bef9SDimitry Andric EndListChildren->first); 625e8d8bef9SDimitry Andric } 626e8d8bef9SDimitry Andric 627480093f4SDimitry Andric /// Add \p Node to the forest and attach child nodes based on \p Tokens. 628fcaf7f86SDimitry Andric void foldChildren(const syntax::TokenBuffer &TB, 629fcaf7f86SDimitry Andric ArrayRef<syntax::Token> Tokens, syntax::Tree *Node) { 630480093f4SDimitry Andric // Attach children to `Node`. 631e8d8bef9SDimitry Andric assert(Node->getFirstChild() == nullptr && "node already has children"); 6325ffd83dbSDimitry Andric 6335ffd83dbSDimitry Andric auto *FirstToken = Tokens.begin(); 6345ffd83dbSDimitry Andric auto BeginChildren = Trees.lower_bound(FirstToken); 6355ffd83dbSDimitry Andric 6365ffd83dbSDimitry Andric assert((BeginChildren == Trees.end() || 6375ffd83dbSDimitry Andric BeginChildren->first == FirstToken) && 6385ffd83dbSDimitry Andric "fold crosses boundaries of existing subtrees"); 6395ffd83dbSDimitry Andric auto EndChildren = Trees.lower_bound(Tokens.end()); 6405ffd83dbSDimitry Andric assert( 6415ffd83dbSDimitry Andric (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) && 6425ffd83dbSDimitry Andric "fold crosses boundaries of existing subtrees"); 6435ffd83dbSDimitry Andric 644e8d8bef9SDimitry Andric for (auto It = BeginChildren; It != EndChildren; ++It) { 645e8d8bef9SDimitry Andric auto *C = It->second; 646e8d8bef9SDimitry Andric if (C->getRole() == NodeRole::Detached) 6475ffd83dbSDimitry Andric C->setRole(NodeRole::Unknown); 648e8d8bef9SDimitry Andric Node->appendChildLowLevel(C); 649480093f4SDimitry Andric } 6500b57cec5SDimitry Andric 6515ffd83dbSDimitry Andric // Mark that this node came from the AST and is backed by the source code. 6525ffd83dbSDimitry Andric Node->Original = true; 653e8d8bef9SDimitry Andric Node->CanModify = 654fcaf7f86SDimitry Andric TB.spelledForExpanded(Tokens).has_value(); 6550b57cec5SDimitry Andric 6565ffd83dbSDimitry Andric Trees.erase(BeginChildren, EndChildren); 6575ffd83dbSDimitry Andric Trees.insert({FirstToken, Node}); 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric // EXPECTS: all tokens were consumed and are owned by a single root node. 6610b57cec5SDimitry Andric syntax::Node *finalize() && { 6620b57cec5SDimitry Andric assert(Trees.size() == 1); 6635ffd83dbSDimitry Andric auto *Root = Trees.begin()->second; 6640b57cec5SDimitry Andric Trees = {}; 6650b57cec5SDimitry Andric return Root; 6660b57cec5SDimitry Andric } 6670b57cec5SDimitry Andric 668fcaf7f86SDimitry Andric std::string str(const syntax::TokenBufferTokenManager &STM) const { 6690b57cec5SDimitry Andric std::string R; 6700b57cec5SDimitry Andric for (auto It = Trees.begin(); It != Trees.end(); ++It) { 6710b57cec5SDimitry Andric unsigned CoveredTokens = 6720b57cec5SDimitry Andric It != Trees.end() 6730b57cec5SDimitry Andric ? (std::next(It)->first - It->first) 674fcaf7f86SDimitry Andric : STM.tokenBuffer().expandedTokens().end() - It->first; 6750b57cec5SDimitry Andric 676e8d8bef9SDimitry Andric R += std::string( 677e8d8bef9SDimitry Andric formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(), 678fcaf7f86SDimitry Andric It->first->text(STM.sourceManager()), CoveredTokens)); 679fcaf7f86SDimitry Andric R += It->second->dump(STM); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric return R; 6820b57cec5SDimitry Andric } 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric private: 6850b57cec5SDimitry Andric /// Maps from the start token to a subtree starting at that token. 686480093f4SDimitry Andric /// Keys in the map are pointers into the array of expanded tokens, so 687480093f4SDimitry Andric /// pointer order corresponds to the order of preprocessor tokens. 6885ffd83dbSDimitry Andric std::map<const syntax::Token *, syntax::Node *> Trees; 6890b57cec5SDimitry Andric }; 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric /// For debugging purposes. 692fcaf7f86SDimitry Andric std::string str() { return Pending.str(TBTM); } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric syntax::Arena &Arena; 695fcaf7f86SDimitry Andric TokenBufferTokenManager& TBTM; 696480093f4SDimitry Andric /// To quickly find tokens by their start location. 697e8d8bef9SDimitry Andric llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken; 6980b57cec5SDimitry Andric Forest Pending; 699480093f4SDimitry Andric llvm::DenseSet<Decl *> DeclsWithoutSemicolons; 7005ffd83dbSDimitry Andric ASTToSyntaxMapping Mapping; 7010b57cec5SDimitry Andric }; 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric namespace { 7040b57cec5SDimitry Andric class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> { 7050b57cec5SDimitry Andric public: 7065ffd83dbSDimitry Andric explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder) 7075ffd83dbSDimitry Andric : Builder(Builder), Context(Context) {} 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric bool shouldTraversePostOrder() const { return true; } 7100b57cec5SDimitry Andric 7115ffd83dbSDimitry Andric bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) { 7125ffd83dbSDimitry Andric return processDeclaratorAndDeclaration(DD); 713480093f4SDimitry Andric } 7145ffd83dbSDimitry Andric 7155ffd83dbSDimitry Andric bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) { 7165ffd83dbSDimitry Andric return processDeclaratorAndDeclaration(TD); 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric bool VisitDecl(Decl *D) { 7200b57cec5SDimitry Andric assert(!D->isImplicit()); 7215ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(D), 7225ffd83dbSDimitry Andric new (allocator()) syntax::UnknownDeclaration(), D); 7235ffd83dbSDimitry Andric return true; 7245ffd83dbSDimitry Andric } 7255ffd83dbSDimitry Andric 7265ffd83dbSDimitry Andric // RAV does not call WalkUpFrom* on explicit instantiations, so we have to 7275ffd83dbSDimitry Andric // override Traverse. 7285ffd83dbSDimitry Andric // FIXME: make RAV call WalkUpFrom* instead. 7295ffd83dbSDimitry Andric bool 7305ffd83dbSDimitry Andric TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) { 7315ffd83dbSDimitry Andric if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C)) 7325ffd83dbSDimitry Andric return false; 7335ffd83dbSDimitry Andric if (C->isExplicitSpecialization()) 7345ffd83dbSDimitry Andric return true; // we are only interested in explicit instantiations. 7355ffd83dbSDimitry Andric auto *Declaration = 7365ffd83dbSDimitry Andric cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C)); 7375ffd83dbSDimitry Andric foldExplicitTemplateInstantiation( 738*0fca6ea1SDimitry Andric Builder.getTemplateRange(C), 739*0fca6ea1SDimitry Andric Builder.findToken(C->getExternKeywordLoc()), 7405ffd83dbSDimitry Andric Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C); 7415ffd83dbSDimitry Andric return true; 7425ffd83dbSDimitry Andric } 7435ffd83dbSDimitry Andric 7445ffd83dbSDimitry Andric bool WalkUpFromTemplateDecl(TemplateDecl *S) { 7455ffd83dbSDimitry Andric foldTemplateDeclaration( 7465ffd83dbSDimitry Andric Builder.getDeclarationRange(S), 7475ffd83dbSDimitry Andric Builder.findToken(S->getTemplateParameters()->getTemplateLoc()), 7485ffd83dbSDimitry Andric Builder.getDeclarationRange(S->getTemplatedDecl()), S); 749480093f4SDimitry Andric return true; 750480093f4SDimitry Andric } 751480093f4SDimitry Andric 752480093f4SDimitry Andric bool WalkUpFromTagDecl(TagDecl *C) { 753480093f4SDimitry Andric // FIXME: build the ClassSpecifier node. 7545ffd83dbSDimitry Andric if (!C->isFreeStanding()) { 7555ffd83dbSDimitry Andric assert(C->getNumTemplateParameterLists() == 0); 756480093f4SDimitry Andric return true; 757480093f4SDimitry Andric } 7585ffd83dbSDimitry Andric handleFreeStandingTagDecl(C); 7590b57cec5SDimitry Andric return true; 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7625ffd83dbSDimitry Andric syntax::Declaration *handleFreeStandingTagDecl(TagDecl *C) { 7635ffd83dbSDimitry Andric assert(C->isFreeStanding()); 7645ffd83dbSDimitry Andric // Class is a declaration specifier and needs a spanning declaration node. 7655ffd83dbSDimitry Andric auto DeclarationRange = Builder.getDeclarationRange(C); 7665ffd83dbSDimitry Andric syntax::Declaration *Result = new (allocator()) syntax::SimpleDeclaration; 7675ffd83dbSDimitry Andric Builder.foldNode(DeclarationRange, Result, nullptr); 7685ffd83dbSDimitry Andric 7695ffd83dbSDimitry Andric // Build TemplateDeclaration nodes if we had template parameters. 7705ffd83dbSDimitry Andric auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) { 7715ffd83dbSDimitry Andric const auto *TemplateKW = Builder.findToken(L.getTemplateLoc()); 772bdd1243dSDimitry Andric auto R = llvm::ArrayRef(TemplateKW, DeclarationRange.end()); 7735ffd83dbSDimitry Andric Result = 7745ffd83dbSDimitry Andric foldTemplateDeclaration(R, TemplateKW, DeclarationRange, nullptr); 7755ffd83dbSDimitry Andric DeclarationRange = R; 7765ffd83dbSDimitry Andric }; 777e8d8bef9SDimitry Andric if (auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(C)) 7785ffd83dbSDimitry Andric ConsumeTemplateParameters(*S->getTemplateParameters()); 7795ffd83dbSDimitry Andric for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I) 7805ffd83dbSDimitry Andric ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1)); 7815ffd83dbSDimitry Andric return Result; 7825ffd83dbSDimitry Andric } 7835ffd83dbSDimitry Andric 7840b57cec5SDimitry Andric bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) { 7855ffd83dbSDimitry Andric // We do not want to call VisitDecl(), the declaration for translation 7860b57cec5SDimitry Andric // unit is built by finalize(). 7870b57cec5SDimitry Andric return true; 7880b57cec5SDimitry Andric } 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric bool WalkUpFromCompoundStmt(CompoundStmt *S) { 7910b57cec5SDimitry Andric using NodeRole = syntax::NodeRole; 7920b57cec5SDimitry Andric 793480093f4SDimitry Andric Builder.markChildToken(S->getLBracLoc(), NodeRole::OpenParen); 794480093f4SDimitry Andric for (auto *Child : S->body()) 795e8d8bef9SDimitry Andric Builder.markStmtChild(Child, NodeRole::Statement); 796480093f4SDimitry Andric Builder.markChildToken(S->getRBracLoc(), NodeRole::CloseParen); 7970b57cec5SDimitry Andric 798480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 7995ffd83dbSDimitry Andric new (allocator()) syntax::CompoundStatement, S); 8000b57cec5SDimitry Andric return true; 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 803480093f4SDimitry Andric // Some statements are not yet handled by syntax trees. 804480093f4SDimitry Andric bool WalkUpFromStmt(Stmt *S) { 805480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 8065ffd83dbSDimitry Andric new (allocator()) syntax::UnknownStatement, S); 807480093f4SDimitry Andric return true; 808480093f4SDimitry Andric } 809480093f4SDimitry Andric 810fe6060f1SDimitry Andric bool TraverseIfStmt(IfStmt *S) { 811fe6060f1SDimitry Andric bool Result = [&, this]() { 812fe6060f1SDimitry Andric if (S->getInit() && !TraverseStmt(S->getInit())) { 813fe6060f1SDimitry Andric return false; 814fe6060f1SDimitry Andric } 815fe6060f1SDimitry Andric // In cases where the condition is an initialized declaration in a 816fe6060f1SDimitry Andric // statement, we want to preserve the declaration and ignore the 817fe6060f1SDimitry Andric // implicit condition expression in the syntax tree. 818fe6060f1SDimitry Andric if (S->hasVarStorage()) { 819fe6060f1SDimitry Andric if (!TraverseStmt(S->getConditionVariableDeclStmt())) 820fe6060f1SDimitry Andric return false; 821fe6060f1SDimitry Andric } else if (S->getCond() && !TraverseStmt(S->getCond())) 822fe6060f1SDimitry Andric return false; 823fe6060f1SDimitry Andric 824fe6060f1SDimitry Andric if (S->getThen() && !TraverseStmt(S->getThen())) 825fe6060f1SDimitry Andric return false; 826fe6060f1SDimitry Andric if (S->getElse() && !TraverseStmt(S->getElse())) 827fe6060f1SDimitry Andric return false; 828fe6060f1SDimitry Andric return true; 829fe6060f1SDimitry Andric }(); 830fe6060f1SDimitry Andric WalkUpFromIfStmt(S); 831fe6060f1SDimitry Andric return Result; 832fe6060f1SDimitry Andric } 833fe6060f1SDimitry Andric 834480093f4SDimitry Andric bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) { 835480093f4SDimitry Andric // We override to traverse range initializer as VarDecl. 836480093f4SDimitry Andric // RAV traverses it as a statement, we produce invalid node kinds in that 837480093f4SDimitry Andric // case. 838480093f4SDimitry Andric // FIXME: should do this in RAV instead? 8395ffd83dbSDimitry Andric bool Result = [&, this]() { 840480093f4SDimitry Andric if (S->getInit() && !TraverseStmt(S->getInit())) 841480093f4SDimitry Andric return false; 842480093f4SDimitry Andric if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable())) 843480093f4SDimitry Andric return false; 844480093f4SDimitry Andric if (S->getRangeInit() && !TraverseStmt(S->getRangeInit())) 845480093f4SDimitry Andric return false; 846480093f4SDimitry Andric if (S->getBody() && !TraverseStmt(S->getBody())) 847480093f4SDimitry Andric return false; 848480093f4SDimitry Andric return true; 8495ffd83dbSDimitry Andric }(); 8505ffd83dbSDimitry Andric WalkUpFromCXXForRangeStmt(S); 8515ffd83dbSDimitry Andric return Result; 852480093f4SDimitry Andric } 853480093f4SDimitry Andric 854480093f4SDimitry Andric bool TraverseStmt(Stmt *S) { 855e8d8bef9SDimitry Andric if (auto *DS = dyn_cast_or_null<DeclStmt>(S)) { 856480093f4SDimitry Andric // We want to consume the semicolon, make sure SimpleDeclaration does not. 857480093f4SDimitry Andric for (auto *D : DS->decls()) 8585ffd83dbSDimitry Andric Builder.noticeDeclWithoutSemicolon(D); 859e8d8bef9SDimitry Andric } else if (auto *E = dyn_cast_or_null<Expr>(S)) { 860e8d8bef9SDimitry Andric return RecursiveASTVisitor::TraverseStmt(IgnoreImplicit(E)); 861480093f4SDimitry Andric } 862480093f4SDimitry Andric return RecursiveASTVisitor::TraverseStmt(S); 863480093f4SDimitry Andric } 864480093f4SDimitry Andric 865fe6060f1SDimitry Andric bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) { 866fe6060f1SDimitry Andric // OpaqueValue doesn't correspond to concrete syntax, ignore it. 867fe6060f1SDimitry Andric return true; 868fe6060f1SDimitry Andric } 869fe6060f1SDimitry Andric 870480093f4SDimitry Andric // Some expressions are not yet handled by syntax trees. 871480093f4SDimitry Andric bool WalkUpFromExpr(Expr *E) { 872480093f4SDimitry Andric assert(!isImplicitExpr(E) && "should be handled by TraverseStmt"); 873480093f4SDimitry Andric Builder.foldNode(Builder.getExprRange(E), 8745ffd83dbSDimitry Andric new (allocator()) syntax::UnknownExpression, E); 875480093f4SDimitry Andric return true; 876480093f4SDimitry Andric } 877480093f4SDimitry Andric 8785ffd83dbSDimitry Andric bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) { 8795ffd83dbSDimitry Andric // The semantic AST node `UserDefinedLiteral` (UDL) may have one child node 8805ffd83dbSDimitry Andric // referencing the location of the UDL suffix (`_w` in `1.2_w`). The 8815ffd83dbSDimitry Andric // UDL suffix location does not point to the beginning of a token, so we 8825ffd83dbSDimitry Andric // can't represent the UDL suffix as a separate syntax tree node. 8835ffd83dbSDimitry Andric 8845ffd83dbSDimitry Andric return WalkUpFromUserDefinedLiteral(S); 8855ffd83dbSDimitry Andric } 8865ffd83dbSDimitry Andric 8875ffd83dbSDimitry Andric syntax::UserDefinedLiteralExpression * 8885ffd83dbSDimitry Andric buildUserDefinedLiteral(UserDefinedLiteral *S) { 8895ffd83dbSDimitry Andric switch (S->getLiteralOperatorKind()) { 890e8d8bef9SDimitry Andric case UserDefinedLiteral::LOK_Integer: 8915ffd83dbSDimitry Andric return new (allocator()) syntax::IntegerUserDefinedLiteralExpression; 892e8d8bef9SDimitry Andric case UserDefinedLiteral::LOK_Floating: 8935ffd83dbSDimitry Andric return new (allocator()) syntax::FloatUserDefinedLiteralExpression; 894e8d8bef9SDimitry Andric case UserDefinedLiteral::LOK_Character: 8955ffd83dbSDimitry Andric return new (allocator()) syntax::CharUserDefinedLiteralExpression; 896e8d8bef9SDimitry Andric case UserDefinedLiteral::LOK_String: 8975ffd83dbSDimitry Andric return new (allocator()) syntax::StringUserDefinedLiteralExpression; 898e8d8bef9SDimitry Andric case UserDefinedLiteral::LOK_Raw: 899e8d8bef9SDimitry Andric case UserDefinedLiteral::LOK_Template: 9005ffd83dbSDimitry Andric // For raw literal operator and numeric literal operator template we 9015ffd83dbSDimitry Andric // cannot get the type of the operand in the semantic AST. We get this 9025ffd83dbSDimitry Andric // information from the token. As integer and floating point have the same 9035ffd83dbSDimitry Andric // token kind, we run `NumericLiteralParser` again to distinguish them. 9045ffd83dbSDimitry Andric auto TokLoc = S->getBeginLoc(); 9055ffd83dbSDimitry Andric auto TokSpelling = 9065ffd83dbSDimitry Andric Builder.findToken(TokLoc)->text(Context.getSourceManager()); 9075ffd83dbSDimitry Andric auto Literal = 9085ffd83dbSDimitry Andric NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(), 9095ffd83dbSDimitry Andric Context.getLangOpts(), Context.getTargetInfo(), 9105ffd83dbSDimitry Andric Context.getDiagnostics()); 9115ffd83dbSDimitry Andric if (Literal.isIntegerLiteral()) 9125ffd83dbSDimitry Andric return new (allocator()) syntax::IntegerUserDefinedLiteralExpression; 9135ffd83dbSDimitry Andric else { 9145ffd83dbSDimitry Andric assert(Literal.isFloatingLiteral()); 9155ffd83dbSDimitry Andric return new (allocator()) syntax::FloatUserDefinedLiteralExpression; 9165ffd83dbSDimitry Andric } 9175ffd83dbSDimitry Andric } 9185ffd83dbSDimitry Andric llvm_unreachable("Unknown literal operator kind."); 9195ffd83dbSDimitry Andric } 9205ffd83dbSDimitry Andric 9215ffd83dbSDimitry Andric bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) { 9225ffd83dbSDimitry Andric Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken); 9235ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S); 9245ffd83dbSDimitry Andric return true; 9255ffd83dbSDimitry Andric } 9265ffd83dbSDimitry Andric 927e8d8bef9SDimitry Andric // FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the 928e8d8bef9SDimitry Andric // `DependentTemplateSpecializationType` case. 929e8d8bef9SDimitry Andric /// Given a nested-name-specifier return the range for the last name 930e8d8bef9SDimitry Andric /// specifier. 931e8d8bef9SDimitry Andric /// 932e8d8bef9SDimitry Andric /// e.g. `std::T::template X<U>::` => `template X<U>::` 933e8d8bef9SDimitry Andric SourceRange getLocalSourceRange(const NestedNameSpecifierLoc &NNSLoc) { 934e8d8bef9SDimitry Andric auto SR = NNSLoc.getLocalSourceRange(); 9355ffd83dbSDimitry Andric 936e8d8bef9SDimitry Andric // The method `NestedNameSpecifierLoc::getLocalSourceRange` *should* 937e8d8bef9SDimitry Andric // return the desired `SourceRange`, but there is a corner case. For a 938e8d8bef9SDimitry Andric // `DependentTemplateSpecializationType` this method returns its 939e8d8bef9SDimitry Andric // qualifiers as well, in other words in the example above this method 940e8d8bef9SDimitry Andric // returns `T::template X<U>::` instead of only `template X<U>::` 941e8d8bef9SDimitry Andric if (auto TL = NNSLoc.getTypeLoc()) { 942e8d8bef9SDimitry Andric if (auto DependentTL = 943e8d8bef9SDimitry Andric TL.getAs<DependentTemplateSpecializationTypeLoc>()) { 944e8d8bef9SDimitry Andric // The 'template' keyword is always present in dependent template 945e8d8bef9SDimitry Andric // specializations. Except in the case of incorrect code 946e8d8bef9SDimitry Andric // TODO: Treat the case of incorrect code. 947e8d8bef9SDimitry Andric SR.setBegin(DependentTL.getTemplateKeywordLoc()); 9485ffd83dbSDimitry Andric } 949e8d8bef9SDimitry Andric } 950e8d8bef9SDimitry Andric 951e8d8bef9SDimitry Andric return SR; 952e8d8bef9SDimitry Andric } 953e8d8bef9SDimitry Andric 954e8d8bef9SDimitry Andric syntax::NodeKind getNameSpecifierKind(const NestedNameSpecifier &NNS) { 955e8d8bef9SDimitry Andric switch (NNS.getKind()) { 956e8d8bef9SDimitry Andric case NestedNameSpecifier::Global: 957e8d8bef9SDimitry Andric return syntax::NodeKind::GlobalNameSpecifier; 958e8d8bef9SDimitry Andric case NestedNameSpecifier::Namespace: 959e8d8bef9SDimitry Andric case NestedNameSpecifier::NamespaceAlias: 960e8d8bef9SDimitry Andric case NestedNameSpecifier::Identifier: 961e8d8bef9SDimitry Andric return syntax::NodeKind::IdentifierNameSpecifier; 962e8d8bef9SDimitry Andric case NestedNameSpecifier::TypeSpecWithTemplate: 963e8d8bef9SDimitry Andric return syntax::NodeKind::SimpleTemplateNameSpecifier; 964e8d8bef9SDimitry Andric case NestedNameSpecifier::TypeSpec: { 965e8d8bef9SDimitry Andric const auto *NNSType = NNS.getAsType(); 966e8d8bef9SDimitry Andric assert(NNSType); 967e8d8bef9SDimitry Andric if (isa<DecltypeType>(NNSType)) 968e8d8bef9SDimitry Andric return syntax::NodeKind::DecltypeNameSpecifier; 969e8d8bef9SDimitry Andric if (isa<TemplateSpecializationType, DependentTemplateSpecializationType>( 970e8d8bef9SDimitry Andric NNSType)) 971e8d8bef9SDimitry Andric return syntax::NodeKind::SimpleTemplateNameSpecifier; 972e8d8bef9SDimitry Andric return syntax::NodeKind::IdentifierNameSpecifier; 973e8d8bef9SDimitry Andric } 974e8d8bef9SDimitry Andric default: 975e8d8bef9SDimitry Andric // FIXME: Support Microsoft's __super 976e8d8bef9SDimitry Andric llvm::report_fatal_error("We don't yet support the __super specifier", 977e8d8bef9SDimitry Andric true); 978e8d8bef9SDimitry Andric } 979e8d8bef9SDimitry Andric } 980e8d8bef9SDimitry Andric 981e8d8bef9SDimitry Andric syntax::NameSpecifier * 982e8d8bef9SDimitry Andric buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) { 983e8d8bef9SDimitry Andric assert(NNSLoc.hasQualifier()); 984e8d8bef9SDimitry Andric auto NameSpecifierTokens = 985e8d8bef9SDimitry Andric Builder.getRange(getLocalSourceRange(NNSLoc)).drop_back(); 986e8d8bef9SDimitry Andric switch (getNameSpecifierKind(*NNSLoc.getNestedNameSpecifier())) { 987e8d8bef9SDimitry Andric case syntax::NodeKind::GlobalNameSpecifier: 988e8d8bef9SDimitry Andric return new (allocator()) syntax::GlobalNameSpecifier; 989e8d8bef9SDimitry Andric case syntax::NodeKind::IdentifierNameSpecifier: { 990e8d8bef9SDimitry Andric assert(NameSpecifierTokens.size() == 1); 991e8d8bef9SDimitry Andric Builder.markChildToken(NameSpecifierTokens.begin(), 992e8d8bef9SDimitry Andric syntax::NodeRole::Unknown); 993e8d8bef9SDimitry Andric auto *NS = new (allocator()) syntax::IdentifierNameSpecifier; 994e8d8bef9SDimitry Andric Builder.foldNode(NameSpecifierTokens, NS, nullptr); 995e8d8bef9SDimitry Andric return NS; 996e8d8bef9SDimitry Andric } 997e8d8bef9SDimitry Andric case syntax::NodeKind::SimpleTemplateNameSpecifier: { 998e8d8bef9SDimitry Andric // TODO: Build `SimpleTemplateNameSpecifier` children and implement 999e8d8bef9SDimitry Andric // accessors to them. 1000e8d8bef9SDimitry Andric // Be aware, we cannot do that simply by calling `TraverseTypeLoc`, 1001e8d8bef9SDimitry Andric // some `TypeLoc`s have inside them the previous name specifier and 1002e8d8bef9SDimitry Andric // we want to treat them independently. 1003e8d8bef9SDimitry Andric auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier; 1004e8d8bef9SDimitry Andric Builder.foldNode(NameSpecifierTokens, NS, nullptr); 1005e8d8bef9SDimitry Andric return NS; 1006e8d8bef9SDimitry Andric } 1007e8d8bef9SDimitry Andric case syntax::NodeKind::DecltypeNameSpecifier: { 1008e8d8bef9SDimitry Andric const auto TL = NNSLoc.getTypeLoc().castAs<DecltypeTypeLoc>(); 1009e8d8bef9SDimitry Andric if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL)) 1010e8d8bef9SDimitry Andric return nullptr; 1011e8d8bef9SDimitry Andric auto *NS = new (allocator()) syntax::DecltypeNameSpecifier; 1012e8d8bef9SDimitry Andric // TODO: Implement accessor to `DecltypeNameSpecifier` inner 1013e8d8bef9SDimitry Andric // `DecltypeTypeLoc`. 1014e8d8bef9SDimitry Andric // For that add mapping from `TypeLoc` to `syntax::Node*` then: 1015e8d8bef9SDimitry Andric // Builder.markChild(TypeLoc, syntax::NodeRole); 1016e8d8bef9SDimitry Andric Builder.foldNode(NameSpecifierTokens, NS, nullptr); 1017e8d8bef9SDimitry Andric return NS; 1018e8d8bef9SDimitry Andric } 1019e8d8bef9SDimitry Andric default: 1020e8d8bef9SDimitry Andric llvm_unreachable("getChildKind() does not return this value"); 1021e8d8bef9SDimitry Andric } 1022e8d8bef9SDimitry Andric } 1023e8d8bef9SDimitry Andric 1024e8d8bef9SDimitry Andric // To build syntax tree nodes for NestedNameSpecifierLoc we override 1025e8d8bef9SDimitry Andric // Traverse instead of WalkUpFrom because we want to traverse the children 1026e8d8bef9SDimitry Andric // ourselves and build a list instead of a nested tree of name specifier 1027e8d8bef9SDimitry Andric // prefixes. 1028e8d8bef9SDimitry Andric bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1029e8d8bef9SDimitry Andric if (!QualifierLoc) 1030e8d8bef9SDimitry Andric return true; 1031e8d8bef9SDimitry Andric for (auto It = QualifierLoc; It; It = It.getPrefix()) { 1032e8d8bef9SDimitry Andric auto *NS = buildNameSpecifier(It); 1033e8d8bef9SDimitry Andric if (!NS) 1034e8d8bef9SDimitry Andric return false; 1035e8d8bef9SDimitry Andric Builder.markChild(NS, syntax::NodeRole::ListElement); 1036e8d8bef9SDimitry Andric Builder.markChildToken(It.getEndLoc(), syntax::NodeRole::ListDelimiter); 1037e8d8bef9SDimitry Andric } 1038e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), 1039e8d8bef9SDimitry Andric new (allocator()) syntax::NestedNameSpecifier, 1040e8d8bef9SDimitry Andric QualifierLoc); 1041e8d8bef9SDimitry Andric return true; 1042e8d8bef9SDimitry Andric } 1043e8d8bef9SDimitry Andric 1044e8d8bef9SDimitry Andric syntax::IdExpression *buildIdExpression(NestedNameSpecifierLoc QualifierLoc, 1045e8d8bef9SDimitry Andric SourceLocation TemplateKeywordLoc, 1046e8d8bef9SDimitry Andric SourceRange UnqualifiedIdLoc, 1047e8d8bef9SDimitry Andric ASTPtr From) { 1048e8d8bef9SDimitry Andric if (QualifierLoc) { 1049e8d8bef9SDimitry Andric Builder.markChild(QualifierLoc, syntax::NodeRole::Qualifier); 1050e8d8bef9SDimitry Andric if (TemplateKeywordLoc.isValid()) 1051e8d8bef9SDimitry Andric Builder.markChildToken(TemplateKeywordLoc, 1052e8d8bef9SDimitry Andric syntax::NodeRole::TemplateKeyword); 1053e8d8bef9SDimitry Andric } 1054e8d8bef9SDimitry Andric 1055e8d8bef9SDimitry Andric auto *TheUnqualifiedId = new (allocator()) syntax::UnqualifiedId; 1056e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId, 1057e8d8bef9SDimitry Andric nullptr); 1058e8d8bef9SDimitry Andric Builder.markChild(TheUnqualifiedId, syntax::NodeRole::UnqualifiedId); 1059e8d8bef9SDimitry Andric 1060e8d8bef9SDimitry Andric auto IdExpressionBeginLoc = 1061e8d8bef9SDimitry Andric QualifierLoc ? QualifierLoc.getBeginLoc() : UnqualifiedIdLoc.getBegin(); 1062e8d8bef9SDimitry Andric 1063e8d8bef9SDimitry Andric auto *TheIdExpression = new (allocator()) syntax::IdExpression; 1064e8d8bef9SDimitry Andric Builder.foldNode( 1065e8d8bef9SDimitry Andric Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.getEnd()), 1066e8d8bef9SDimitry Andric TheIdExpression, From); 1067e8d8bef9SDimitry Andric 1068e8d8bef9SDimitry Andric return TheIdExpression; 1069e8d8bef9SDimitry Andric } 1070e8d8bef9SDimitry Andric 1071e8d8bef9SDimitry Andric bool WalkUpFromMemberExpr(MemberExpr *S) { 1072e8d8bef9SDimitry Andric // For `MemberExpr` with implicit `this->` we generate a simple 1073e8d8bef9SDimitry Andric // `id-expression` syntax node, beacuse an implicit `member-expression` is 1074e8d8bef9SDimitry Andric // syntactically undistinguishable from an `id-expression` 1075e8d8bef9SDimitry Andric if (S->isImplicitAccess()) { 1076e8d8bef9SDimitry Andric buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(), 1077e8d8bef9SDimitry Andric SourceRange(S->getMemberLoc(), S->getEndLoc()), S); 1078e8d8bef9SDimitry Andric return true; 1079e8d8bef9SDimitry Andric } 1080e8d8bef9SDimitry Andric 1081e8d8bef9SDimitry Andric auto *TheIdExpression = buildIdExpression( 1082e8d8bef9SDimitry Andric S->getQualifierLoc(), S->getTemplateKeywordLoc(), 1083e8d8bef9SDimitry Andric SourceRange(S->getMemberLoc(), S->getEndLoc()), nullptr); 1084e8d8bef9SDimitry Andric 1085e8d8bef9SDimitry Andric Builder.markChild(TheIdExpression, syntax::NodeRole::Member); 1086e8d8bef9SDimitry Andric 1087e8d8bef9SDimitry Andric Builder.markExprChild(S->getBase(), syntax::NodeRole::Object); 1088e8d8bef9SDimitry Andric Builder.markChildToken(S->getOperatorLoc(), syntax::NodeRole::AccessToken); 10895ffd83dbSDimitry Andric 10905ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 1091e8d8bef9SDimitry Andric new (allocator()) syntax::MemberExpression, S); 1092e8d8bef9SDimitry Andric return true; 1093e8d8bef9SDimitry Andric } 1094e8d8bef9SDimitry Andric 1095e8d8bef9SDimitry Andric bool WalkUpFromDeclRefExpr(DeclRefExpr *S) { 1096e8d8bef9SDimitry Andric buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(), 1097e8d8bef9SDimitry Andric SourceRange(S->getLocation(), S->getEndLoc()), S); 1098e8d8bef9SDimitry Andric 1099e8d8bef9SDimitry Andric return true; 1100e8d8bef9SDimitry Andric } 1101e8d8bef9SDimitry Andric 1102e8d8bef9SDimitry Andric // Same logic as DeclRefExpr. 1103e8d8bef9SDimitry Andric bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) { 1104e8d8bef9SDimitry Andric buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(), 1105e8d8bef9SDimitry Andric SourceRange(S->getLocation(), S->getEndLoc()), S); 1106e8d8bef9SDimitry Andric 1107e8d8bef9SDimitry Andric return true; 1108e8d8bef9SDimitry Andric } 1109e8d8bef9SDimitry Andric 1110e8d8bef9SDimitry Andric bool WalkUpFromCXXThisExpr(CXXThisExpr *S) { 1111e8d8bef9SDimitry Andric if (!S->isImplicit()) { 1112e8d8bef9SDimitry Andric Builder.markChildToken(S->getLocation(), 1113e8d8bef9SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1114e8d8bef9SDimitry Andric Builder.foldNode(Builder.getExprRange(S), 1115e8d8bef9SDimitry Andric new (allocator()) syntax::ThisExpression, S); 1116e8d8bef9SDimitry Andric } 11175ffd83dbSDimitry Andric return true; 11185ffd83dbSDimitry Andric } 11195ffd83dbSDimitry Andric 11205ffd83dbSDimitry Andric bool WalkUpFromParenExpr(ParenExpr *S) { 11215ffd83dbSDimitry Andric Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen); 1122e8d8bef9SDimitry Andric Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::SubExpression); 11235ffd83dbSDimitry Andric Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen); 11245ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11255ffd83dbSDimitry Andric new (allocator()) syntax::ParenExpression, S); 11265ffd83dbSDimitry Andric return true; 11275ffd83dbSDimitry Andric } 11285ffd83dbSDimitry Andric 11295ffd83dbSDimitry Andric bool WalkUpFromIntegerLiteral(IntegerLiteral *S) { 11305ffd83dbSDimitry Andric Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 11315ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11325ffd83dbSDimitry Andric new (allocator()) syntax::IntegerLiteralExpression, S); 11335ffd83dbSDimitry Andric return true; 11345ffd83dbSDimitry Andric } 11355ffd83dbSDimitry Andric 11365ffd83dbSDimitry Andric bool WalkUpFromCharacterLiteral(CharacterLiteral *S) { 11375ffd83dbSDimitry Andric Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 11385ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11395ffd83dbSDimitry Andric new (allocator()) syntax::CharacterLiteralExpression, S); 11405ffd83dbSDimitry Andric return true; 11415ffd83dbSDimitry Andric } 11425ffd83dbSDimitry Andric 11435ffd83dbSDimitry Andric bool WalkUpFromFloatingLiteral(FloatingLiteral *S) { 11445ffd83dbSDimitry Andric Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 11455ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11465ffd83dbSDimitry Andric new (allocator()) syntax::FloatingLiteralExpression, S); 11475ffd83dbSDimitry Andric return true; 11485ffd83dbSDimitry Andric } 11495ffd83dbSDimitry Andric 11505ffd83dbSDimitry Andric bool WalkUpFromStringLiteral(StringLiteral *S) { 11515ffd83dbSDimitry Andric Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken); 11525ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11535ffd83dbSDimitry Andric new (allocator()) syntax::StringLiteralExpression, S); 11545ffd83dbSDimitry Andric return true; 11555ffd83dbSDimitry Andric } 11565ffd83dbSDimitry Andric 11575ffd83dbSDimitry Andric bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) { 11585ffd83dbSDimitry Andric Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 11595ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11605ffd83dbSDimitry Andric new (allocator()) syntax::BoolLiteralExpression, S); 11615ffd83dbSDimitry Andric return true; 11625ffd83dbSDimitry Andric } 11635ffd83dbSDimitry Andric 11645ffd83dbSDimitry Andric bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) { 11655ffd83dbSDimitry Andric Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 11665ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11675ffd83dbSDimitry Andric new (allocator()) syntax::CxxNullPtrExpression, S); 11685ffd83dbSDimitry Andric return true; 11695ffd83dbSDimitry Andric } 11705ffd83dbSDimitry Andric 11715ffd83dbSDimitry Andric bool WalkUpFromUnaryOperator(UnaryOperator *S) { 11725ffd83dbSDimitry Andric Builder.markChildToken(S->getOperatorLoc(), 1173e8d8bef9SDimitry Andric syntax::NodeRole::OperatorToken); 1174e8d8bef9SDimitry Andric Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::Operand); 11755ffd83dbSDimitry Andric 11765ffd83dbSDimitry Andric if (S->isPostfix()) 11775ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11785ffd83dbSDimitry Andric new (allocator()) syntax::PostfixUnaryOperatorExpression, 11795ffd83dbSDimitry Andric S); 11805ffd83dbSDimitry Andric else 11815ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11825ffd83dbSDimitry Andric new (allocator()) syntax::PrefixUnaryOperatorExpression, 11835ffd83dbSDimitry Andric S); 11845ffd83dbSDimitry Andric 11855ffd83dbSDimitry Andric return true; 11865ffd83dbSDimitry Andric } 11875ffd83dbSDimitry Andric 11885ffd83dbSDimitry Andric bool WalkUpFromBinaryOperator(BinaryOperator *S) { 1189e8d8bef9SDimitry Andric Builder.markExprChild(S->getLHS(), syntax::NodeRole::LeftHandSide); 11905ffd83dbSDimitry Andric Builder.markChildToken(S->getOperatorLoc(), 1191e8d8bef9SDimitry Andric syntax::NodeRole::OperatorToken); 1192e8d8bef9SDimitry Andric Builder.markExprChild(S->getRHS(), syntax::NodeRole::RightHandSide); 11935ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 11945ffd83dbSDimitry Andric new (allocator()) syntax::BinaryOperatorExpression, S); 11955ffd83dbSDimitry Andric return true; 11965ffd83dbSDimitry Andric } 11975ffd83dbSDimitry Andric 1198e8d8bef9SDimitry Andric /// Builds `CallArguments` syntax node from arguments that appear in source 1199e8d8bef9SDimitry Andric /// code, i.e. not default arguments. 1200e8d8bef9SDimitry Andric syntax::CallArguments * 1201e8d8bef9SDimitry Andric buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs) { 1202e8d8bef9SDimitry Andric auto Args = dropDefaultArgs(ArgsAndDefaultArgs); 1203e8d8bef9SDimitry Andric for (auto *Arg : Args) { 1204e8d8bef9SDimitry Andric Builder.markExprChild(Arg, syntax::NodeRole::ListElement); 1205e8d8bef9SDimitry Andric const auto *DelimiterToken = 1206e8d8bef9SDimitry Andric std::next(Builder.findToken(Arg->getEndLoc())); 1207e8d8bef9SDimitry Andric if (DelimiterToken->kind() == clang::tok::TokenKind::comma) 1208e8d8bef9SDimitry Andric Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter); 1209e8d8bef9SDimitry Andric } 1210e8d8bef9SDimitry Andric 1211e8d8bef9SDimitry Andric auto *Arguments = new (allocator()) syntax::CallArguments; 1212e8d8bef9SDimitry Andric if (!Args.empty()) 1213e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(), 1214e8d8bef9SDimitry Andric (*(Args.end() - 1))->getEndLoc()), 1215e8d8bef9SDimitry Andric Arguments, nullptr); 1216e8d8bef9SDimitry Andric 1217e8d8bef9SDimitry Andric return Arguments; 1218e8d8bef9SDimitry Andric } 1219e8d8bef9SDimitry Andric 1220e8d8bef9SDimitry Andric bool WalkUpFromCallExpr(CallExpr *S) { 1221e8d8bef9SDimitry Andric Builder.markExprChild(S->getCallee(), syntax::NodeRole::Callee); 1222e8d8bef9SDimitry Andric 1223e8d8bef9SDimitry Andric const auto *LParenToken = 1224e8d8bef9SDimitry Andric std::next(Builder.findToken(S->getCallee()->getEndLoc())); 1225e8d8bef9SDimitry Andric // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have fixed 1226e8d8bef9SDimitry Andric // the test on decltype desctructors. 1227e8d8bef9SDimitry Andric if (LParenToken->kind() == clang::tok::l_paren) 1228e8d8bef9SDimitry Andric Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen); 1229e8d8bef9SDimitry Andric 1230e8d8bef9SDimitry Andric Builder.markChild(buildCallArguments(S->arguments()), 1231e8d8bef9SDimitry Andric syntax::NodeRole::Arguments); 1232e8d8bef9SDimitry Andric 1233e8d8bef9SDimitry Andric Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen); 1234e8d8bef9SDimitry Andric 1235e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange(S->getSourceRange()), 1236e8d8bef9SDimitry Andric new (allocator()) syntax::CallExpression, S); 1237e8d8bef9SDimitry Andric return true; 1238e8d8bef9SDimitry Andric } 1239e8d8bef9SDimitry Andric 1240e8d8bef9SDimitry Andric bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S) { 1241e8d8bef9SDimitry Andric // Ignore the implicit calls to default constructors. 1242e8d8bef9SDimitry Andric if ((S->getNumArgs() == 0 || isa<CXXDefaultArgExpr>(S->getArg(0))) && 1243e8d8bef9SDimitry Andric S->getParenOrBraceRange().isInvalid()) 1244e8d8bef9SDimitry Andric return true; 1245e8d8bef9SDimitry Andric return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S); 1246e8d8bef9SDimitry Andric } 1247e8d8bef9SDimitry Andric 12485ffd83dbSDimitry Andric bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) { 1249e8d8bef9SDimitry Andric // To construct a syntax tree of the same shape for calls to built-in and 1250e8d8bef9SDimitry Andric // user-defined operators, ignore the `DeclRefExpr` that refers to the 1251e8d8bef9SDimitry Andric // operator and treat it as a simple token. Do that by traversing 1252e8d8bef9SDimitry Andric // arguments instead of children. 1253e8d8bef9SDimitry Andric for (auto *child : S->arguments()) { 12545ffd83dbSDimitry Andric // A postfix unary operator is declared as taking two operands. The 12555ffd83dbSDimitry Andric // second operand is used to distinguish from its prefix counterpart. In 12565ffd83dbSDimitry Andric // the semantic AST this "phantom" operand is represented as a 12575ffd83dbSDimitry Andric // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this 12585ffd83dbSDimitry Andric // operand because it does not correspond to anything written in source 1259e8d8bef9SDimitry Andric // code. 1260e8d8bef9SDimitry Andric if (child->getSourceRange().isInvalid()) { 1261e8d8bef9SDimitry Andric assert(getOperatorNodeKind(*S) == 1262e8d8bef9SDimitry Andric syntax::NodeKind::PostfixUnaryOperatorExpression); 12635ffd83dbSDimitry Andric continue; 1264e8d8bef9SDimitry Andric } 12655ffd83dbSDimitry Andric if (!TraverseStmt(child)) 12665ffd83dbSDimitry Andric return false; 12675ffd83dbSDimitry Andric } 12685ffd83dbSDimitry Andric return WalkUpFromCXXOperatorCallExpr(S); 12695ffd83dbSDimitry Andric } 12705ffd83dbSDimitry Andric 12715ffd83dbSDimitry Andric bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) { 12725ffd83dbSDimitry Andric switch (getOperatorNodeKind(*S)) { 12735ffd83dbSDimitry Andric case syntax::NodeKind::BinaryOperatorExpression: 1274e8d8bef9SDimitry Andric Builder.markExprChild(S->getArg(0), syntax::NodeRole::LeftHandSide); 1275e8d8bef9SDimitry Andric Builder.markChildToken(S->getOperatorLoc(), 1276e8d8bef9SDimitry Andric syntax::NodeRole::OperatorToken); 1277e8d8bef9SDimitry Andric Builder.markExprChild(S->getArg(1), syntax::NodeRole::RightHandSide); 12785ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 12795ffd83dbSDimitry Andric new (allocator()) syntax::BinaryOperatorExpression, S); 12805ffd83dbSDimitry Andric return true; 12815ffd83dbSDimitry Andric case syntax::NodeKind::PrefixUnaryOperatorExpression: 1282e8d8bef9SDimitry Andric Builder.markChildToken(S->getOperatorLoc(), 1283e8d8bef9SDimitry Andric syntax::NodeRole::OperatorToken); 1284e8d8bef9SDimitry Andric Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand); 12855ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 12865ffd83dbSDimitry Andric new (allocator()) syntax::PrefixUnaryOperatorExpression, 12875ffd83dbSDimitry Andric S); 12885ffd83dbSDimitry Andric return true; 12895ffd83dbSDimitry Andric case syntax::NodeKind::PostfixUnaryOperatorExpression: 1290e8d8bef9SDimitry Andric Builder.markChildToken(S->getOperatorLoc(), 1291e8d8bef9SDimitry Andric syntax::NodeRole::OperatorToken); 1292e8d8bef9SDimitry Andric Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand); 12935ffd83dbSDimitry Andric Builder.foldNode(Builder.getExprRange(S), 12945ffd83dbSDimitry Andric new (allocator()) syntax::PostfixUnaryOperatorExpression, 12955ffd83dbSDimitry Andric S); 12965ffd83dbSDimitry Andric return true; 1297e8d8bef9SDimitry Andric case syntax::NodeKind::CallExpression: { 1298e8d8bef9SDimitry Andric Builder.markExprChild(S->getArg(0), syntax::NodeRole::Callee); 1299e8d8bef9SDimitry Andric 1300e8d8bef9SDimitry Andric const auto *LParenToken = 1301e8d8bef9SDimitry Andric std::next(Builder.findToken(S->getArg(0)->getEndLoc())); 1302e8d8bef9SDimitry Andric // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have 1303e8d8bef9SDimitry Andric // fixed the test on decltype desctructors. 1304e8d8bef9SDimitry Andric if (LParenToken->kind() == clang::tok::l_paren) 1305e8d8bef9SDimitry Andric Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen); 1306e8d8bef9SDimitry Andric 1307e8d8bef9SDimitry Andric Builder.markChild(buildCallArguments(CallExpr::arg_range( 1308e8d8bef9SDimitry Andric S->arg_begin() + 1, S->arg_end())), 1309e8d8bef9SDimitry Andric syntax::NodeRole::Arguments); 1310e8d8bef9SDimitry Andric 1311e8d8bef9SDimitry Andric Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen); 1312e8d8bef9SDimitry Andric 1313e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange(S->getSourceRange()), 1314e8d8bef9SDimitry Andric new (allocator()) syntax::CallExpression, S); 1315e8d8bef9SDimitry Andric return true; 1316e8d8bef9SDimitry Andric } 13175ffd83dbSDimitry Andric case syntax::NodeKind::UnknownExpression: 1318e8d8bef9SDimitry Andric return WalkUpFromExpr(S); 13195ffd83dbSDimitry Andric default: 13205ffd83dbSDimitry Andric llvm_unreachable("getOperatorNodeKind() does not return this value"); 13215ffd83dbSDimitry Andric } 13225ffd83dbSDimitry Andric } 13235ffd83dbSDimitry Andric 1324e8d8bef9SDimitry Andric bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S) { return true; } 1325e8d8bef9SDimitry Andric 1326480093f4SDimitry Andric bool WalkUpFromNamespaceDecl(NamespaceDecl *S) { 13275ffd83dbSDimitry Andric auto Tokens = Builder.getDeclarationRange(S); 1328480093f4SDimitry Andric if (Tokens.front().kind() == tok::coloncolon) { 1329480093f4SDimitry Andric // Handle nested namespace definitions. Those start at '::' token, e.g. 1330480093f4SDimitry Andric // namespace a^::b {} 1331480093f4SDimitry Andric // FIXME: build corresponding nodes for the name of this namespace. 1332480093f4SDimitry Andric return true; 1333480093f4SDimitry Andric } 13345ffd83dbSDimitry Andric Builder.foldNode(Tokens, new (allocator()) syntax::NamespaceDefinition, S); 13355ffd83dbSDimitry Andric return true; 13365ffd83dbSDimitry Andric } 13375ffd83dbSDimitry Andric 1338e8d8bef9SDimitry Andric // FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test 1339e8d8bef9SDimitry Andric // results. Find test coverage or remove it. 13405ffd83dbSDimitry Andric bool TraverseParenTypeLoc(ParenTypeLoc L) { 13415ffd83dbSDimitry Andric // We reverse order of traversal to get the proper syntax structure. 13425ffd83dbSDimitry Andric if (!WalkUpFromParenTypeLoc(L)) 13435ffd83dbSDimitry Andric return false; 13445ffd83dbSDimitry Andric return TraverseTypeLoc(L.getInnerLoc()); 13455ffd83dbSDimitry Andric } 13465ffd83dbSDimitry Andric 13475ffd83dbSDimitry Andric bool WalkUpFromParenTypeLoc(ParenTypeLoc L) { 13485ffd83dbSDimitry Andric Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen); 13495ffd83dbSDimitry Andric Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen); 13505ffd83dbSDimitry Andric Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getRParenLoc()), 13515ffd83dbSDimitry Andric new (allocator()) syntax::ParenDeclarator, L); 13525ffd83dbSDimitry Andric return true; 13535ffd83dbSDimitry Andric } 13545ffd83dbSDimitry Andric 13555ffd83dbSDimitry Andric // Declarator chunks, they are produced by type locs and some clang::Decls. 13565ffd83dbSDimitry Andric bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L) { 13575ffd83dbSDimitry Andric Builder.markChildToken(L.getLBracketLoc(), syntax::NodeRole::OpenParen); 1358e8d8bef9SDimitry Andric Builder.markExprChild(L.getSizeExpr(), syntax::NodeRole::Size); 13595ffd83dbSDimitry Andric Builder.markChildToken(L.getRBracketLoc(), syntax::NodeRole::CloseParen); 13605ffd83dbSDimitry Andric Builder.foldNode(Builder.getRange(L.getLBracketLoc(), L.getRBracketLoc()), 13615ffd83dbSDimitry Andric new (allocator()) syntax::ArraySubscript, L); 13625ffd83dbSDimitry Andric return true; 13635ffd83dbSDimitry Andric } 13645ffd83dbSDimitry Andric 1365e8d8bef9SDimitry Andric syntax::ParameterDeclarationList * 1366e8d8bef9SDimitry Andric buildParameterDeclarationList(ArrayRef<ParmVarDecl *> Params) { 1367e8d8bef9SDimitry Andric for (auto *P : Params) { 1368e8d8bef9SDimitry Andric Builder.markChild(P, syntax::NodeRole::ListElement); 1369e8d8bef9SDimitry Andric const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc())); 1370e8d8bef9SDimitry Andric if (DelimiterToken->kind() == clang::tok::TokenKind::comma) 1371e8d8bef9SDimitry Andric Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter); 1372e8d8bef9SDimitry Andric } 1373e8d8bef9SDimitry Andric auto *Parameters = new (allocator()) syntax::ParameterDeclarationList; 1374e8d8bef9SDimitry Andric if (!Params.empty()) 1375e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(), 1376e8d8bef9SDimitry Andric Params.back()->getEndLoc()), 1377e8d8bef9SDimitry Andric Parameters, nullptr); 1378e8d8bef9SDimitry Andric return Parameters; 1379e8d8bef9SDimitry Andric } 1380e8d8bef9SDimitry Andric 13815ffd83dbSDimitry Andric bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) { 13825ffd83dbSDimitry Andric Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen); 1383e8d8bef9SDimitry Andric 1384e8d8bef9SDimitry Andric Builder.markChild(buildParameterDeclarationList(L.getParams()), 1385e8d8bef9SDimitry Andric syntax::NodeRole::Parameters); 1386e8d8bef9SDimitry Andric 13875ffd83dbSDimitry Andric Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen); 13885ffd83dbSDimitry Andric Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()), 13895ffd83dbSDimitry Andric new (allocator()) syntax::ParametersAndQualifiers, L); 13905ffd83dbSDimitry Andric return true; 13915ffd83dbSDimitry Andric } 13925ffd83dbSDimitry Andric 13935ffd83dbSDimitry Andric bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L) { 13945ffd83dbSDimitry Andric if (!L.getTypePtr()->hasTrailingReturn()) 13955ffd83dbSDimitry Andric return WalkUpFromFunctionTypeLoc(L); 13965ffd83dbSDimitry Andric 1397e8d8bef9SDimitry Andric auto *TrailingReturnTokens = buildTrailingReturn(L); 13985ffd83dbSDimitry Andric // Finish building the node for parameters. 1399e8d8bef9SDimitry Andric Builder.markChild(TrailingReturnTokens, syntax::NodeRole::TrailingReturn); 14005ffd83dbSDimitry Andric return WalkUpFromFunctionTypeLoc(L); 14015ffd83dbSDimitry Andric } 14025ffd83dbSDimitry Andric 1403e8d8bef9SDimitry Andric bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) { 1404e8d8bef9SDimitry Andric // In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds 1405e8d8bef9SDimitry Andric // to "Y::*" but it points to a `ParenTypeLoc` that corresponds to 1406e8d8bef9SDimitry Andric // "(Y::*mp)" We thus reverse the order of traversal to get the proper 1407e8d8bef9SDimitry Andric // syntax structure. 1408e8d8bef9SDimitry Andric if (!WalkUpFromMemberPointerTypeLoc(L)) 1409e8d8bef9SDimitry Andric return false; 1410e8d8bef9SDimitry Andric return TraverseTypeLoc(L.getPointeeLoc()); 1411e8d8bef9SDimitry Andric } 1412e8d8bef9SDimitry Andric 14135ffd83dbSDimitry Andric bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) { 14145ffd83dbSDimitry Andric auto SR = L.getLocalSourceRange(); 14155ffd83dbSDimitry Andric Builder.foldNode(Builder.getRange(SR), 14165ffd83dbSDimitry Andric new (allocator()) syntax::MemberPointer, L); 1417480093f4SDimitry Andric return true; 1418480093f4SDimitry Andric } 1419480093f4SDimitry Andric 1420480093f4SDimitry Andric // The code below is very regular, it could even be generated with some 1421480093f4SDimitry Andric // preprocessor magic. We merely assign roles to the corresponding children 1422480093f4SDimitry Andric // and fold resulting nodes. 1423480093f4SDimitry Andric bool WalkUpFromDeclStmt(DeclStmt *S) { 1424480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14255ffd83dbSDimitry Andric new (allocator()) syntax::DeclarationStatement, S); 1426480093f4SDimitry Andric return true; 1427480093f4SDimitry Andric } 1428480093f4SDimitry Andric 1429480093f4SDimitry Andric bool WalkUpFromNullStmt(NullStmt *S) { 1430480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14315ffd83dbSDimitry Andric new (allocator()) syntax::EmptyStatement, S); 1432480093f4SDimitry Andric return true; 1433480093f4SDimitry Andric } 1434480093f4SDimitry Andric 1435480093f4SDimitry Andric bool WalkUpFromSwitchStmt(SwitchStmt *S) { 1436480093f4SDimitry Andric Builder.markChildToken(S->getSwitchLoc(), 1437480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1438480093f4SDimitry Andric Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 1439480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14405ffd83dbSDimitry Andric new (allocator()) syntax::SwitchStatement, S); 1441480093f4SDimitry Andric return true; 1442480093f4SDimitry Andric } 1443480093f4SDimitry Andric 1444480093f4SDimitry Andric bool WalkUpFromCaseStmt(CaseStmt *S) { 1445480093f4SDimitry Andric Builder.markChildToken(S->getKeywordLoc(), 1446480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1447e8d8bef9SDimitry Andric Builder.markExprChild(S->getLHS(), syntax::NodeRole::CaseValue); 1448480093f4SDimitry Andric Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement); 1449480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14505ffd83dbSDimitry Andric new (allocator()) syntax::CaseStatement, S); 1451480093f4SDimitry Andric return true; 1452480093f4SDimitry Andric } 1453480093f4SDimitry Andric 1454480093f4SDimitry Andric bool WalkUpFromDefaultStmt(DefaultStmt *S) { 1455480093f4SDimitry Andric Builder.markChildToken(S->getKeywordLoc(), 1456480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1457480093f4SDimitry Andric Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement); 1458480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14595ffd83dbSDimitry Andric new (allocator()) syntax::DefaultStatement, S); 1460480093f4SDimitry Andric return true; 1461480093f4SDimitry Andric } 1462480093f4SDimitry Andric 1463480093f4SDimitry Andric bool WalkUpFromIfStmt(IfStmt *S) { 1464480093f4SDimitry Andric Builder.markChildToken(S->getIfLoc(), syntax::NodeRole::IntroducerKeyword); 1465fe6060f1SDimitry Andric Stmt *ConditionStatement = S->getCond(); 1466fe6060f1SDimitry Andric if (S->hasVarStorage()) 1467fe6060f1SDimitry Andric ConditionStatement = S->getConditionVariableDeclStmt(); 1468fe6060f1SDimitry Andric Builder.markStmtChild(ConditionStatement, syntax::NodeRole::Condition); 1469e8d8bef9SDimitry Andric Builder.markStmtChild(S->getThen(), syntax::NodeRole::ThenStatement); 1470e8d8bef9SDimitry Andric Builder.markChildToken(S->getElseLoc(), syntax::NodeRole::ElseKeyword); 1471e8d8bef9SDimitry Andric Builder.markStmtChild(S->getElse(), syntax::NodeRole::ElseStatement); 1472480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14735ffd83dbSDimitry Andric new (allocator()) syntax::IfStatement, S); 1474480093f4SDimitry Andric return true; 1475480093f4SDimitry Andric } 1476480093f4SDimitry Andric 1477480093f4SDimitry Andric bool WalkUpFromForStmt(ForStmt *S) { 1478480093f4SDimitry Andric Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword); 1479480093f4SDimitry Andric Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 1480480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14815ffd83dbSDimitry Andric new (allocator()) syntax::ForStatement, S); 1482480093f4SDimitry Andric return true; 1483480093f4SDimitry Andric } 1484480093f4SDimitry Andric 1485480093f4SDimitry Andric bool WalkUpFromWhileStmt(WhileStmt *S) { 1486480093f4SDimitry Andric Builder.markChildToken(S->getWhileLoc(), 1487480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1488480093f4SDimitry Andric Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 1489480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14905ffd83dbSDimitry Andric new (allocator()) syntax::WhileStatement, S); 1491480093f4SDimitry Andric return true; 1492480093f4SDimitry Andric } 1493480093f4SDimitry Andric 1494480093f4SDimitry Andric bool WalkUpFromContinueStmt(ContinueStmt *S) { 1495480093f4SDimitry Andric Builder.markChildToken(S->getContinueLoc(), 1496480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1497480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 14985ffd83dbSDimitry Andric new (allocator()) syntax::ContinueStatement, S); 1499480093f4SDimitry Andric return true; 1500480093f4SDimitry Andric } 1501480093f4SDimitry Andric 1502480093f4SDimitry Andric bool WalkUpFromBreakStmt(BreakStmt *S) { 1503480093f4SDimitry Andric Builder.markChildToken(S->getBreakLoc(), 1504480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1505480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 15065ffd83dbSDimitry Andric new (allocator()) syntax::BreakStatement, S); 1507480093f4SDimitry Andric return true; 1508480093f4SDimitry Andric } 1509480093f4SDimitry Andric 1510480093f4SDimitry Andric bool WalkUpFromReturnStmt(ReturnStmt *S) { 1511480093f4SDimitry Andric Builder.markChildToken(S->getReturnLoc(), 1512480093f4SDimitry Andric syntax::NodeRole::IntroducerKeyword); 1513e8d8bef9SDimitry Andric Builder.markExprChild(S->getRetValue(), syntax::NodeRole::ReturnValue); 1514480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 15155ffd83dbSDimitry Andric new (allocator()) syntax::ReturnStatement, S); 1516480093f4SDimitry Andric return true; 1517480093f4SDimitry Andric } 1518480093f4SDimitry Andric 1519480093f4SDimitry Andric bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S) { 1520480093f4SDimitry Andric Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword); 1521480093f4SDimitry Andric Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 1522480093f4SDimitry Andric Builder.foldNode(Builder.getStmtRange(S), 15235ffd83dbSDimitry Andric new (allocator()) syntax::RangeBasedForStatement, S); 1524480093f4SDimitry Andric return true; 1525480093f4SDimitry Andric } 1526480093f4SDimitry Andric 1527480093f4SDimitry Andric bool WalkUpFromEmptyDecl(EmptyDecl *S) { 15285ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15295ffd83dbSDimitry Andric new (allocator()) syntax::EmptyDeclaration, S); 1530480093f4SDimitry Andric return true; 1531480093f4SDimitry Andric } 1532480093f4SDimitry Andric 1533480093f4SDimitry Andric bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S) { 1534e8d8bef9SDimitry Andric Builder.markExprChild(S->getAssertExpr(), syntax::NodeRole::Condition); 1535e8d8bef9SDimitry Andric Builder.markExprChild(S->getMessage(), syntax::NodeRole::Message); 15365ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15375ffd83dbSDimitry Andric new (allocator()) syntax::StaticAssertDeclaration, S); 1538480093f4SDimitry Andric return true; 1539480093f4SDimitry Andric } 1540480093f4SDimitry Andric 1541480093f4SDimitry Andric bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) { 15425ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15435ffd83dbSDimitry Andric new (allocator()) syntax::LinkageSpecificationDeclaration, 15445ffd83dbSDimitry Andric S); 1545480093f4SDimitry Andric return true; 1546480093f4SDimitry Andric } 1547480093f4SDimitry Andric 1548480093f4SDimitry Andric bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) { 15495ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15505ffd83dbSDimitry Andric new (allocator()) syntax::NamespaceAliasDefinition, S); 1551480093f4SDimitry Andric return true; 1552480093f4SDimitry Andric } 1553480093f4SDimitry Andric 1554480093f4SDimitry Andric bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) { 15555ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15565ffd83dbSDimitry Andric new (allocator()) syntax::UsingNamespaceDirective, S); 1557480093f4SDimitry Andric return true; 1558480093f4SDimitry Andric } 1559480093f4SDimitry Andric 1560480093f4SDimitry Andric bool WalkUpFromUsingDecl(UsingDecl *S) { 15615ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15625ffd83dbSDimitry Andric new (allocator()) syntax::UsingDeclaration, S); 1563480093f4SDimitry Andric return true; 1564480093f4SDimitry Andric } 1565480093f4SDimitry Andric 1566480093f4SDimitry Andric bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) { 15675ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15685ffd83dbSDimitry Andric new (allocator()) syntax::UsingDeclaration, S); 1569480093f4SDimitry Andric return true; 1570480093f4SDimitry Andric } 1571480093f4SDimitry Andric 1572480093f4SDimitry Andric bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) { 15735ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15745ffd83dbSDimitry Andric new (allocator()) syntax::UsingDeclaration, S); 1575480093f4SDimitry Andric return true; 1576480093f4SDimitry Andric } 1577480093f4SDimitry Andric 1578480093f4SDimitry Andric bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) { 15795ffd83dbSDimitry Andric Builder.foldNode(Builder.getDeclarationRange(S), 15805ffd83dbSDimitry Andric new (allocator()) syntax::TypeAliasDeclaration, S); 1581480093f4SDimitry Andric return true; 1582480093f4SDimitry Andric } 1583480093f4SDimitry Andric 15840b57cec5SDimitry Andric private: 15855ffd83dbSDimitry Andric /// Folds SimpleDeclarator node (if present) and in case this is the last 15865ffd83dbSDimitry Andric /// declarator in the chain it also folds SimpleDeclaration node. 15875ffd83dbSDimitry Andric template <class T> bool processDeclaratorAndDeclaration(T *D) { 1588e8d8bef9SDimitry Andric auto Range = getDeclaratorRange( 1589e8d8bef9SDimitry Andric Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(), 1590e8d8bef9SDimitry Andric getQualifiedNameStart(D), getInitializerRange(D)); 15915ffd83dbSDimitry Andric 15925ffd83dbSDimitry Andric // There doesn't have to be a declarator (e.g. `void foo(int)` only has 15935ffd83dbSDimitry Andric // declaration, but no declarator). 1594e8d8bef9SDimitry Andric if (!Range.getBegin().isValid()) { 1595e8d8bef9SDimitry Andric Builder.markChild(new (allocator()) syntax::DeclaratorList, 1596e8d8bef9SDimitry Andric syntax::NodeRole::Declarators); 1597e8d8bef9SDimitry Andric Builder.foldNode(Builder.getDeclarationRange(D), 1598e8d8bef9SDimitry Andric new (allocator()) syntax::SimpleDeclaration, D); 1599e8d8bef9SDimitry Andric return true; 16005ffd83dbSDimitry Andric } 16015ffd83dbSDimitry Andric 1602e8d8bef9SDimitry Andric auto *N = new (allocator()) syntax::SimpleDeclarator; 1603e8d8bef9SDimitry Andric Builder.foldNode(Builder.getRange(Range), N, nullptr); 1604e8d8bef9SDimitry Andric Builder.markChild(N, syntax::NodeRole::ListElement); 1605e8d8bef9SDimitry Andric 1606e8d8bef9SDimitry Andric if (!Builder.isResponsibleForCreatingDeclaration(D)) { 1607e8d8bef9SDimitry Andric // If this is not the last declarator in the declaration we expect a 1608e8d8bef9SDimitry Andric // delimiter after it. 1609e8d8bef9SDimitry Andric const auto *DelimiterToken = std::next(Builder.findToken(Range.getEnd())); 1610e8d8bef9SDimitry Andric if (DelimiterToken->kind() == clang::tok::TokenKind::comma) 1611e8d8bef9SDimitry Andric Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter); 1612e8d8bef9SDimitry Andric } else { 1613e8d8bef9SDimitry Andric auto *DL = new (allocator()) syntax::DeclaratorList; 1614e8d8bef9SDimitry Andric auto DeclarationRange = Builder.getDeclarationRange(D); 1615e8d8bef9SDimitry Andric Builder.foldList(DeclarationRange, DL, nullptr); 1616e8d8bef9SDimitry Andric 1617e8d8bef9SDimitry Andric Builder.markChild(DL, syntax::NodeRole::Declarators); 1618e8d8bef9SDimitry Andric Builder.foldNode(DeclarationRange, 16195ffd83dbSDimitry Andric new (allocator()) syntax::SimpleDeclaration, D); 16205ffd83dbSDimitry Andric } 16215ffd83dbSDimitry Andric return true; 16225ffd83dbSDimitry Andric } 16235ffd83dbSDimitry Andric 16245ffd83dbSDimitry Andric /// Returns the range of the built node. 1625e8d8bef9SDimitry Andric syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) { 16265ffd83dbSDimitry Andric assert(L.getTypePtr()->hasTrailingReturn()); 16275ffd83dbSDimitry Andric 16285ffd83dbSDimitry Andric auto ReturnedType = L.getReturnLoc(); 16295ffd83dbSDimitry Andric // Build node for the declarator, if any. 1630e8d8bef9SDimitry Andric auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType), 1631e8d8bef9SDimitry Andric ReturnedType.getEndLoc()); 16325ffd83dbSDimitry Andric syntax::SimpleDeclarator *ReturnDeclarator = nullptr; 16335ffd83dbSDimitry Andric if (ReturnDeclaratorRange.isValid()) { 16345ffd83dbSDimitry Andric ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator; 16355ffd83dbSDimitry Andric Builder.foldNode(Builder.getRange(ReturnDeclaratorRange), 16365ffd83dbSDimitry Andric ReturnDeclarator, nullptr); 16375ffd83dbSDimitry Andric } 16385ffd83dbSDimitry Andric 16395ffd83dbSDimitry Andric // Build node for trailing return type. 16405ffd83dbSDimitry Andric auto Return = Builder.getRange(ReturnedType.getSourceRange()); 16415ffd83dbSDimitry Andric const auto *Arrow = Return.begin() - 1; 16425ffd83dbSDimitry Andric assert(Arrow->kind() == tok::arrow); 1643bdd1243dSDimitry Andric auto Tokens = llvm::ArrayRef(Arrow, Return.end()); 16445ffd83dbSDimitry Andric Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken); 16455ffd83dbSDimitry Andric if (ReturnDeclarator) 1646e8d8bef9SDimitry Andric Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator); 16475ffd83dbSDimitry Andric auto *R = new (allocator()) syntax::TrailingReturnType; 16485ffd83dbSDimitry Andric Builder.foldNode(Tokens, R, L); 16495ffd83dbSDimitry Andric return R; 16505ffd83dbSDimitry Andric } 16515ffd83dbSDimitry Andric 16525ffd83dbSDimitry Andric void foldExplicitTemplateInstantiation( 16535ffd83dbSDimitry Andric ArrayRef<syntax::Token> Range, const syntax::Token *ExternKW, 16545ffd83dbSDimitry Andric const syntax::Token *TemplateKW, 16555ffd83dbSDimitry Andric syntax::SimpleDeclaration *InnerDeclaration, Decl *From) { 16565ffd83dbSDimitry Andric assert(!ExternKW || ExternKW->kind() == tok::kw_extern); 16575ffd83dbSDimitry Andric assert(TemplateKW && TemplateKW->kind() == tok::kw_template); 16585ffd83dbSDimitry Andric Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword); 16595ffd83dbSDimitry Andric Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword); 1660e8d8bef9SDimitry Andric Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration); 16615ffd83dbSDimitry Andric Builder.foldNode( 16625ffd83dbSDimitry Andric Range, new (allocator()) syntax::ExplicitTemplateInstantiation, From); 16635ffd83dbSDimitry Andric } 16645ffd83dbSDimitry Andric 16655ffd83dbSDimitry Andric syntax::TemplateDeclaration *foldTemplateDeclaration( 16665ffd83dbSDimitry Andric ArrayRef<syntax::Token> Range, const syntax::Token *TemplateKW, 16675ffd83dbSDimitry Andric ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) { 16685ffd83dbSDimitry Andric assert(TemplateKW && TemplateKW->kind() == tok::kw_template); 16695ffd83dbSDimitry Andric Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword); 16705ffd83dbSDimitry Andric 16715ffd83dbSDimitry Andric auto *N = new (allocator()) syntax::TemplateDeclaration; 16725ffd83dbSDimitry Andric Builder.foldNode(Range, N, From); 1673e8d8bef9SDimitry Andric Builder.markChild(N, syntax::NodeRole::Declaration); 16745ffd83dbSDimitry Andric return N; 16755ffd83dbSDimitry Andric } 16765ffd83dbSDimitry Andric 16770b57cec5SDimitry Andric /// A small helper to save some typing. 16780b57cec5SDimitry Andric llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); } 16790b57cec5SDimitry Andric 16800b57cec5SDimitry Andric syntax::TreeBuilder &Builder; 16815ffd83dbSDimitry Andric const ASTContext &Context; 16820b57cec5SDimitry Andric }; 16830b57cec5SDimitry Andric } // namespace 16840b57cec5SDimitry Andric 16855ffd83dbSDimitry Andric void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) { 1686480093f4SDimitry Andric DeclsWithoutSemicolons.insert(D); 1687480093f4SDimitry Andric } 1688480093f4SDimitry Andric 1689480093f4SDimitry Andric void syntax::TreeBuilder::markChildToken(SourceLocation Loc, NodeRole Role) { 16900b57cec5SDimitry Andric if (Loc.isInvalid()) 16910b57cec5SDimitry Andric return; 16920b57cec5SDimitry Andric Pending.assignRole(*findToken(Loc), Role); 16930b57cec5SDimitry Andric } 16940b57cec5SDimitry Andric 16955ffd83dbSDimitry Andric void syntax::TreeBuilder::markChildToken(const syntax::Token *T, NodeRole R) { 16965ffd83dbSDimitry Andric if (!T) 16975ffd83dbSDimitry Andric return; 16985ffd83dbSDimitry Andric Pending.assignRole(*T, R); 16995ffd83dbSDimitry Andric } 17005ffd83dbSDimitry Andric 17015ffd83dbSDimitry Andric void syntax::TreeBuilder::markChild(syntax::Node *N, NodeRole R) { 17025ffd83dbSDimitry Andric assert(N); 17035ffd83dbSDimitry Andric setRole(N, R); 17045ffd83dbSDimitry Andric } 17055ffd83dbSDimitry Andric 17065ffd83dbSDimitry Andric void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) { 17075ffd83dbSDimitry Andric auto *SN = Mapping.find(N); 17085ffd83dbSDimitry Andric assert(SN != nullptr); 17095ffd83dbSDimitry Andric setRole(SN, R); 17105ffd83dbSDimitry Andric } 1711e8d8bef9SDimitry Andric void syntax::TreeBuilder::markChild(NestedNameSpecifierLoc NNSLoc, NodeRole R) { 1712e8d8bef9SDimitry Andric auto *SN = Mapping.find(NNSLoc); 1713e8d8bef9SDimitry Andric assert(SN != nullptr); 1714e8d8bef9SDimitry Andric setRole(SN, R); 1715e8d8bef9SDimitry Andric } 17165ffd83dbSDimitry Andric 1717480093f4SDimitry Andric void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) { 1718480093f4SDimitry Andric if (!Child) 1719480093f4SDimitry Andric return; 1720480093f4SDimitry Andric 17215ffd83dbSDimitry Andric syntax::Tree *ChildNode; 17225ffd83dbSDimitry Andric if (Expr *ChildExpr = dyn_cast<Expr>(Child)) { 1723480093f4SDimitry Andric // This is an expression in a statement position, consume the trailing 1724480093f4SDimitry Andric // semicolon and form an 'ExpressionStatement' node. 1725e8d8bef9SDimitry Andric markExprChild(ChildExpr, NodeRole::Expression); 17265ffd83dbSDimitry Andric ChildNode = new (allocator()) syntax::ExpressionStatement; 17275ffd83dbSDimitry Andric // (!) 'getStmtRange()' ensures this covers a trailing semicolon. 1728fcaf7f86SDimitry Andric Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode); 17295ffd83dbSDimitry Andric } else { 17305ffd83dbSDimitry Andric ChildNode = Mapping.find(Child); 1731480093f4SDimitry Andric } 17325ffd83dbSDimitry Andric assert(ChildNode != nullptr); 17335ffd83dbSDimitry Andric setRole(ChildNode, Role); 1734480093f4SDimitry Andric } 1735480093f4SDimitry Andric 1736480093f4SDimitry Andric void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) { 1737480093f4SDimitry Andric if (!Child) 1738480093f4SDimitry Andric return; 1739e8d8bef9SDimitry Andric Child = IgnoreImplicit(Child); 1740480093f4SDimitry Andric 17415ffd83dbSDimitry Andric syntax::Tree *ChildNode = Mapping.find(Child); 17425ffd83dbSDimitry Andric assert(ChildNode != nullptr); 17435ffd83dbSDimitry Andric setRole(ChildNode, Role); 1744480093f4SDimitry Andric } 1745480093f4SDimitry Andric 17460b57cec5SDimitry Andric const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const { 17475ffd83dbSDimitry Andric if (L.isInvalid()) 17485ffd83dbSDimitry Andric return nullptr; 1749e8d8bef9SDimitry Andric auto It = LocationToToken.find(L); 1750480093f4SDimitry Andric assert(It != LocationToToken.end()); 1751480093f4SDimitry Andric return It->second; 17520b57cec5SDimitry Andric } 17530b57cec5SDimitry Andric 1754e8d8bef9SDimitry Andric syntax::TranslationUnit *syntax::buildSyntaxTree(Arena &A, 1755fcaf7f86SDimitry Andric TokenBufferTokenManager& TBTM, 1756e8d8bef9SDimitry Andric ASTContext &Context) { 1757fcaf7f86SDimitry Andric TreeBuilder Builder(A, TBTM); 1758e8d8bef9SDimitry Andric BuildTreeVisitor(Context, Builder).TraverseAST(Context); 17590b57cec5SDimitry Andric return std::move(Builder).finalize(); 17600b57cec5SDimitry Andric } 1761