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"
16af732203SDimitry Andric #include "clang/AST/IgnoreExpr.h"
17af732203SDimitry 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"
300b57cec5SDimitry Andric #include "clang/Tooling/Syntax/Tokens.h"
310b57cec5SDimitry Andric #include "clang/Tooling/Syntax/Tree.h"
320b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
335ffd83dbSDimitry Andric #include "llvm/ADT/DenseMap.h"
345ffd83dbSDimitry Andric #include "llvm/ADT/PointerUnion.h"
350b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
365ffd83dbSDimitry Andric #include "llvm/ADT/ScopeExit.h"
370b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
380b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
390b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
40480093f4SDimitry Andric #include "llvm/Support/Compiler.h"
410b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h"
42480093f4SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
430b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
445ffd83dbSDimitry Andric #include <cstddef>
450b57cec5SDimitry Andric #include <map>
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric using namespace clang;
480b57cec5SDimitry Andric 
49af732203SDimitry Andric // Ignores the implicit `CXXConstructExpr` for copy/move constructor calls
50af732203SDimitry Andric // generated by the compiler, as well as in implicit conversions like the one
51af732203SDimitry Andric // wrapping `1` in `X x = 1;`.
IgnoreImplicitConstructorSingleStep(Expr * E)52af732203SDimitry Andric static Expr *IgnoreImplicitConstructorSingleStep(Expr *E) {
53af732203SDimitry Andric   if (auto *C = dyn_cast<CXXConstructExpr>(E)) {
54af732203SDimitry Andric     auto NumArgs = C->getNumArgs();
55af732203SDimitry Andric     if (NumArgs == 1 || (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) {
56af732203SDimitry Andric       Expr *A = C->getArg(0);
57af732203SDimitry Andric       if (C->getParenOrBraceRange().isInvalid())
58af732203SDimitry Andric         return A;
59af732203SDimitry Andric     }
60af732203SDimitry Andric   }
61af732203SDimitry Andric   return E;
62af732203SDimitry Andric }
63af732203SDimitry Andric 
64af732203SDimitry Andric // In:
65af732203SDimitry Andric // struct X {
66af732203SDimitry Andric //   X(int)
67af732203SDimitry Andric // };
68af732203SDimitry Andric // X x = X(1);
69af732203SDimitry Andric // Ignores the implicit `CXXFunctionalCastExpr` that wraps
70af732203SDimitry Andric // `CXXConstructExpr X(1)`.
IgnoreCXXFunctionalCastExprWrappingConstructor(Expr * E)71af732203SDimitry Andric static Expr *IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E) {
72af732203SDimitry Andric   if (auto *F = dyn_cast<CXXFunctionalCastExpr>(E)) {
73af732203SDimitry Andric     if (F->getCastKind() == CK_ConstructorConversion)
74af732203SDimitry Andric       return F->getSubExpr();
75af732203SDimitry Andric   }
76af732203SDimitry Andric   return E;
77af732203SDimitry Andric }
78af732203SDimitry Andric 
IgnoreImplicit(Expr * E)79af732203SDimitry Andric static Expr *IgnoreImplicit(Expr *E) {
80af732203SDimitry Andric   return IgnoreExprNodes(E, IgnoreImplicitSingleStep,
81af732203SDimitry Andric                          IgnoreImplicitConstructorSingleStep,
82af732203SDimitry Andric                          IgnoreCXXFunctionalCastExprWrappingConstructor);
83af732203SDimitry Andric }
84af732203SDimitry Andric 
85480093f4SDimitry Andric LLVM_ATTRIBUTE_UNUSED
isImplicitExpr(Expr * E)86af732203SDimitry Andric static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; }
87480093f4SDimitry Andric 
885ffd83dbSDimitry Andric namespace {
895ffd83dbSDimitry Andric /// Get start location of the Declarator from the TypeLoc.
905ffd83dbSDimitry Andric /// E.g.:
915ffd83dbSDimitry Andric ///   loc of `(` in `int (a)`
925ffd83dbSDimitry Andric ///   loc of `*` in `int *(a)`
935ffd83dbSDimitry Andric ///   loc of the first `(` in `int (*a)(int)`
945ffd83dbSDimitry Andric ///   loc of the `*` in `int *(a)(int)`
955ffd83dbSDimitry Andric ///   loc of the first `*` in `const int *const *volatile a;`
965ffd83dbSDimitry Andric ///
975ffd83dbSDimitry Andric /// It is non-trivial to get the start location because TypeLocs are stored
985ffd83dbSDimitry Andric /// inside out. In the example above `*volatile` is the TypeLoc returned
995ffd83dbSDimitry Andric /// by `Decl.getTypeSourceInfo()`, and `*const` is what `.getPointeeLoc()`
1005ffd83dbSDimitry Andric /// returns.
1015ffd83dbSDimitry Andric struct GetStartLoc : TypeLocVisitor<GetStartLoc, SourceLocation> {
VisitParenTypeLoc__anonbca4b38f0111::GetStartLoc1025ffd83dbSDimitry Andric   SourceLocation VisitParenTypeLoc(ParenTypeLoc T) {
1035ffd83dbSDimitry Andric     auto L = Visit(T.getInnerLoc());
1045ffd83dbSDimitry Andric     if (L.isValid())
1055ffd83dbSDimitry Andric       return L;
1065ffd83dbSDimitry Andric     return T.getLParenLoc();
1075ffd83dbSDimitry Andric   }
1085ffd83dbSDimitry Andric 
1095ffd83dbSDimitry Andric   // Types spelled in the prefix part of the declarator.
VisitPointerTypeLoc__anonbca4b38f0111::GetStartLoc1105ffd83dbSDimitry Andric   SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) {
1115ffd83dbSDimitry Andric     return HandlePointer(T);
1125ffd83dbSDimitry Andric   }
1135ffd83dbSDimitry Andric 
VisitMemberPointerTypeLoc__anonbca4b38f0111::GetStartLoc1145ffd83dbSDimitry Andric   SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
1155ffd83dbSDimitry Andric     return HandlePointer(T);
1165ffd83dbSDimitry Andric   }
1175ffd83dbSDimitry Andric 
VisitBlockPointerTypeLoc__anonbca4b38f0111::GetStartLoc1185ffd83dbSDimitry Andric   SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
1195ffd83dbSDimitry Andric     return HandlePointer(T);
1205ffd83dbSDimitry Andric   }
1215ffd83dbSDimitry Andric 
VisitReferenceTypeLoc__anonbca4b38f0111::GetStartLoc1225ffd83dbSDimitry Andric   SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) {
1235ffd83dbSDimitry Andric     return HandlePointer(T);
1245ffd83dbSDimitry Andric   }
1255ffd83dbSDimitry Andric 
VisitObjCObjectPointerTypeLoc__anonbca4b38f0111::GetStartLoc1265ffd83dbSDimitry Andric   SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) {
1275ffd83dbSDimitry Andric     return HandlePointer(T);
1285ffd83dbSDimitry Andric   }
1295ffd83dbSDimitry Andric 
1305ffd83dbSDimitry Andric   // All other cases are not important, as they are either part of declaration
1315ffd83dbSDimitry Andric   // specifiers (e.g. inheritors of TypeSpecTypeLoc) or introduce modifiers on
1325ffd83dbSDimitry Andric   // existing declarators (e.g. QualifiedTypeLoc). They cannot start the
1335ffd83dbSDimitry Andric   // declarator themselves, but their underlying type can.
VisitTypeLoc__anonbca4b38f0111::GetStartLoc1345ffd83dbSDimitry Andric   SourceLocation VisitTypeLoc(TypeLoc T) {
1355ffd83dbSDimitry Andric     auto N = T.getNextTypeLoc();
1365ffd83dbSDimitry Andric     if (!N)
1375ffd83dbSDimitry Andric       return SourceLocation();
1385ffd83dbSDimitry Andric     return Visit(N);
1395ffd83dbSDimitry Andric   }
1405ffd83dbSDimitry Andric 
VisitFunctionProtoTypeLoc__anonbca4b38f0111::GetStartLoc1415ffd83dbSDimitry Andric   SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) {
1425ffd83dbSDimitry Andric     if (T.getTypePtr()->hasTrailingReturn())
1435ffd83dbSDimitry Andric       return SourceLocation(); // avoid recursing into the suffix of declarator.
1445ffd83dbSDimitry Andric     return VisitTypeLoc(T);
1455ffd83dbSDimitry Andric   }
1465ffd83dbSDimitry Andric 
1475ffd83dbSDimitry Andric private:
HandlePointer__anonbca4b38f0111::GetStartLoc1485ffd83dbSDimitry Andric   template <class PtrLoc> SourceLocation HandlePointer(PtrLoc T) {
1495ffd83dbSDimitry Andric     auto L = Visit(T.getPointeeLoc());
1505ffd83dbSDimitry Andric     if (L.isValid())
1515ffd83dbSDimitry Andric       return L;
1525ffd83dbSDimitry Andric     return T.getLocalSourceRange().getBegin();
1535ffd83dbSDimitry Andric   }
1545ffd83dbSDimitry Andric };
1555ffd83dbSDimitry Andric } // namespace
1565ffd83dbSDimitry Andric 
dropDefaultArgs(CallExpr::arg_range Args)157af732203SDimitry Andric static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args) {
158af732203SDimitry Andric   auto FirstDefaultArg = std::find_if(Args.begin(), Args.end(), [](auto It) {
159af732203SDimitry Andric     return isa<CXXDefaultArgExpr>(It);
160af732203SDimitry Andric   });
161af732203SDimitry Andric   return llvm::make_range(Args.begin(), FirstDefaultArg);
162af732203SDimitry Andric }
163af732203SDimitry Andric 
getOperatorNodeKind(const CXXOperatorCallExpr & E)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;
235af732203SDimitry Andric   case OO_Call:
236af732203SDimitry 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 
245af732203SDimitry Andric /// Get the start of the qualified name. In the examples below it gives the
246af732203SDimitry Andric /// location of the `^`:
247af732203SDimitry Andric ///     `int ^a;`
248af732203SDimitry Andric ///     `int *^a;`
249af732203SDimitry Andric ///     `int ^a::S::f(){}`
getQualifiedNameStart(NamedDecl * D)250af732203SDimitry Andric static SourceLocation getQualifiedNameStart(NamedDecl *D) {
251af732203SDimitry Andric   assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) &&
252af732203SDimitry Andric          "only DeclaratorDecl and TypedefNameDecl are supported.");
253af732203SDimitry Andric 
254af732203SDimitry Andric   auto DN = D->getDeclName();
255af732203SDimitry Andric   bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo();
256af732203SDimitry Andric   if (IsAnonymous)
257af732203SDimitry Andric     return SourceLocation();
258af732203SDimitry Andric 
259af732203SDimitry Andric   if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
260af732203SDimitry Andric     if (DD->getQualifierLoc()) {
261af732203SDimitry Andric       return DD->getQualifierLoc().getBeginLoc();
262af732203SDimitry Andric     }
263af732203SDimitry Andric   }
264af732203SDimitry Andric 
265af732203SDimitry Andric   return D->getLocation();
266af732203SDimitry Andric }
267af732203SDimitry Andric 
268af732203SDimitry Andric /// Gets the range of the initializer inside an init-declarator C++ [dcl.decl].
269af732203SDimitry Andric ///     `int a;` -> range of ``,
270af732203SDimitry Andric ///     `int *a = nullptr` -> range of `= nullptr`.
271af732203SDimitry Andric ///     `int a{}` -> range of `{}`.
272af732203SDimitry Andric ///     `int a()` -> range of `()`.
getInitializerRange(Decl * D)273af732203SDimitry Andric static SourceRange getInitializerRange(Decl *D) {
274af732203SDimitry Andric   if (auto *V = dyn_cast<VarDecl>(D)) {
275af732203SDimitry Andric     auto *I = V->getInit();
276af732203SDimitry Andric     // Initializers in range-based-for are not part of the declarator
277af732203SDimitry Andric     if (I && !V->isCXXForRangeDecl())
278af732203SDimitry Andric       return I->getSourceRange();
279af732203SDimitry Andric   }
280af732203SDimitry Andric 
281af732203SDimitry Andric   return SourceRange();
282af732203SDimitry Andric }
283af732203SDimitry 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`.
290af732203SDimitry Andric ///     `int S::f(){}` -> range of `S::f()`.
291af732203SDimitry Andric /// FIXME: \p Name must be a source range.
getDeclaratorRange(const SourceManager & SM,TypeLoc T,SourceLocation Name,SourceRange Initializer)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);
296af732203SDimitry Andric   SourceLocation End = T.getEndLoc();
2975ffd83dbSDimitry Andric   if (Name.isValid()) {
2985ffd83dbSDimitry Andric     if (Start.isInvalid())
2995ffd83dbSDimitry Andric       Start = Name;
300*5f7ddb14SDimitry Andric     // End of TypeLoc could be invalid if the type is invalid, fallback to the
301*5f7ddb14SDimitry Andric     // NameLoc.
302*5f7ddb14SDimitry 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:
add(ASTPtr From,syntax::Tree * To)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 
add(NestedNameSpecifierLoc From,syntax::Tree * To)331af732203SDimitry Andric   void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
332af732203SDimitry Andric     assert(To != nullptr);
333af732203SDimitry Andric     assert(From.hasQualifier());
334af732203SDimitry Andric 
335af732203SDimitry Andric     bool Added = NNSNodes.insert({From, To}).second;
336af732203SDimitry Andric     (void)Added;
337af732203SDimitry Andric     assert(Added && "mapping added twice");
338af732203SDimitry Andric   }
339af732203SDimitry Andric 
find(ASTPtr P) const3405ffd83dbSDimitry Andric   syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }
3415ffd83dbSDimitry Andric 
find(NestedNameSpecifierLoc P) const342af732203SDimitry Andric   syntax::Tree *find(NestedNameSpecifierLoc P) const {
343af732203SDimitry Andric     return NNSNodes.lookup(P);
344af732203SDimitry Andric   }
345af732203SDimitry Andric 
3465ffd83dbSDimitry Andric private:
3475ffd83dbSDimitry Andric   llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes;
348af732203SDimitry 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:
TreeBuilder(syntax::Arena & Arena)369480093f4SDimitry Andric   TreeBuilder(syntax::Arena &Arena) : Arena(Arena), Pending(Arena) {
370af732203SDimitry Andric     for (const auto &T : Arena.getTokenBuffer().expandedTokens())
371af732203SDimitry Andric       LocationToToken.insert({T.location(), &T});
372480093f4SDimitry Andric   }
3730b57cec5SDimitry Andric 
allocator()374af732203SDimitry Andric   llvm::BumpPtrAllocator &allocator() { return Arena.getAllocator(); }
sourceManager() const375af732203SDimitry Andric   const SourceManager &sourceManager() const {
376af732203SDimitry Andric     return Arena.getSourceManager();
377af732203SDimitry Andric   }
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   /// Populate children for \p New node, assuming it covers tokens from \p
3800b57cec5SDimitry Andric   /// Range.
foldNode(ArrayRef<syntax::Token> Range,syntax::Tree * New,ASTPtr From)381af732203SDimitry Andric   void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, ASTPtr From) {
3825ffd83dbSDimitry Andric     assert(New);
3835ffd83dbSDimitry Andric     Pending.foldChildren(Arena, Range, New);
3845ffd83dbSDimitry Andric     if (From)
3855ffd83dbSDimitry Andric       Mapping.add(From, New);
3865ffd83dbSDimitry Andric   }
387af732203SDimitry Andric 
foldNode(ArrayRef<syntax::Token> Range,syntax::Tree * New,TypeLoc L)388af732203SDimitry Andric   void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, TypeLoc L) {
3895ffd83dbSDimitry Andric     // FIXME: add mapping for TypeLocs
3905ffd83dbSDimitry Andric     foldNode(Range, New, nullptr);
3915ffd83dbSDimitry Andric   }
392480093f4SDimitry Andric 
foldNode(llvm::ArrayRef<syntax::Token> Range,syntax::Tree * New,NestedNameSpecifierLoc From)393af732203SDimitry Andric   void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New,
394af732203SDimitry Andric                 NestedNameSpecifierLoc From) {
395af732203SDimitry Andric     assert(New);
396af732203SDimitry Andric     Pending.foldChildren(Arena, Range, New);
397af732203SDimitry Andric     if (From)
398af732203SDimitry Andric       Mapping.add(From, New);
399af732203SDimitry Andric   }
400af732203SDimitry Andric 
401af732203SDimitry Andric   /// Populate children for \p New list, assuming it covers tokens from a
402af732203SDimitry Andric   /// subrange of \p SuperRange.
foldList(ArrayRef<syntax::Token> SuperRange,syntax::List * New,ASTPtr From)403af732203SDimitry Andric   void foldList(ArrayRef<syntax::Token> SuperRange, syntax::List *New,
404af732203SDimitry Andric                 ASTPtr From) {
405af732203SDimitry Andric     assert(New);
406af732203SDimitry Andric     auto ListRange = Pending.shrinkToFitList(SuperRange);
407af732203SDimitry Andric     Pending.foldChildren(Arena, ListRange, New);
408af732203SDimitry Andric     if (From)
409af732203SDimitry Andric       Mapping.add(From, New);
410af732203SDimitry Andric   }
411af732203SDimitry Andric 
412480093f4SDimitry Andric   /// Notifies that we should not consume trailing semicolon when computing
413480093f4SDimitry Andric   /// token range of \p D.
4145ffd83dbSDimitry Andric   void noticeDeclWithoutSemicolon(Decl *D);
415480093f4SDimitry Andric 
416480093f4SDimitry Andric   /// Mark the \p Child node with a corresponding \p Role. All marked children
417480093f4SDimitry Andric   /// should be consumed by foldNode.
4185ffd83dbSDimitry Andric   /// When called on expressions (clang::Expr is derived from clang::Stmt),
419480093f4SDimitry Andric   /// wraps expressions into expression statement.
420480093f4SDimitry Andric   void markStmtChild(Stmt *Child, NodeRole Role);
421480093f4SDimitry Andric   /// Should be called for expressions in non-statement position to avoid
422480093f4SDimitry Andric   /// wrapping into expression statement.
423480093f4SDimitry Andric   void markExprChild(Expr *Child, NodeRole Role);
4240b57cec5SDimitry Andric   /// Set role for a token starting at \p Loc.
425480093f4SDimitry Andric   void markChildToken(SourceLocation Loc, NodeRole R);
4265ffd83dbSDimitry Andric   /// Set role for \p T.
4275ffd83dbSDimitry Andric   void markChildToken(const syntax::Token *T, NodeRole R);
4285ffd83dbSDimitry Andric 
4295ffd83dbSDimitry Andric   /// Set role for \p N.
4305ffd83dbSDimitry Andric   void markChild(syntax::Node *N, NodeRole R);
4315ffd83dbSDimitry Andric   /// Set role for the syntax node matching \p N.
4325ffd83dbSDimitry Andric   void markChild(ASTPtr N, NodeRole R);
433af732203SDimitry Andric   /// Set role for the syntax node matching \p N.
434af732203SDimitry Andric   void markChild(NestedNameSpecifierLoc N, NodeRole R);
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   /// Finish building the tree and consume the root node.
finalize()4370b57cec5SDimitry Andric   syntax::TranslationUnit *finalize() && {
438af732203SDimitry Andric     auto Tokens = Arena.getTokenBuffer().expandedTokens();
439a7dea167SDimitry Andric     assert(!Tokens.empty());
440a7dea167SDimitry Andric     assert(Tokens.back().kind() == tok::eof);
441a7dea167SDimitry Andric 
4420b57cec5SDimitry Andric     // Build the root of the tree, consuming all the children.
443480093f4SDimitry Andric     Pending.foldChildren(Arena, Tokens.drop_back(),
444af732203SDimitry Andric                          new (Arena.getAllocator()) syntax::TranslationUnit);
4450b57cec5SDimitry Andric 
446480093f4SDimitry Andric     auto *TU = cast<syntax::TranslationUnit>(std::move(Pending).finalize());
447480093f4SDimitry Andric     TU->assertInvariantsRecursive();
448480093f4SDimitry Andric     return TU;
4490b57cec5SDimitry Andric   }
4500b57cec5SDimitry Andric 
4515ffd83dbSDimitry Andric   /// Finds a token starting at \p L. The token must exist if \p L is valid.
4525ffd83dbSDimitry Andric   const syntax::Token *findToken(SourceLocation L) const;
4535ffd83dbSDimitry Andric 
4545ffd83dbSDimitry Andric   /// Finds the syntax tokens corresponding to the \p SourceRange.
getRange(SourceRange Range) const455af732203SDimitry Andric   ArrayRef<syntax::Token> getRange(SourceRange Range) const {
4565ffd83dbSDimitry Andric     assert(Range.isValid());
4575ffd83dbSDimitry Andric     return getRange(Range.getBegin(), Range.getEnd());
4585ffd83dbSDimitry Andric   }
4595ffd83dbSDimitry Andric 
4605ffd83dbSDimitry Andric   /// Finds the syntax tokens corresponding to the passed source locations.
4610b57cec5SDimitry Andric   /// \p First is the start position of the first token and \p Last is the start
4620b57cec5SDimitry Andric   /// position of the last token.
getRange(SourceLocation First,SourceLocation Last) const463af732203SDimitry Andric   ArrayRef<syntax::Token> getRange(SourceLocation First,
4640b57cec5SDimitry Andric                                    SourceLocation Last) const {
4650b57cec5SDimitry Andric     assert(First.isValid());
4660b57cec5SDimitry Andric     assert(Last.isValid());
4670b57cec5SDimitry Andric     assert(First == Last ||
468af732203SDimitry Andric            Arena.getSourceManager().isBeforeInTranslationUnit(First, Last));
4690b57cec5SDimitry Andric     return llvm::makeArrayRef(findToken(First), std::next(findToken(Last)));
4700b57cec5SDimitry Andric   }
4715ffd83dbSDimitry Andric 
472af732203SDimitry Andric   ArrayRef<syntax::Token>
getTemplateRange(const ClassTemplateSpecializationDecl * D) const4735ffd83dbSDimitry Andric   getTemplateRange(const ClassTemplateSpecializationDecl *D) const {
4745ffd83dbSDimitry Andric     auto Tokens = getRange(D->getSourceRange());
4755ffd83dbSDimitry Andric     return maybeAppendSemicolon(Tokens, D);
4760b57cec5SDimitry Andric   }
4775ffd83dbSDimitry Andric 
4785ffd83dbSDimitry Andric   /// Returns true if \p D is the last declarator in a chain and is thus
4795ffd83dbSDimitry Andric   /// reponsible for creating SimpleDeclaration for the whole chain.
isResponsibleForCreatingDeclaration(const Decl * D) const480af732203SDimitry Andric   bool isResponsibleForCreatingDeclaration(const Decl *D) const {
481af732203SDimitry Andric     assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) &&
4825ffd83dbSDimitry Andric            "only DeclaratorDecl and TypedefNameDecl are supported.");
4835ffd83dbSDimitry Andric 
4845ffd83dbSDimitry Andric     const Decl *Next = D->getNextDeclInContext();
4855ffd83dbSDimitry Andric 
4865ffd83dbSDimitry Andric     // There's no next sibling, this one is responsible.
4875ffd83dbSDimitry Andric     if (Next == nullptr) {
4885ffd83dbSDimitry Andric       return true;
4895ffd83dbSDimitry Andric     }
4905ffd83dbSDimitry Andric 
4915ffd83dbSDimitry Andric     // Next sibling is not the same type, this one is responsible.
492af732203SDimitry Andric     if (D->getKind() != Next->getKind()) {
4935ffd83dbSDimitry Andric       return true;
4945ffd83dbSDimitry Andric     }
4955ffd83dbSDimitry Andric     // Next sibling doesn't begin at the same loc, it must be a different
4965ffd83dbSDimitry Andric     // declaration, so this declarator is responsible.
497af732203SDimitry Andric     if (Next->getBeginLoc() != D->getBeginLoc()) {
4985ffd83dbSDimitry Andric       return true;
4995ffd83dbSDimitry Andric     }
5005ffd83dbSDimitry Andric 
5015ffd83dbSDimitry Andric     // NextT is a member of the same declaration, and we need the last member to
5025ffd83dbSDimitry Andric     // create declaration. This one is not responsible.
5035ffd83dbSDimitry Andric     return false;
5045ffd83dbSDimitry Andric   }
5055ffd83dbSDimitry Andric 
getDeclarationRange(Decl * D)506af732203SDimitry Andric   ArrayRef<syntax::Token> getDeclarationRange(Decl *D) {
507af732203SDimitry Andric     ArrayRef<syntax::Token> Tokens;
5085ffd83dbSDimitry Andric     // We want to drop the template parameters for specializations.
509af732203SDimitry Andric     if (const auto *S = dyn_cast<TagDecl>(D))
5105ffd83dbSDimitry Andric       Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());
5115ffd83dbSDimitry Andric     else
5125ffd83dbSDimitry Andric       Tokens = getRange(D->getSourceRange());
5135ffd83dbSDimitry Andric     return maybeAppendSemicolon(Tokens, D);
5145ffd83dbSDimitry Andric   }
5155ffd83dbSDimitry Andric 
getExprRange(const Expr * E) const516af732203SDimitry Andric   ArrayRef<syntax::Token> getExprRange(const Expr *E) const {
5175ffd83dbSDimitry Andric     return getRange(E->getSourceRange());
518480093f4SDimitry Andric   }
5195ffd83dbSDimitry Andric 
520480093f4SDimitry Andric   /// Find the adjusted range for the statement, consuming the trailing
521480093f4SDimitry Andric   /// semicolon when needed.
getStmtRange(const Stmt * S) const522af732203SDimitry Andric   ArrayRef<syntax::Token> getStmtRange(const Stmt *S) const {
5235ffd83dbSDimitry Andric     auto Tokens = getRange(S->getSourceRange());
524480093f4SDimitry Andric     if (isa<CompoundStmt>(S))
525480093f4SDimitry Andric       return Tokens;
526480093f4SDimitry Andric 
527480093f4SDimitry Andric     // Some statements miss a trailing semicolon, e.g. 'return', 'continue' and
528480093f4SDimitry Andric     // all statements that end with those. Consume this semicolon here.
529480093f4SDimitry Andric     if (Tokens.back().kind() == tok::semi)
530480093f4SDimitry Andric       return Tokens;
531480093f4SDimitry Andric     return withTrailingSemicolon(Tokens);
5320b57cec5SDimitry Andric   }
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric private:
maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,const Decl * D) const535af732203SDimitry Andric   ArrayRef<syntax::Token> maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,
5365ffd83dbSDimitry Andric                                                const Decl *D) const {
537af732203SDimitry Andric     if (isa<NamespaceDecl>(D))
5385ffd83dbSDimitry Andric       return Tokens;
5395ffd83dbSDimitry Andric     if (DeclsWithoutSemicolons.count(D))
5405ffd83dbSDimitry Andric       return Tokens;
5415ffd83dbSDimitry Andric     // FIXME: do not consume trailing semicolon on function definitions.
5425ffd83dbSDimitry Andric     // Most declarations own a semicolon in syntax trees, but not in clang AST.
5435ffd83dbSDimitry Andric     return withTrailingSemicolon(Tokens);
5445ffd83dbSDimitry Andric   }
5455ffd83dbSDimitry Andric 
546af732203SDimitry Andric   ArrayRef<syntax::Token>
withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const547af732203SDimitry Andric   withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const {
548480093f4SDimitry Andric     assert(!Tokens.empty());
549480093f4SDimitry Andric     assert(Tokens.back().kind() != tok::eof);
5505ffd83dbSDimitry Andric     // We never consume 'eof', so looking at the next token is ok.
551480093f4SDimitry Andric     if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi)
552480093f4SDimitry Andric       return llvm::makeArrayRef(Tokens.begin(), Tokens.end() + 1);
553480093f4SDimitry Andric     return Tokens;
554480093f4SDimitry Andric   }
555480093f4SDimitry Andric 
setRole(syntax::Node * N,NodeRole R)5565ffd83dbSDimitry Andric   void setRole(syntax::Node *N, NodeRole R) {
557af732203SDimitry Andric     assert(N->getRole() == NodeRole::Detached);
5585ffd83dbSDimitry Andric     N->setRole(R);
5595ffd83dbSDimitry Andric   }
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   /// A collection of trees covering the input tokens.
5620b57cec5SDimitry Andric   /// When created, each tree corresponds to a single token in the file.
5630b57cec5SDimitry Andric   /// Clients call 'foldChildren' to attach one or more subtrees to a parent
5640b57cec5SDimitry Andric   /// node and update the list of trees accordingly.
5650b57cec5SDimitry Andric   ///
5660b57cec5SDimitry Andric   /// Ensures that added nodes properly nest and cover the whole token stream.
5670b57cec5SDimitry Andric   struct Forest {
Forestsyntax::TreeBuilder::Forest5680b57cec5SDimitry Andric     Forest(syntax::Arena &A) {
569af732203SDimitry Andric       assert(!A.getTokenBuffer().expandedTokens().empty());
570af732203SDimitry Andric       assert(A.getTokenBuffer().expandedTokens().back().kind() == tok::eof);
5710b57cec5SDimitry Andric       // Create all leaf nodes.
572a7dea167SDimitry Andric       // Note that we do not have 'eof' in the tree.
573af732203SDimitry Andric       for (const auto &T : A.getTokenBuffer().expandedTokens().drop_back()) {
574af732203SDimitry Andric         auto *L = new (A.getAllocator()) syntax::Leaf(&T);
575480093f4SDimitry Andric         L->Original = true;
576af732203SDimitry Andric         L->CanModify = A.getTokenBuffer().spelledForExpanded(T).hasValue();
5775ffd83dbSDimitry Andric         Trees.insert(Trees.end(), {&T, L});
5780b57cec5SDimitry Andric       }
579480093f4SDimitry Andric     }
580480093f4SDimitry Andric 
assignRolesyntax::TreeBuilder::Forest581af732203SDimitry Andric     void assignRole(ArrayRef<syntax::Token> Range, syntax::NodeRole Role) {
5820b57cec5SDimitry Andric       assert(!Range.empty());
5830b57cec5SDimitry Andric       auto It = Trees.lower_bound(Range.begin());
5840b57cec5SDimitry Andric       assert(It != Trees.end() && "no node found");
5850b57cec5SDimitry Andric       assert(It->first == Range.begin() && "no child with the specified range");
5860b57cec5SDimitry Andric       assert((std::next(It) == Trees.end() ||
5870b57cec5SDimitry Andric               std::next(It)->first == Range.end()) &&
5880b57cec5SDimitry Andric              "no child with the specified range");
589af732203SDimitry Andric       assert(It->second->getRole() == NodeRole::Detached &&
5905ffd83dbSDimitry Andric              "re-assigning role for a child");
5915ffd83dbSDimitry Andric       It->second->setRole(Role);
5920b57cec5SDimitry Andric     }
5930b57cec5SDimitry Andric 
594af732203SDimitry Andric     /// Shrink \p Range to a subrange that only contains tokens of a list.
595af732203SDimitry Andric     /// List elements and delimiters should already have correct roles.
shrinkToFitListsyntax::TreeBuilder::Forest596af732203SDimitry Andric     ArrayRef<syntax::Token> shrinkToFitList(ArrayRef<syntax::Token> Range) {
597af732203SDimitry Andric       auto BeginChildren = Trees.lower_bound(Range.begin());
598af732203SDimitry Andric       assert((BeginChildren == Trees.end() ||
599af732203SDimitry Andric               BeginChildren->first == Range.begin()) &&
600af732203SDimitry Andric              "Range crosses boundaries of existing subtrees");
601af732203SDimitry Andric 
602af732203SDimitry Andric       auto EndChildren = Trees.lower_bound(Range.end());
603af732203SDimitry Andric       assert(
604af732203SDimitry Andric           (EndChildren == Trees.end() || EndChildren->first == Range.end()) &&
605af732203SDimitry Andric           "Range crosses boundaries of existing subtrees");
606af732203SDimitry Andric 
607af732203SDimitry Andric       auto BelongsToList = [](decltype(Trees)::value_type KV) {
608af732203SDimitry Andric         auto Role = KV.second->getRole();
609af732203SDimitry Andric         return Role == syntax::NodeRole::ListElement ||
610af732203SDimitry Andric                Role == syntax::NodeRole::ListDelimiter;
611af732203SDimitry Andric       };
612af732203SDimitry Andric 
613af732203SDimitry Andric       auto BeginListChildren =
614af732203SDimitry Andric           std::find_if(BeginChildren, EndChildren, BelongsToList);
615af732203SDimitry Andric 
616af732203SDimitry Andric       auto EndListChildren =
617af732203SDimitry Andric           std::find_if_not(BeginListChildren, EndChildren, BelongsToList);
618af732203SDimitry Andric 
619af732203SDimitry Andric       return ArrayRef<syntax::Token>(BeginListChildren->first,
620af732203SDimitry Andric                                      EndListChildren->first);
621af732203SDimitry Andric     }
622af732203SDimitry Andric 
623480093f4SDimitry Andric     /// Add \p Node to the forest and attach child nodes based on \p Tokens.
foldChildrensyntax::TreeBuilder::Forest624af732203SDimitry Andric     void foldChildren(const syntax::Arena &A, ArrayRef<syntax::Token> Tokens,
6250b57cec5SDimitry Andric                       syntax::Tree *Node) {
626480093f4SDimitry Andric       // Attach children to `Node`.
627af732203SDimitry Andric       assert(Node->getFirstChild() == nullptr && "node already has children");
6285ffd83dbSDimitry Andric 
6295ffd83dbSDimitry Andric       auto *FirstToken = Tokens.begin();
6305ffd83dbSDimitry Andric       auto BeginChildren = Trees.lower_bound(FirstToken);
6315ffd83dbSDimitry Andric 
6325ffd83dbSDimitry Andric       assert((BeginChildren == Trees.end() ||
6335ffd83dbSDimitry Andric               BeginChildren->first == FirstToken) &&
6345ffd83dbSDimitry Andric              "fold crosses boundaries of existing subtrees");
6355ffd83dbSDimitry Andric       auto EndChildren = Trees.lower_bound(Tokens.end());
6365ffd83dbSDimitry Andric       assert(
6375ffd83dbSDimitry Andric           (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&
6385ffd83dbSDimitry Andric           "fold crosses boundaries of existing subtrees");
6395ffd83dbSDimitry Andric 
640af732203SDimitry Andric       for (auto It = BeginChildren; It != EndChildren; ++It) {
641af732203SDimitry Andric         auto *C = It->second;
642af732203SDimitry Andric         if (C->getRole() == NodeRole::Detached)
6435ffd83dbSDimitry Andric           C->setRole(NodeRole::Unknown);
644af732203SDimitry Andric         Node->appendChildLowLevel(C);
645480093f4SDimitry Andric       }
6460b57cec5SDimitry Andric 
6475ffd83dbSDimitry Andric       // Mark that this node came from the AST and is backed by the source code.
6485ffd83dbSDimitry Andric       Node->Original = true;
649af732203SDimitry Andric       Node->CanModify =
650af732203SDimitry Andric           A.getTokenBuffer().spelledForExpanded(Tokens).hasValue();
6510b57cec5SDimitry Andric 
6525ffd83dbSDimitry Andric       Trees.erase(BeginChildren, EndChildren);
6535ffd83dbSDimitry Andric       Trees.insert({FirstToken, Node});
6540b57cec5SDimitry Andric     }
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric     // EXPECTS: all tokens were consumed and are owned by a single root node.
finalizesyntax::TreeBuilder::Forest6570b57cec5SDimitry Andric     syntax::Node *finalize() && {
6580b57cec5SDimitry Andric       assert(Trees.size() == 1);
6595ffd83dbSDimitry Andric       auto *Root = Trees.begin()->second;
6600b57cec5SDimitry Andric       Trees = {};
6610b57cec5SDimitry Andric       return Root;
6620b57cec5SDimitry Andric     }
6630b57cec5SDimitry Andric 
strsyntax::TreeBuilder::Forest6640b57cec5SDimitry Andric     std::string str(const syntax::Arena &A) const {
6650b57cec5SDimitry Andric       std::string R;
6660b57cec5SDimitry Andric       for (auto It = Trees.begin(); It != Trees.end(); ++It) {
6670b57cec5SDimitry Andric         unsigned CoveredTokens =
6680b57cec5SDimitry Andric             It != Trees.end()
6690b57cec5SDimitry Andric                 ? (std::next(It)->first - It->first)
670af732203SDimitry Andric                 : A.getTokenBuffer().expandedTokens().end() - It->first;
6710b57cec5SDimitry Andric 
672af732203SDimitry Andric         R += std::string(
673af732203SDimitry Andric             formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(),
674af732203SDimitry Andric                     It->first->text(A.getSourceManager()), CoveredTokens));
675af732203SDimitry Andric         R += It->second->dump(A.getSourceManager());
6760b57cec5SDimitry Andric       }
6770b57cec5SDimitry Andric       return R;
6780b57cec5SDimitry Andric     }
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   private:
6810b57cec5SDimitry Andric     /// Maps from the start token to a subtree starting at that token.
682480093f4SDimitry Andric     /// Keys in the map are pointers into the array of expanded tokens, so
683480093f4SDimitry Andric     /// pointer order corresponds to the order of preprocessor tokens.
6845ffd83dbSDimitry Andric     std::map<const syntax::Token *, syntax::Node *> Trees;
6850b57cec5SDimitry Andric   };
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric   /// For debugging purposes.
str()6880b57cec5SDimitry Andric   std::string str() { return Pending.str(Arena); }
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric   syntax::Arena &Arena;
691480093f4SDimitry Andric   /// To quickly find tokens by their start location.
692af732203SDimitry Andric   llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken;
6930b57cec5SDimitry Andric   Forest Pending;
694480093f4SDimitry Andric   llvm::DenseSet<Decl *> DeclsWithoutSemicolons;
6955ffd83dbSDimitry Andric   ASTToSyntaxMapping Mapping;
6960b57cec5SDimitry Andric };
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric namespace {
6990b57cec5SDimitry Andric class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
7000b57cec5SDimitry Andric public:
BuildTreeVisitor(ASTContext & Context,syntax::TreeBuilder & Builder)7015ffd83dbSDimitry Andric   explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
7025ffd83dbSDimitry Andric       : Builder(Builder), Context(Context) {}
7030b57cec5SDimitry Andric 
shouldTraversePostOrder() const7040b57cec5SDimitry Andric   bool shouldTraversePostOrder() const { return true; }
7050b57cec5SDimitry Andric 
WalkUpFromDeclaratorDecl(DeclaratorDecl * DD)7065ffd83dbSDimitry Andric   bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {
7075ffd83dbSDimitry Andric     return processDeclaratorAndDeclaration(DD);
708480093f4SDimitry Andric   }
7095ffd83dbSDimitry Andric 
WalkUpFromTypedefNameDecl(TypedefNameDecl * TD)7105ffd83dbSDimitry Andric   bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) {
7115ffd83dbSDimitry Andric     return processDeclaratorAndDeclaration(TD);
7120b57cec5SDimitry Andric   }
7130b57cec5SDimitry Andric 
VisitDecl(Decl * D)7140b57cec5SDimitry Andric   bool VisitDecl(Decl *D) {
7150b57cec5SDimitry Andric     assert(!D->isImplicit());
7165ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(D),
7175ffd83dbSDimitry Andric                      new (allocator()) syntax::UnknownDeclaration(), D);
7185ffd83dbSDimitry Andric     return true;
7195ffd83dbSDimitry Andric   }
7205ffd83dbSDimitry Andric 
7215ffd83dbSDimitry Andric   // RAV does not call WalkUpFrom* on explicit instantiations, so we have to
7225ffd83dbSDimitry Andric   // override Traverse.
7235ffd83dbSDimitry Andric   // FIXME: make RAV call WalkUpFrom* instead.
7245ffd83dbSDimitry Andric   bool
TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * C)7255ffd83dbSDimitry Andric   TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {
7265ffd83dbSDimitry Andric     if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C))
7275ffd83dbSDimitry Andric       return false;
7285ffd83dbSDimitry Andric     if (C->isExplicitSpecialization())
7295ffd83dbSDimitry Andric       return true; // we are only interested in explicit instantiations.
7305ffd83dbSDimitry Andric     auto *Declaration =
7315ffd83dbSDimitry Andric         cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C));
7325ffd83dbSDimitry Andric     foldExplicitTemplateInstantiation(
7335ffd83dbSDimitry Andric         Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()),
7345ffd83dbSDimitry Andric         Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C);
7355ffd83dbSDimitry Andric     return true;
7365ffd83dbSDimitry Andric   }
7375ffd83dbSDimitry Andric 
WalkUpFromTemplateDecl(TemplateDecl * S)7385ffd83dbSDimitry Andric   bool WalkUpFromTemplateDecl(TemplateDecl *S) {
7395ffd83dbSDimitry Andric     foldTemplateDeclaration(
7405ffd83dbSDimitry Andric         Builder.getDeclarationRange(S),
7415ffd83dbSDimitry Andric         Builder.findToken(S->getTemplateParameters()->getTemplateLoc()),
7425ffd83dbSDimitry Andric         Builder.getDeclarationRange(S->getTemplatedDecl()), S);
743480093f4SDimitry Andric     return true;
744480093f4SDimitry Andric   }
745480093f4SDimitry Andric 
WalkUpFromTagDecl(TagDecl * C)746480093f4SDimitry Andric   bool WalkUpFromTagDecl(TagDecl *C) {
747480093f4SDimitry Andric     // FIXME: build the ClassSpecifier node.
7485ffd83dbSDimitry Andric     if (!C->isFreeStanding()) {
7495ffd83dbSDimitry Andric       assert(C->getNumTemplateParameterLists() == 0);
750480093f4SDimitry Andric       return true;
751480093f4SDimitry Andric     }
7525ffd83dbSDimitry Andric     handleFreeStandingTagDecl(C);
7530b57cec5SDimitry Andric     return true;
7540b57cec5SDimitry Andric   }
7550b57cec5SDimitry Andric 
handleFreeStandingTagDecl(TagDecl * C)7565ffd83dbSDimitry Andric   syntax::Declaration *handleFreeStandingTagDecl(TagDecl *C) {
7575ffd83dbSDimitry Andric     assert(C->isFreeStanding());
7585ffd83dbSDimitry Andric     // Class is a declaration specifier and needs a spanning declaration node.
7595ffd83dbSDimitry Andric     auto DeclarationRange = Builder.getDeclarationRange(C);
7605ffd83dbSDimitry Andric     syntax::Declaration *Result = new (allocator()) syntax::SimpleDeclaration;
7615ffd83dbSDimitry Andric     Builder.foldNode(DeclarationRange, Result, nullptr);
7625ffd83dbSDimitry Andric 
7635ffd83dbSDimitry Andric     // Build TemplateDeclaration nodes if we had template parameters.
7645ffd83dbSDimitry Andric     auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) {
7655ffd83dbSDimitry Andric       const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
7665ffd83dbSDimitry Andric       auto R = llvm::makeArrayRef(TemplateKW, DeclarationRange.end());
7675ffd83dbSDimitry Andric       Result =
7685ffd83dbSDimitry Andric           foldTemplateDeclaration(R, TemplateKW, DeclarationRange, nullptr);
7695ffd83dbSDimitry Andric       DeclarationRange = R;
7705ffd83dbSDimitry Andric     };
771af732203SDimitry Andric     if (auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(C))
7725ffd83dbSDimitry Andric       ConsumeTemplateParameters(*S->getTemplateParameters());
7735ffd83dbSDimitry Andric     for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I)
7745ffd83dbSDimitry Andric       ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1));
7755ffd83dbSDimitry Andric     return Result;
7765ffd83dbSDimitry Andric   }
7775ffd83dbSDimitry Andric 
WalkUpFromTranslationUnitDecl(TranslationUnitDecl * TU)7780b57cec5SDimitry Andric   bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
7795ffd83dbSDimitry Andric     // We do not want to call VisitDecl(), the declaration for translation
7800b57cec5SDimitry Andric     // unit is built by finalize().
7810b57cec5SDimitry Andric     return true;
7820b57cec5SDimitry Andric   }
7830b57cec5SDimitry Andric 
WalkUpFromCompoundStmt(CompoundStmt * S)7840b57cec5SDimitry Andric   bool WalkUpFromCompoundStmt(CompoundStmt *S) {
7850b57cec5SDimitry Andric     using NodeRole = syntax::NodeRole;
7860b57cec5SDimitry Andric 
787480093f4SDimitry Andric     Builder.markChildToken(S->getLBracLoc(), NodeRole::OpenParen);
788480093f4SDimitry Andric     for (auto *Child : S->body())
789af732203SDimitry Andric       Builder.markStmtChild(Child, NodeRole::Statement);
790480093f4SDimitry Andric     Builder.markChildToken(S->getRBracLoc(), NodeRole::CloseParen);
7910b57cec5SDimitry Andric 
792480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
7935ffd83dbSDimitry Andric                      new (allocator()) syntax::CompoundStatement, S);
7940b57cec5SDimitry Andric     return true;
7950b57cec5SDimitry Andric   }
7960b57cec5SDimitry Andric 
797480093f4SDimitry Andric   // Some statements are not yet handled by syntax trees.
WalkUpFromStmt(Stmt * S)798480093f4SDimitry Andric   bool WalkUpFromStmt(Stmt *S) {
799480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
8005ffd83dbSDimitry Andric                      new (allocator()) syntax::UnknownStatement, S);
801480093f4SDimitry Andric     return true;
802480093f4SDimitry Andric   }
803480093f4SDimitry Andric 
TraverseIfStmt(IfStmt * S)804*5f7ddb14SDimitry Andric   bool TraverseIfStmt(IfStmt *S) {
805*5f7ddb14SDimitry Andric     bool Result = [&, this]() {
806*5f7ddb14SDimitry Andric       if (S->getInit() && !TraverseStmt(S->getInit())) {
807*5f7ddb14SDimitry Andric         return false;
808*5f7ddb14SDimitry Andric       }
809*5f7ddb14SDimitry Andric       // In cases where the condition is an initialized declaration in a
810*5f7ddb14SDimitry Andric       // statement, we want to preserve the declaration and ignore the
811*5f7ddb14SDimitry Andric       // implicit condition expression in the syntax tree.
812*5f7ddb14SDimitry Andric       if (S->hasVarStorage()) {
813*5f7ddb14SDimitry Andric         if (!TraverseStmt(S->getConditionVariableDeclStmt()))
814*5f7ddb14SDimitry Andric           return false;
815*5f7ddb14SDimitry Andric       } else if (S->getCond() && !TraverseStmt(S->getCond()))
816*5f7ddb14SDimitry Andric         return false;
817*5f7ddb14SDimitry Andric 
818*5f7ddb14SDimitry Andric       if (S->getThen() && !TraverseStmt(S->getThen()))
819*5f7ddb14SDimitry Andric         return false;
820*5f7ddb14SDimitry Andric       if (S->getElse() && !TraverseStmt(S->getElse()))
821*5f7ddb14SDimitry Andric         return false;
822*5f7ddb14SDimitry Andric       return true;
823*5f7ddb14SDimitry Andric     }();
824*5f7ddb14SDimitry Andric     WalkUpFromIfStmt(S);
825*5f7ddb14SDimitry Andric     return Result;
826*5f7ddb14SDimitry Andric   }
827*5f7ddb14SDimitry Andric 
TraverseCXXForRangeStmt(CXXForRangeStmt * S)828480093f4SDimitry Andric   bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
829480093f4SDimitry Andric     // We override to traverse range initializer as VarDecl.
830480093f4SDimitry Andric     // RAV traverses it as a statement, we produce invalid node kinds in that
831480093f4SDimitry Andric     // case.
832480093f4SDimitry Andric     // FIXME: should do this in RAV instead?
8335ffd83dbSDimitry Andric     bool Result = [&, this]() {
834480093f4SDimitry Andric       if (S->getInit() && !TraverseStmt(S->getInit()))
835480093f4SDimitry Andric         return false;
836480093f4SDimitry Andric       if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable()))
837480093f4SDimitry Andric         return false;
838480093f4SDimitry Andric       if (S->getRangeInit() && !TraverseStmt(S->getRangeInit()))
839480093f4SDimitry Andric         return false;
840480093f4SDimitry Andric       if (S->getBody() && !TraverseStmt(S->getBody()))
841480093f4SDimitry Andric         return false;
842480093f4SDimitry Andric       return true;
8435ffd83dbSDimitry Andric     }();
8445ffd83dbSDimitry Andric     WalkUpFromCXXForRangeStmt(S);
8455ffd83dbSDimitry Andric     return Result;
846480093f4SDimitry Andric   }
847480093f4SDimitry Andric 
TraverseStmt(Stmt * S)848480093f4SDimitry Andric   bool TraverseStmt(Stmt *S) {
849af732203SDimitry Andric     if (auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
850480093f4SDimitry Andric       // We want to consume the semicolon, make sure SimpleDeclaration does not.
851480093f4SDimitry Andric       for (auto *D : DS->decls())
8525ffd83dbSDimitry Andric         Builder.noticeDeclWithoutSemicolon(D);
853af732203SDimitry Andric     } else if (auto *E = dyn_cast_or_null<Expr>(S)) {
854af732203SDimitry Andric       return RecursiveASTVisitor::TraverseStmt(IgnoreImplicit(E));
855480093f4SDimitry Andric     }
856480093f4SDimitry Andric     return RecursiveASTVisitor::TraverseStmt(S);
857480093f4SDimitry Andric   }
858480093f4SDimitry Andric 
TraverseOpaqueValueExpr(OpaqueValueExpr * VE)859*5f7ddb14SDimitry Andric   bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
860*5f7ddb14SDimitry Andric     // OpaqueValue doesn't correspond to concrete syntax, ignore it.
861*5f7ddb14SDimitry Andric     return true;
862*5f7ddb14SDimitry Andric   }
863*5f7ddb14SDimitry Andric 
864480093f4SDimitry Andric   // Some expressions are not yet handled by syntax trees.
WalkUpFromExpr(Expr * E)865480093f4SDimitry Andric   bool WalkUpFromExpr(Expr *E) {
866480093f4SDimitry Andric     assert(!isImplicitExpr(E) && "should be handled by TraverseStmt");
867480093f4SDimitry Andric     Builder.foldNode(Builder.getExprRange(E),
8685ffd83dbSDimitry Andric                      new (allocator()) syntax::UnknownExpression, E);
869480093f4SDimitry Andric     return true;
870480093f4SDimitry Andric   }
871480093f4SDimitry Andric 
TraverseUserDefinedLiteral(UserDefinedLiteral * S)8725ffd83dbSDimitry Andric   bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
8735ffd83dbSDimitry Andric     // The semantic AST node `UserDefinedLiteral` (UDL) may have one child node
8745ffd83dbSDimitry Andric     // referencing the location of the UDL suffix (`_w` in `1.2_w`). The
8755ffd83dbSDimitry Andric     // UDL suffix location does not point to the beginning of a token, so we
8765ffd83dbSDimitry Andric     // can't represent the UDL suffix as a separate syntax tree node.
8775ffd83dbSDimitry Andric 
8785ffd83dbSDimitry Andric     return WalkUpFromUserDefinedLiteral(S);
8795ffd83dbSDimitry Andric   }
8805ffd83dbSDimitry Andric 
8815ffd83dbSDimitry Andric   syntax::UserDefinedLiteralExpression *
buildUserDefinedLiteral(UserDefinedLiteral * S)8825ffd83dbSDimitry Andric   buildUserDefinedLiteral(UserDefinedLiteral *S) {
8835ffd83dbSDimitry Andric     switch (S->getLiteralOperatorKind()) {
884af732203SDimitry Andric     case UserDefinedLiteral::LOK_Integer:
8855ffd83dbSDimitry Andric       return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
886af732203SDimitry Andric     case UserDefinedLiteral::LOK_Floating:
8875ffd83dbSDimitry Andric       return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
888af732203SDimitry Andric     case UserDefinedLiteral::LOK_Character:
8895ffd83dbSDimitry Andric       return new (allocator()) syntax::CharUserDefinedLiteralExpression;
890af732203SDimitry Andric     case UserDefinedLiteral::LOK_String:
8915ffd83dbSDimitry Andric       return new (allocator()) syntax::StringUserDefinedLiteralExpression;
892af732203SDimitry Andric     case UserDefinedLiteral::LOK_Raw:
893af732203SDimitry Andric     case UserDefinedLiteral::LOK_Template:
8945ffd83dbSDimitry Andric       // For raw literal operator and numeric literal operator template we
8955ffd83dbSDimitry Andric       // cannot get the type of the operand in the semantic AST. We get this
8965ffd83dbSDimitry Andric       // information from the token. As integer and floating point have the same
8975ffd83dbSDimitry Andric       // token kind, we run `NumericLiteralParser` again to distinguish them.
8985ffd83dbSDimitry Andric       auto TokLoc = S->getBeginLoc();
8995ffd83dbSDimitry Andric       auto TokSpelling =
9005ffd83dbSDimitry Andric           Builder.findToken(TokLoc)->text(Context.getSourceManager());
9015ffd83dbSDimitry Andric       auto Literal =
9025ffd83dbSDimitry Andric           NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(),
9035ffd83dbSDimitry Andric                                Context.getLangOpts(), Context.getTargetInfo(),
9045ffd83dbSDimitry Andric                                Context.getDiagnostics());
9055ffd83dbSDimitry Andric       if (Literal.isIntegerLiteral())
9065ffd83dbSDimitry Andric         return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
9075ffd83dbSDimitry Andric       else {
9085ffd83dbSDimitry Andric         assert(Literal.isFloatingLiteral());
9095ffd83dbSDimitry Andric         return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
9105ffd83dbSDimitry Andric       }
9115ffd83dbSDimitry Andric     }
9125ffd83dbSDimitry Andric     llvm_unreachable("Unknown literal operator kind.");
9135ffd83dbSDimitry Andric   }
9145ffd83dbSDimitry Andric 
WalkUpFromUserDefinedLiteral(UserDefinedLiteral * S)9155ffd83dbSDimitry Andric   bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
9165ffd83dbSDimitry Andric     Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
9175ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
9185ffd83dbSDimitry Andric     return true;
9195ffd83dbSDimitry Andric   }
9205ffd83dbSDimitry Andric 
921af732203SDimitry Andric   // FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the
922af732203SDimitry Andric   // `DependentTemplateSpecializationType` case.
923af732203SDimitry Andric   /// Given a nested-name-specifier return the range for the last name
924af732203SDimitry Andric   /// specifier.
925af732203SDimitry Andric   ///
926af732203SDimitry Andric   /// e.g. `std::T::template X<U>::` => `template X<U>::`
getLocalSourceRange(const NestedNameSpecifierLoc & NNSLoc)927af732203SDimitry Andric   SourceRange getLocalSourceRange(const NestedNameSpecifierLoc &NNSLoc) {
928af732203SDimitry Andric     auto SR = NNSLoc.getLocalSourceRange();
9295ffd83dbSDimitry Andric 
930af732203SDimitry Andric     // The method `NestedNameSpecifierLoc::getLocalSourceRange` *should*
931af732203SDimitry Andric     // return the desired `SourceRange`, but there is a corner case. For a
932af732203SDimitry Andric     // `DependentTemplateSpecializationType` this method returns its
933af732203SDimitry Andric     // qualifiers as well, in other words in the example above this method
934af732203SDimitry Andric     // returns `T::template X<U>::` instead of only `template X<U>::`
935af732203SDimitry Andric     if (auto TL = NNSLoc.getTypeLoc()) {
936af732203SDimitry Andric       if (auto DependentTL =
937af732203SDimitry Andric               TL.getAs<DependentTemplateSpecializationTypeLoc>()) {
938af732203SDimitry Andric         // The 'template' keyword is always present in dependent template
939af732203SDimitry Andric         // specializations. Except in the case of incorrect code
940af732203SDimitry Andric         // TODO: Treat the case of incorrect code.
941af732203SDimitry Andric         SR.setBegin(DependentTL.getTemplateKeywordLoc());
9425ffd83dbSDimitry Andric       }
943af732203SDimitry Andric     }
944af732203SDimitry Andric 
945af732203SDimitry Andric     return SR;
946af732203SDimitry Andric   }
947af732203SDimitry Andric 
getNameSpecifierKind(const NestedNameSpecifier & NNS)948af732203SDimitry Andric   syntax::NodeKind getNameSpecifierKind(const NestedNameSpecifier &NNS) {
949af732203SDimitry Andric     switch (NNS.getKind()) {
950af732203SDimitry Andric     case NestedNameSpecifier::Global:
951af732203SDimitry Andric       return syntax::NodeKind::GlobalNameSpecifier;
952af732203SDimitry Andric     case NestedNameSpecifier::Namespace:
953af732203SDimitry Andric     case NestedNameSpecifier::NamespaceAlias:
954af732203SDimitry Andric     case NestedNameSpecifier::Identifier:
955af732203SDimitry Andric       return syntax::NodeKind::IdentifierNameSpecifier;
956af732203SDimitry Andric     case NestedNameSpecifier::TypeSpecWithTemplate:
957af732203SDimitry Andric       return syntax::NodeKind::SimpleTemplateNameSpecifier;
958af732203SDimitry Andric     case NestedNameSpecifier::TypeSpec: {
959af732203SDimitry Andric       const auto *NNSType = NNS.getAsType();
960af732203SDimitry Andric       assert(NNSType);
961af732203SDimitry Andric       if (isa<DecltypeType>(NNSType))
962af732203SDimitry Andric         return syntax::NodeKind::DecltypeNameSpecifier;
963af732203SDimitry Andric       if (isa<TemplateSpecializationType, DependentTemplateSpecializationType>(
964af732203SDimitry Andric               NNSType))
965af732203SDimitry Andric         return syntax::NodeKind::SimpleTemplateNameSpecifier;
966af732203SDimitry Andric       return syntax::NodeKind::IdentifierNameSpecifier;
967af732203SDimitry Andric     }
968af732203SDimitry Andric     default:
969af732203SDimitry Andric       // FIXME: Support Microsoft's __super
970af732203SDimitry Andric       llvm::report_fatal_error("We don't yet support the __super specifier",
971af732203SDimitry Andric                                true);
972af732203SDimitry Andric     }
973af732203SDimitry Andric   }
974af732203SDimitry Andric 
975af732203SDimitry Andric   syntax::NameSpecifier *
buildNameSpecifier(const NestedNameSpecifierLoc & NNSLoc)976af732203SDimitry Andric   buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {
977af732203SDimitry Andric     assert(NNSLoc.hasQualifier());
978af732203SDimitry Andric     auto NameSpecifierTokens =
979af732203SDimitry Andric         Builder.getRange(getLocalSourceRange(NNSLoc)).drop_back();
980af732203SDimitry Andric     switch (getNameSpecifierKind(*NNSLoc.getNestedNameSpecifier())) {
981af732203SDimitry Andric     case syntax::NodeKind::GlobalNameSpecifier:
982af732203SDimitry Andric       return new (allocator()) syntax::GlobalNameSpecifier;
983af732203SDimitry Andric     case syntax::NodeKind::IdentifierNameSpecifier: {
984af732203SDimitry Andric       assert(NameSpecifierTokens.size() == 1);
985af732203SDimitry Andric       Builder.markChildToken(NameSpecifierTokens.begin(),
986af732203SDimitry Andric                              syntax::NodeRole::Unknown);
987af732203SDimitry Andric       auto *NS = new (allocator()) syntax::IdentifierNameSpecifier;
988af732203SDimitry Andric       Builder.foldNode(NameSpecifierTokens, NS, nullptr);
989af732203SDimitry Andric       return NS;
990af732203SDimitry Andric     }
991af732203SDimitry Andric     case syntax::NodeKind::SimpleTemplateNameSpecifier: {
992af732203SDimitry Andric       // TODO: Build `SimpleTemplateNameSpecifier` children and implement
993af732203SDimitry Andric       // accessors to them.
994af732203SDimitry Andric       // Be aware, we cannot do that simply by calling `TraverseTypeLoc`,
995af732203SDimitry Andric       // some `TypeLoc`s have inside them the previous name specifier and
996af732203SDimitry Andric       // we want to treat them independently.
997af732203SDimitry Andric       auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier;
998af732203SDimitry Andric       Builder.foldNode(NameSpecifierTokens, NS, nullptr);
999af732203SDimitry Andric       return NS;
1000af732203SDimitry Andric     }
1001af732203SDimitry Andric     case syntax::NodeKind::DecltypeNameSpecifier: {
1002af732203SDimitry Andric       const auto TL = NNSLoc.getTypeLoc().castAs<DecltypeTypeLoc>();
1003af732203SDimitry Andric       if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL))
1004af732203SDimitry Andric         return nullptr;
1005af732203SDimitry Andric       auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;
1006af732203SDimitry Andric       // TODO: Implement accessor to `DecltypeNameSpecifier` inner
1007af732203SDimitry Andric       // `DecltypeTypeLoc`.
1008af732203SDimitry Andric       // For that add mapping from `TypeLoc` to `syntax::Node*` then:
1009af732203SDimitry Andric       // Builder.markChild(TypeLoc, syntax::NodeRole);
1010af732203SDimitry Andric       Builder.foldNode(NameSpecifierTokens, NS, nullptr);
1011af732203SDimitry Andric       return NS;
1012af732203SDimitry Andric     }
1013af732203SDimitry Andric     default:
1014af732203SDimitry Andric       llvm_unreachable("getChildKind() does not return this value");
1015af732203SDimitry Andric     }
1016af732203SDimitry Andric   }
1017af732203SDimitry Andric 
1018af732203SDimitry Andric   // To build syntax tree nodes for NestedNameSpecifierLoc we override
1019af732203SDimitry Andric   // Traverse instead of WalkUpFrom because we want to traverse the children
1020af732203SDimitry Andric   // ourselves and build a list instead of a nested tree of name specifier
1021af732203SDimitry Andric   // prefixes.
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)1022af732203SDimitry Andric   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1023af732203SDimitry Andric     if (!QualifierLoc)
1024af732203SDimitry Andric       return true;
1025af732203SDimitry Andric     for (auto It = QualifierLoc; It; It = It.getPrefix()) {
1026af732203SDimitry Andric       auto *NS = buildNameSpecifier(It);
1027af732203SDimitry Andric       if (!NS)
1028af732203SDimitry Andric         return false;
1029af732203SDimitry Andric       Builder.markChild(NS, syntax::NodeRole::ListElement);
1030af732203SDimitry Andric       Builder.markChildToken(It.getEndLoc(), syntax::NodeRole::ListDelimiter);
1031af732203SDimitry Andric     }
1032af732203SDimitry Andric     Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),
1033af732203SDimitry Andric                      new (allocator()) syntax::NestedNameSpecifier,
1034af732203SDimitry Andric                      QualifierLoc);
1035af732203SDimitry Andric     return true;
1036af732203SDimitry Andric   }
1037af732203SDimitry Andric 
buildIdExpression(NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKeywordLoc,SourceRange UnqualifiedIdLoc,ASTPtr From)1038af732203SDimitry Andric   syntax::IdExpression *buildIdExpression(NestedNameSpecifierLoc QualifierLoc,
1039af732203SDimitry Andric                                           SourceLocation TemplateKeywordLoc,
1040af732203SDimitry Andric                                           SourceRange UnqualifiedIdLoc,
1041af732203SDimitry Andric                                           ASTPtr From) {
1042af732203SDimitry Andric     if (QualifierLoc) {
1043af732203SDimitry Andric       Builder.markChild(QualifierLoc, syntax::NodeRole::Qualifier);
1044af732203SDimitry Andric       if (TemplateKeywordLoc.isValid())
1045af732203SDimitry Andric         Builder.markChildToken(TemplateKeywordLoc,
1046af732203SDimitry Andric                                syntax::NodeRole::TemplateKeyword);
1047af732203SDimitry Andric     }
1048af732203SDimitry Andric 
1049af732203SDimitry Andric     auto *TheUnqualifiedId = new (allocator()) syntax::UnqualifiedId;
1050af732203SDimitry Andric     Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1051af732203SDimitry Andric                      nullptr);
1052af732203SDimitry Andric     Builder.markChild(TheUnqualifiedId, syntax::NodeRole::UnqualifiedId);
1053af732203SDimitry Andric 
1054af732203SDimitry Andric     auto IdExpressionBeginLoc =
1055af732203SDimitry Andric         QualifierLoc ? QualifierLoc.getBeginLoc() : UnqualifiedIdLoc.getBegin();
1056af732203SDimitry Andric 
1057af732203SDimitry Andric     auto *TheIdExpression = new (allocator()) syntax::IdExpression;
1058af732203SDimitry Andric     Builder.foldNode(
1059af732203SDimitry Andric         Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.getEnd()),
1060af732203SDimitry Andric         TheIdExpression, From);
1061af732203SDimitry Andric 
1062af732203SDimitry Andric     return TheIdExpression;
1063af732203SDimitry Andric   }
1064af732203SDimitry Andric 
WalkUpFromMemberExpr(MemberExpr * S)1065af732203SDimitry Andric   bool WalkUpFromMemberExpr(MemberExpr *S) {
1066af732203SDimitry Andric     // For `MemberExpr` with implicit `this->` we generate a simple
1067af732203SDimitry Andric     // `id-expression` syntax node, beacuse an implicit `member-expression` is
1068af732203SDimitry Andric     // syntactically undistinguishable from an `id-expression`
1069af732203SDimitry Andric     if (S->isImplicitAccess()) {
1070af732203SDimitry Andric       buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1071af732203SDimitry Andric                         SourceRange(S->getMemberLoc(), S->getEndLoc()), S);
1072af732203SDimitry Andric       return true;
1073af732203SDimitry Andric     }
1074af732203SDimitry Andric 
1075af732203SDimitry Andric     auto *TheIdExpression = buildIdExpression(
1076af732203SDimitry Andric         S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1077af732203SDimitry Andric         SourceRange(S->getMemberLoc(), S->getEndLoc()), nullptr);
1078af732203SDimitry Andric 
1079af732203SDimitry Andric     Builder.markChild(TheIdExpression, syntax::NodeRole::Member);
1080af732203SDimitry Andric 
1081af732203SDimitry Andric     Builder.markExprChild(S->getBase(), syntax::NodeRole::Object);
1082af732203SDimitry Andric     Builder.markChildToken(S->getOperatorLoc(), syntax::NodeRole::AccessToken);
10835ffd83dbSDimitry Andric 
10845ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1085af732203SDimitry Andric                      new (allocator()) syntax::MemberExpression, S);
1086af732203SDimitry Andric     return true;
1087af732203SDimitry Andric   }
1088af732203SDimitry Andric 
WalkUpFromDeclRefExpr(DeclRefExpr * S)1089af732203SDimitry Andric   bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
1090af732203SDimitry Andric     buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1091af732203SDimitry Andric                       SourceRange(S->getLocation(), S->getEndLoc()), S);
1092af732203SDimitry Andric 
1093af732203SDimitry Andric     return true;
1094af732203SDimitry Andric   }
1095af732203SDimitry Andric 
1096af732203SDimitry Andric   // Same logic as DeclRefExpr.
WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr * S)1097af732203SDimitry Andric   bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
1098af732203SDimitry Andric     buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1099af732203SDimitry Andric                       SourceRange(S->getLocation(), S->getEndLoc()), S);
1100af732203SDimitry Andric 
1101af732203SDimitry Andric     return true;
1102af732203SDimitry Andric   }
1103af732203SDimitry Andric 
WalkUpFromCXXThisExpr(CXXThisExpr * S)1104af732203SDimitry Andric   bool WalkUpFromCXXThisExpr(CXXThisExpr *S) {
1105af732203SDimitry Andric     if (!S->isImplicit()) {
1106af732203SDimitry Andric       Builder.markChildToken(S->getLocation(),
1107af732203SDimitry Andric                              syntax::NodeRole::IntroducerKeyword);
1108af732203SDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1109af732203SDimitry Andric                        new (allocator()) syntax::ThisExpression, S);
1110af732203SDimitry Andric     }
11115ffd83dbSDimitry Andric     return true;
11125ffd83dbSDimitry Andric   }
11135ffd83dbSDimitry Andric 
WalkUpFromParenExpr(ParenExpr * S)11145ffd83dbSDimitry Andric   bool WalkUpFromParenExpr(ParenExpr *S) {
11155ffd83dbSDimitry Andric     Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
1116af732203SDimitry Andric     Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::SubExpression);
11175ffd83dbSDimitry Andric     Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen);
11185ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11195ffd83dbSDimitry Andric                      new (allocator()) syntax::ParenExpression, S);
11205ffd83dbSDimitry Andric     return true;
11215ffd83dbSDimitry Andric   }
11225ffd83dbSDimitry Andric 
WalkUpFromIntegerLiteral(IntegerLiteral * S)11235ffd83dbSDimitry Andric   bool WalkUpFromIntegerLiteral(IntegerLiteral *S) {
11245ffd83dbSDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
11255ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11265ffd83dbSDimitry Andric                      new (allocator()) syntax::IntegerLiteralExpression, S);
11275ffd83dbSDimitry Andric     return true;
11285ffd83dbSDimitry Andric   }
11295ffd83dbSDimitry Andric 
WalkUpFromCharacterLiteral(CharacterLiteral * S)11305ffd83dbSDimitry Andric   bool WalkUpFromCharacterLiteral(CharacterLiteral *S) {
11315ffd83dbSDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
11325ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11335ffd83dbSDimitry Andric                      new (allocator()) syntax::CharacterLiteralExpression, S);
11345ffd83dbSDimitry Andric     return true;
11355ffd83dbSDimitry Andric   }
11365ffd83dbSDimitry Andric 
WalkUpFromFloatingLiteral(FloatingLiteral * S)11375ffd83dbSDimitry Andric   bool WalkUpFromFloatingLiteral(FloatingLiteral *S) {
11385ffd83dbSDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
11395ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11405ffd83dbSDimitry Andric                      new (allocator()) syntax::FloatingLiteralExpression, S);
11415ffd83dbSDimitry Andric     return true;
11425ffd83dbSDimitry Andric   }
11435ffd83dbSDimitry Andric 
WalkUpFromStringLiteral(StringLiteral * S)11445ffd83dbSDimitry Andric   bool WalkUpFromStringLiteral(StringLiteral *S) {
11455ffd83dbSDimitry Andric     Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
11465ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11475ffd83dbSDimitry Andric                      new (allocator()) syntax::StringLiteralExpression, S);
11485ffd83dbSDimitry Andric     return true;
11495ffd83dbSDimitry Andric   }
11505ffd83dbSDimitry Andric 
WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr * S)11515ffd83dbSDimitry Andric   bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
11525ffd83dbSDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
11535ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11545ffd83dbSDimitry Andric                      new (allocator()) syntax::BoolLiteralExpression, S);
11555ffd83dbSDimitry Andric     return true;
11565ffd83dbSDimitry Andric   }
11575ffd83dbSDimitry Andric 
WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr * S)11585ffd83dbSDimitry Andric   bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
11595ffd83dbSDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
11605ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11615ffd83dbSDimitry Andric                      new (allocator()) syntax::CxxNullPtrExpression, S);
11625ffd83dbSDimitry Andric     return true;
11635ffd83dbSDimitry Andric   }
11645ffd83dbSDimitry Andric 
WalkUpFromUnaryOperator(UnaryOperator * S)11655ffd83dbSDimitry Andric   bool WalkUpFromUnaryOperator(UnaryOperator *S) {
11665ffd83dbSDimitry Andric     Builder.markChildToken(S->getOperatorLoc(),
1167af732203SDimitry Andric                            syntax::NodeRole::OperatorToken);
1168af732203SDimitry Andric     Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::Operand);
11695ffd83dbSDimitry Andric 
11705ffd83dbSDimitry Andric     if (S->isPostfix())
11715ffd83dbSDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
11725ffd83dbSDimitry Andric                        new (allocator()) syntax::PostfixUnaryOperatorExpression,
11735ffd83dbSDimitry Andric                        S);
11745ffd83dbSDimitry Andric     else
11755ffd83dbSDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
11765ffd83dbSDimitry Andric                        new (allocator()) syntax::PrefixUnaryOperatorExpression,
11775ffd83dbSDimitry Andric                        S);
11785ffd83dbSDimitry Andric 
11795ffd83dbSDimitry Andric     return true;
11805ffd83dbSDimitry Andric   }
11815ffd83dbSDimitry Andric 
WalkUpFromBinaryOperator(BinaryOperator * S)11825ffd83dbSDimitry Andric   bool WalkUpFromBinaryOperator(BinaryOperator *S) {
1183af732203SDimitry Andric     Builder.markExprChild(S->getLHS(), syntax::NodeRole::LeftHandSide);
11845ffd83dbSDimitry Andric     Builder.markChildToken(S->getOperatorLoc(),
1185af732203SDimitry Andric                            syntax::NodeRole::OperatorToken);
1186af732203SDimitry Andric     Builder.markExprChild(S->getRHS(), syntax::NodeRole::RightHandSide);
11875ffd83dbSDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
11885ffd83dbSDimitry Andric                      new (allocator()) syntax::BinaryOperatorExpression, S);
11895ffd83dbSDimitry Andric     return true;
11905ffd83dbSDimitry Andric   }
11915ffd83dbSDimitry Andric 
1192af732203SDimitry Andric   /// Builds `CallArguments` syntax node from arguments that appear in source
1193af732203SDimitry Andric   /// code, i.e. not default arguments.
1194af732203SDimitry Andric   syntax::CallArguments *
buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs)1195af732203SDimitry Andric   buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs) {
1196af732203SDimitry Andric     auto Args = dropDefaultArgs(ArgsAndDefaultArgs);
1197af732203SDimitry Andric     for (auto *Arg : Args) {
1198af732203SDimitry Andric       Builder.markExprChild(Arg, syntax::NodeRole::ListElement);
1199af732203SDimitry Andric       const auto *DelimiterToken =
1200af732203SDimitry Andric           std::next(Builder.findToken(Arg->getEndLoc()));
1201af732203SDimitry Andric       if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1202af732203SDimitry Andric         Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1203af732203SDimitry Andric     }
1204af732203SDimitry Andric 
1205af732203SDimitry Andric     auto *Arguments = new (allocator()) syntax::CallArguments;
1206af732203SDimitry Andric     if (!Args.empty())
1207af732203SDimitry Andric       Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1208af732203SDimitry Andric                                         (*(Args.end() - 1))->getEndLoc()),
1209af732203SDimitry Andric                        Arguments, nullptr);
1210af732203SDimitry Andric 
1211af732203SDimitry Andric     return Arguments;
1212af732203SDimitry Andric   }
1213af732203SDimitry Andric 
WalkUpFromCallExpr(CallExpr * S)1214af732203SDimitry Andric   bool WalkUpFromCallExpr(CallExpr *S) {
1215af732203SDimitry Andric     Builder.markExprChild(S->getCallee(), syntax::NodeRole::Callee);
1216af732203SDimitry Andric 
1217af732203SDimitry Andric     const auto *LParenToken =
1218af732203SDimitry Andric         std::next(Builder.findToken(S->getCallee()->getEndLoc()));
1219af732203SDimitry Andric     // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have fixed
1220af732203SDimitry Andric     // the test on decltype desctructors.
1221af732203SDimitry Andric     if (LParenToken->kind() == clang::tok::l_paren)
1222af732203SDimitry Andric       Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
1223af732203SDimitry Andric 
1224af732203SDimitry Andric     Builder.markChild(buildCallArguments(S->arguments()),
1225af732203SDimitry Andric                       syntax::NodeRole::Arguments);
1226af732203SDimitry Andric 
1227af732203SDimitry Andric     Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
1228af732203SDimitry Andric 
1229af732203SDimitry Andric     Builder.foldNode(Builder.getRange(S->getSourceRange()),
1230af732203SDimitry Andric                      new (allocator()) syntax::CallExpression, S);
1231af732203SDimitry Andric     return true;
1232af732203SDimitry Andric   }
1233af732203SDimitry Andric 
WalkUpFromCXXConstructExpr(CXXConstructExpr * S)1234af732203SDimitry Andric   bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S) {
1235af732203SDimitry Andric     // Ignore the implicit calls to default constructors.
1236af732203SDimitry Andric     if ((S->getNumArgs() == 0 || isa<CXXDefaultArgExpr>(S->getArg(0))) &&
1237af732203SDimitry Andric         S->getParenOrBraceRange().isInvalid())
1238af732203SDimitry Andric       return true;
1239af732203SDimitry Andric     return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1240af732203SDimitry Andric   }
1241af732203SDimitry Andric 
TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * S)12425ffd83dbSDimitry Andric   bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
1243af732203SDimitry Andric     // To construct a syntax tree of the same shape for calls to built-in and
1244af732203SDimitry Andric     // user-defined operators, ignore the `DeclRefExpr` that refers to the
1245af732203SDimitry Andric     // operator and treat it as a simple token. Do that by traversing
1246af732203SDimitry Andric     // arguments instead of children.
1247af732203SDimitry Andric     for (auto *child : S->arguments()) {
12485ffd83dbSDimitry Andric       // A postfix unary operator is declared as taking two operands. The
12495ffd83dbSDimitry Andric       // second operand is used to distinguish from its prefix counterpart. In
12505ffd83dbSDimitry Andric       // the semantic AST this "phantom" operand is represented as a
12515ffd83dbSDimitry Andric       // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
12525ffd83dbSDimitry Andric       // operand because it does not correspond to anything written in source
1253af732203SDimitry Andric       // code.
1254af732203SDimitry Andric       if (child->getSourceRange().isInvalid()) {
1255af732203SDimitry Andric         assert(getOperatorNodeKind(*S) ==
1256af732203SDimitry Andric                syntax::NodeKind::PostfixUnaryOperatorExpression);
12575ffd83dbSDimitry Andric         continue;
1258af732203SDimitry Andric       }
12595ffd83dbSDimitry Andric       if (!TraverseStmt(child))
12605ffd83dbSDimitry Andric         return false;
12615ffd83dbSDimitry Andric     }
12625ffd83dbSDimitry Andric     return WalkUpFromCXXOperatorCallExpr(S);
12635ffd83dbSDimitry Andric   }
12645ffd83dbSDimitry Andric 
WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr * S)12655ffd83dbSDimitry Andric   bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
12665ffd83dbSDimitry Andric     switch (getOperatorNodeKind(*S)) {
12675ffd83dbSDimitry Andric     case syntax::NodeKind::BinaryOperatorExpression:
1268af732203SDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::LeftHandSide);
1269af732203SDimitry Andric       Builder.markChildToken(S->getOperatorLoc(),
1270af732203SDimitry Andric                              syntax::NodeRole::OperatorToken);
1271af732203SDimitry Andric       Builder.markExprChild(S->getArg(1), syntax::NodeRole::RightHandSide);
12725ffd83dbSDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
12735ffd83dbSDimitry Andric                        new (allocator()) syntax::BinaryOperatorExpression, S);
12745ffd83dbSDimitry Andric       return true;
12755ffd83dbSDimitry Andric     case syntax::NodeKind::PrefixUnaryOperatorExpression:
1276af732203SDimitry Andric       Builder.markChildToken(S->getOperatorLoc(),
1277af732203SDimitry Andric                              syntax::NodeRole::OperatorToken);
1278af732203SDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand);
12795ffd83dbSDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
12805ffd83dbSDimitry Andric                        new (allocator()) syntax::PrefixUnaryOperatorExpression,
12815ffd83dbSDimitry Andric                        S);
12825ffd83dbSDimitry Andric       return true;
12835ffd83dbSDimitry Andric     case syntax::NodeKind::PostfixUnaryOperatorExpression:
1284af732203SDimitry Andric       Builder.markChildToken(S->getOperatorLoc(),
1285af732203SDimitry Andric                              syntax::NodeRole::OperatorToken);
1286af732203SDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand);
12875ffd83dbSDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
12885ffd83dbSDimitry Andric                        new (allocator()) syntax::PostfixUnaryOperatorExpression,
12895ffd83dbSDimitry Andric                        S);
12905ffd83dbSDimitry Andric       return true;
1291af732203SDimitry Andric     case syntax::NodeKind::CallExpression: {
1292af732203SDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::Callee);
1293af732203SDimitry Andric 
1294af732203SDimitry Andric       const auto *LParenToken =
1295af732203SDimitry Andric           std::next(Builder.findToken(S->getArg(0)->getEndLoc()));
1296af732203SDimitry Andric       // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have
1297af732203SDimitry Andric       // fixed the test on decltype desctructors.
1298af732203SDimitry Andric       if (LParenToken->kind() == clang::tok::l_paren)
1299af732203SDimitry Andric         Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
1300af732203SDimitry Andric 
1301af732203SDimitry Andric       Builder.markChild(buildCallArguments(CallExpr::arg_range(
1302af732203SDimitry Andric                             S->arg_begin() + 1, S->arg_end())),
1303af732203SDimitry Andric                         syntax::NodeRole::Arguments);
1304af732203SDimitry Andric 
1305af732203SDimitry Andric       Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
1306af732203SDimitry Andric 
1307af732203SDimitry Andric       Builder.foldNode(Builder.getRange(S->getSourceRange()),
1308af732203SDimitry Andric                        new (allocator()) syntax::CallExpression, S);
1309af732203SDimitry Andric       return true;
1310af732203SDimitry Andric     }
13115ffd83dbSDimitry Andric     case syntax::NodeKind::UnknownExpression:
1312af732203SDimitry Andric       return WalkUpFromExpr(S);
13135ffd83dbSDimitry Andric     default:
13145ffd83dbSDimitry Andric       llvm_unreachable("getOperatorNodeKind() does not return this value");
13155ffd83dbSDimitry Andric     }
13165ffd83dbSDimitry Andric   }
13175ffd83dbSDimitry Andric 
WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr * S)1318af732203SDimitry Andric   bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S) { return true; }
1319af732203SDimitry Andric 
WalkUpFromNamespaceDecl(NamespaceDecl * S)1320480093f4SDimitry Andric   bool WalkUpFromNamespaceDecl(NamespaceDecl *S) {
13215ffd83dbSDimitry Andric     auto Tokens = Builder.getDeclarationRange(S);
1322480093f4SDimitry Andric     if (Tokens.front().kind() == tok::coloncolon) {
1323480093f4SDimitry Andric       // Handle nested namespace definitions. Those start at '::' token, e.g.
1324480093f4SDimitry Andric       // namespace a^::b {}
1325480093f4SDimitry Andric       // FIXME: build corresponding nodes for the name of this namespace.
1326480093f4SDimitry Andric       return true;
1327480093f4SDimitry Andric     }
13285ffd83dbSDimitry Andric     Builder.foldNode(Tokens, new (allocator()) syntax::NamespaceDefinition, S);
13295ffd83dbSDimitry Andric     return true;
13305ffd83dbSDimitry Andric   }
13315ffd83dbSDimitry Andric 
1332af732203SDimitry Andric   // FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test
1333af732203SDimitry Andric   // results. Find test coverage or remove it.
TraverseParenTypeLoc(ParenTypeLoc L)13345ffd83dbSDimitry Andric   bool TraverseParenTypeLoc(ParenTypeLoc L) {
13355ffd83dbSDimitry Andric     // We reverse order of traversal to get the proper syntax structure.
13365ffd83dbSDimitry Andric     if (!WalkUpFromParenTypeLoc(L))
13375ffd83dbSDimitry Andric       return false;
13385ffd83dbSDimitry Andric     return TraverseTypeLoc(L.getInnerLoc());
13395ffd83dbSDimitry Andric   }
13405ffd83dbSDimitry Andric 
WalkUpFromParenTypeLoc(ParenTypeLoc L)13415ffd83dbSDimitry Andric   bool WalkUpFromParenTypeLoc(ParenTypeLoc L) {
13425ffd83dbSDimitry Andric     Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
13435ffd83dbSDimitry Andric     Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
13445ffd83dbSDimitry Andric     Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getRParenLoc()),
13455ffd83dbSDimitry Andric                      new (allocator()) syntax::ParenDeclarator, L);
13465ffd83dbSDimitry Andric     return true;
13475ffd83dbSDimitry Andric   }
13485ffd83dbSDimitry Andric 
13495ffd83dbSDimitry Andric   // Declarator chunks, they are produced by type locs and some clang::Decls.
WalkUpFromArrayTypeLoc(ArrayTypeLoc L)13505ffd83dbSDimitry Andric   bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L) {
13515ffd83dbSDimitry Andric     Builder.markChildToken(L.getLBracketLoc(), syntax::NodeRole::OpenParen);
1352af732203SDimitry Andric     Builder.markExprChild(L.getSizeExpr(), syntax::NodeRole::Size);
13535ffd83dbSDimitry Andric     Builder.markChildToken(L.getRBracketLoc(), syntax::NodeRole::CloseParen);
13545ffd83dbSDimitry Andric     Builder.foldNode(Builder.getRange(L.getLBracketLoc(), L.getRBracketLoc()),
13555ffd83dbSDimitry Andric                      new (allocator()) syntax::ArraySubscript, L);
13565ffd83dbSDimitry Andric     return true;
13575ffd83dbSDimitry Andric   }
13585ffd83dbSDimitry Andric 
1359af732203SDimitry Andric   syntax::ParameterDeclarationList *
buildParameterDeclarationList(ArrayRef<ParmVarDecl * > Params)1360af732203SDimitry Andric   buildParameterDeclarationList(ArrayRef<ParmVarDecl *> Params) {
1361af732203SDimitry Andric     for (auto *P : Params) {
1362af732203SDimitry Andric       Builder.markChild(P, syntax::NodeRole::ListElement);
1363af732203SDimitry Andric       const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1364af732203SDimitry Andric       if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1365af732203SDimitry Andric         Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1366af732203SDimitry Andric     }
1367af732203SDimitry Andric     auto *Parameters = new (allocator()) syntax::ParameterDeclarationList;
1368af732203SDimitry Andric     if (!Params.empty())
1369af732203SDimitry Andric       Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1370af732203SDimitry Andric                                         Params.back()->getEndLoc()),
1371af732203SDimitry Andric                        Parameters, nullptr);
1372af732203SDimitry Andric     return Parameters;
1373af732203SDimitry Andric   }
1374af732203SDimitry Andric 
WalkUpFromFunctionTypeLoc(FunctionTypeLoc L)13755ffd83dbSDimitry Andric   bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) {
13765ffd83dbSDimitry Andric     Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
1377af732203SDimitry Andric 
1378af732203SDimitry Andric     Builder.markChild(buildParameterDeclarationList(L.getParams()),
1379af732203SDimitry Andric                       syntax::NodeRole::Parameters);
1380af732203SDimitry Andric 
13815ffd83dbSDimitry Andric     Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
13825ffd83dbSDimitry Andric     Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()),
13835ffd83dbSDimitry Andric                      new (allocator()) syntax::ParametersAndQualifiers, L);
13845ffd83dbSDimitry Andric     return true;
13855ffd83dbSDimitry Andric   }
13865ffd83dbSDimitry Andric 
WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L)13875ffd83dbSDimitry Andric   bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L) {
13885ffd83dbSDimitry Andric     if (!L.getTypePtr()->hasTrailingReturn())
13895ffd83dbSDimitry Andric       return WalkUpFromFunctionTypeLoc(L);
13905ffd83dbSDimitry Andric 
1391af732203SDimitry Andric     auto *TrailingReturnTokens = buildTrailingReturn(L);
13925ffd83dbSDimitry Andric     // Finish building the node for parameters.
1393af732203SDimitry Andric     Builder.markChild(TrailingReturnTokens, syntax::NodeRole::TrailingReturn);
13945ffd83dbSDimitry Andric     return WalkUpFromFunctionTypeLoc(L);
13955ffd83dbSDimitry Andric   }
13965ffd83dbSDimitry Andric 
TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L)1397af732203SDimitry Andric   bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) {
1398af732203SDimitry Andric     // In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds
1399af732203SDimitry Andric     // to "Y::*" but it points to a `ParenTypeLoc` that corresponds to
1400af732203SDimitry Andric     // "(Y::*mp)" We thus reverse the order of traversal to get the proper
1401af732203SDimitry Andric     // syntax structure.
1402af732203SDimitry Andric     if (!WalkUpFromMemberPointerTypeLoc(L))
1403af732203SDimitry Andric       return false;
1404af732203SDimitry Andric     return TraverseTypeLoc(L.getPointeeLoc());
1405af732203SDimitry Andric   }
1406af732203SDimitry Andric 
WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L)14075ffd83dbSDimitry Andric   bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) {
14085ffd83dbSDimitry Andric     auto SR = L.getLocalSourceRange();
14095ffd83dbSDimitry Andric     Builder.foldNode(Builder.getRange(SR),
14105ffd83dbSDimitry Andric                      new (allocator()) syntax::MemberPointer, L);
1411480093f4SDimitry Andric     return true;
1412480093f4SDimitry Andric   }
1413480093f4SDimitry Andric 
1414480093f4SDimitry Andric   // The code below is very regular, it could even be generated with some
1415480093f4SDimitry Andric   // preprocessor magic. We merely assign roles to the corresponding children
1416480093f4SDimitry Andric   // and fold resulting nodes.
WalkUpFromDeclStmt(DeclStmt * S)1417480093f4SDimitry Andric   bool WalkUpFromDeclStmt(DeclStmt *S) {
1418480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14195ffd83dbSDimitry Andric                      new (allocator()) syntax::DeclarationStatement, S);
1420480093f4SDimitry Andric     return true;
1421480093f4SDimitry Andric   }
1422480093f4SDimitry Andric 
WalkUpFromNullStmt(NullStmt * S)1423480093f4SDimitry Andric   bool WalkUpFromNullStmt(NullStmt *S) {
1424480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14255ffd83dbSDimitry Andric                      new (allocator()) syntax::EmptyStatement, S);
1426480093f4SDimitry Andric     return true;
1427480093f4SDimitry Andric   }
1428480093f4SDimitry Andric 
WalkUpFromSwitchStmt(SwitchStmt * S)1429480093f4SDimitry Andric   bool WalkUpFromSwitchStmt(SwitchStmt *S) {
1430480093f4SDimitry Andric     Builder.markChildToken(S->getSwitchLoc(),
1431480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1432480093f4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1433480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14345ffd83dbSDimitry Andric                      new (allocator()) syntax::SwitchStatement, S);
1435480093f4SDimitry Andric     return true;
1436480093f4SDimitry Andric   }
1437480093f4SDimitry Andric 
WalkUpFromCaseStmt(CaseStmt * S)1438480093f4SDimitry Andric   bool WalkUpFromCaseStmt(CaseStmt *S) {
1439480093f4SDimitry Andric     Builder.markChildToken(S->getKeywordLoc(),
1440480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1441af732203SDimitry Andric     Builder.markExprChild(S->getLHS(), syntax::NodeRole::CaseValue);
1442480093f4SDimitry Andric     Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement);
1443480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14445ffd83dbSDimitry Andric                      new (allocator()) syntax::CaseStatement, S);
1445480093f4SDimitry Andric     return true;
1446480093f4SDimitry Andric   }
1447480093f4SDimitry Andric 
WalkUpFromDefaultStmt(DefaultStmt * S)1448480093f4SDimitry Andric   bool WalkUpFromDefaultStmt(DefaultStmt *S) {
1449480093f4SDimitry Andric     Builder.markChildToken(S->getKeywordLoc(),
1450480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1451480093f4SDimitry Andric     Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement);
1452480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14535ffd83dbSDimitry Andric                      new (allocator()) syntax::DefaultStatement, S);
1454480093f4SDimitry Andric     return true;
1455480093f4SDimitry Andric   }
1456480093f4SDimitry Andric 
WalkUpFromIfStmt(IfStmt * S)1457480093f4SDimitry Andric   bool WalkUpFromIfStmt(IfStmt *S) {
1458480093f4SDimitry Andric     Builder.markChildToken(S->getIfLoc(), syntax::NodeRole::IntroducerKeyword);
1459*5f7ddb14SDimitry Andric     Stmt *ConditionStatement = S->getCond();
1460*5f7ddb14SDimitry Andric     if (S->hasVarStorage())
1461*5f7ddb14SDimitry Andric       ConditionStatement = S->getConditionVariableDeclStmt();
1462*5f7ddb14SDimitry Andric     Builder.markStmtChild(ConditionStatement, syntax::NodeRole::Condition);
1463af732203SDimitry Andric     Builder.markStmtChild(S->getThen(), syntax::NodeRole::ThenStatement);
1464af732203SDimitry Andric     Builder.markChildToken(S->getElseLoc(), syntax::NodeRole::ElseKeyword);
1465af732203SDimitry Andric     Builder.markStmtChild(S->getElse(), syntax::NodeRole::ElseStatement);
1466480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14675ffd83dbSDimitry Andric                      new (allocator()) syntax::IfStatement, S);
1468480093f4SDimitry Andric     return true;
1469480093f4SDimitry Andric   }
1470480093f4SDimitry Andric 
WalkUpFromForStmt(ForStmt * S)1471480093f4SDimitry Andric   bool WalkUpFromForStmt(ForStmt *S) {
1472480093f4SDimitry Andric     Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword);
1473480093f4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1474480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14755ffd83dbSDimitry Andric                      new (allocator()) syntax::ForStatement, S);
1476480093f4SDimitry Andric     return true;
1477480093f4SDimitry Andric   }
1478480093f4SDimitry Andric 
WalkUpFromWhileStmt(WhileStmt * S)1479480093f4SDimitry Andric   bool WalkUpFromWhileStmt(WhileStmt *S) {
1480480093f4SDimitry Andric     Builder.markChildToken(S->getWhileLoc(),
1481480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1482480093f4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1483480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14845ffd83dbSDimitry Andric                      new (allocator()) syntax::WhileStatement, S);
1485480093f4SDimitry Andric     return true;
1486480093f4SDimitry Andric   }
1487480093f4SDimitry Andric 
WalkUpFromContinueStmt(ContinueStmt * S)1488480093f4SDimitry Andric   bool WalkUpFromContinueStmt(ContinueStmt *S) {
1489480093f4SDimitry Andric     Builder.markChildToken(S->getContinueLoc(),
1490480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1491480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
14925ffd83dbSDimitry Andric                      new (allocator()) syntax::ContinueStatement, S);
1493480093f4SDimitry Andric     return true;
1494480093f4SDimitry Andric   }
1495480093f4SDimitry Andric 
WalkUpFromBreakStmt(BreakStmt * S)1496480093f4SDimitry Andric   bool WalkUpFromBreakStmt(BreakStmt *S) {
1497480093f4SDimitry Andric     Builder.markChildToken(S->getBreakLoc(),
1498480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1499480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
15005ffd83dbSDimitry Andric                      new (allocator()) syntax::BreakStatement, S);
1501480093f4SDimitry Andric     return true;
1502480093f4SDimitry Andric   }
1503480093f4SDimitry Andric 
WalkUpFromReturnStmt(ReturnStmt * S)1504480093f4SDimitry Andric   bool WalkUpFromReturnStmt(ReturnStmt *S) {
1505480093f4SDimitry Andric     Builder.markChildToken(S->getReturnLoc(),
1506480093f4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1507af732203SDimitry Andric     Builder.markExprChild(S->getRetValue(), syntax::NodeRole::ReturnValue);
1508480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
15095ffd83dbSDimitry Andric                      new (allocator()) syntax::ReturnStatement, S);
1510480093f4SDimitry Andric     return true;
1511480093f4SDimitry Andric   }
1512480093f4SDimitry Andric 
WalkUpFromCXXForRangeStmt(CXXForRangeStmt * S)1513480093f4SDimitry Andric   bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S) {
1514480093f4SDimitry Andric     Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword);
1515480093f4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1516480093f4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
15175ffd83dbSDimitry Andric                      new (allocator()) syntax::RangeBasedForStatement, S);
1518480093f4SDimitry Andric     return true;
1519480093f4SDimitry Andric   }
1520480093f4SDimitry Andric 
WalkUpFromEmptyDecl(EmptyDecl * S)1521480093f4SDimitry Andric   bool WalkUpFromEmptyDecl(EmptyDecl *S) {
15225ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15235ffd83dbSDimitry Andric                      new (allocator()) syntax::EmptyDeclaration, S);
1524480093f4SDimitry Andric     return true;
1525480093f4SDimitry Andric   }
1526480093f4SDimitry Andric 
WalkUpFromStaticAssertDecl(StaticAssertDecl * S)1527480093f4SDimitry Andric   bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S) {
1528af732203SDimitry Andric     Builder.markExprChild(S->getAssertExpr(), syntax::NodeRole::Condition);
1529af732203SDimitry Andric     Builder.markExprChild(S->getMessage(), syntax::NodeRole::Message);
15305ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15315ffd83dbSDimitry Andric                      new (allocator()) syntax::StaticAssertDeclaration, S);
1532480093f4SDimitry Andric     return true;
1533480093f4SDimitry Andric   }
1534480093f4SDimitry Andric 
WalkUpFromLinkageSpecDecl(LinkageSpecDecl * S)1535480093f4SDimitry Andric   bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) {
15365ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15375ffd83dbSDimitry Andric                      new (allocator()) syntax::LinkageSpecificationDeclaration,
15385ffd83dbSDimitry Andric                      S);
1539480093f4SDimitry Andric     return true;
1540480093f4SDimitry Andric   }
1541480093f4SDimitry Andric 
WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl * S)1542480093f4SDimitry Andric   bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) {
15435ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15445ffd83dbSDimitry Andric                      new (allocator()) syntax::NamespaceAliasDefinition, S);
1545480093f4SDimitry Andric     return true;
1546480093f4SDimitry Andric   }
1547480093f4SDimitry Andric 
WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl * S)1548480093f4SDimitry Andric   bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) {
15495ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15505ffd83dbSDimitry Andric                      new (allocator()) syntax::UsingNamespaceDirective, S);
1551480093f4SDimitry Andric     return true;
1552480093f4SDimitry Andric   }
1553480093f4SDimitry Andric 
WalkUpFromUsingDecl(UsingDecl * S)1554480093f4SDimitry Andric   bool WalkUpFromUsingDecl(UsingDecl *S) {
15555ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15565ffd83dbSDimitry Andric                      new (allocator()) syntax::UsingDeclaration, S);
1557480093f4SDimitry Andric     return true;
1558480093f4SDimitry Andric   }
1559480093f4SDimitry Andric 
WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * S)1560480093f4SDimitry Andric   bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) {
15615ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15625ffd83dbSDimitry Andric                      new (allocator()) syntax::UsingDeclaration, S);
1563480093f4SDimitry Andric     return true;
1564480093f4SDimitry Andric   }
1565480093f4SDimitry Andric 
WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * S)1566480093f4SDimitry Andric   bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) {
15675ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15685ffd83dbSDimitry Andric                      new (allocator()) syntax::UsingDeclaration, S);
1569480093f4SDimitry Andric     return true;
1570480093f4SDimitry Andric   }
1571480093f4SDimitry Andric 
WalkUpFromTypeAliasDecl(TypeAliasDecl * S)1572480093f4SDimitry Andric   bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) {
15735ffd83dbSDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
15745ffd83dbSDimitry Andric                      new (allocator()) syntax::TypeAliasDeclaration, S);
1575480093f4SDimitry Andric     return true;
1576480093f4SDimitry Andric   }
1577480093f4SDimitry Andric 
15780b57cec5SDimitry Andric private:
15795ffd83dbSDimitry Andric   /// Folds SimpleDeclarator node (if present) and in case this is the last
15805ffd83dbSDimitry Andric   /// declarator in the chain it also folds SimpleDeclaration node.
processDeclaratorAndDeclaration(T * D)15815ffd83dbSDimitry Andric   template <class T> bool processDeclaratorAndDeclaration(T *D) {
1582af732203SDimitry Andric     auto Range = getDeclaratorRange(
1583af732203SDimitry Andric         Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1584af732203SDimitry Andric         getQualifiedNameStart(D), getInitializerRange(D));
15855ffd83dbSDimitry Andric 
15865ffd83dbSDimitry Andric     // There doesn't have to be a declarator (e.g. `void foo(int)` only has
15875ffd83dbSDimitry Andric     // declaration, but no declarator).
1588af732203SDimitry Andric     if (!Range.getBegin().isValid()) {
1589af732203SDimitry Andric       Builder.markChild(new (allocator()) syntax::DeclaratorList,
1590af732203SDimitry Andric                         syntax::NodeRole::Declarators);
1591af732203SDimitry Andric       Builder.foldNode(Builder.getDeclarationRange(D),
1592af732203SDimitry Andric                        new (allocator()) syntax::SimpleDeclaration, D);
1593af732203SDimitry Andric       return true;
15945ffd83dbSDimitry Andric     }
15955ffd83dbSDimitry Andric 
1596af732203SDimitry Andric     auto *N = new (allocator()) syntax::SimpleDeclarator;
1597af732203SDimitry Andric     Builder.foldNode(Builder.getRange(Range), N, nullptr);
1598af732203SDimitry Andric     Builder.markChild(N, syntax::NodeRole::ListElement);
1599af732203SDimitry Andric 
1600af732203SDimitry Andric     if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1601af732203SDimitry Andric       // If this is not the last declarator in the declaration we expect a
1602af732203SDimitry Andric       // delimiter after it.
1603af732203SDimitry Andric       const auto *DelimiterToken = std::next(Builder.findToken(Range.getEnd()));
1604af732203SDimitry Andric       if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1605af732203SDimitry Andric         Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1606af732203SDimitry Andric     } else {
1607af732203SDimitry Andric       auto *DL = new (allocator()) syntax::DeclaratorList;
1608af732203SDimitry Andric       auto DeclarationRange = Builder.getDeclarationRange(D);
1609af732203SDimitry Andric       Builder.foldList(DeclarationRange, DL, nullptr);
1610af732203SDimitry Andric 
1611af732203SDimitry Andric       Builder.markChild(DL, syntax::NodeRole::Declarators);
1612af732203SDimitry Andric       Builder.foldNode(DeclarationRange,
16135ffd83dbSDimitry Andric                        new (allocator()) syntax::SimpleDeclaration, D);
16145ffd83dbSDimitry Andric     }
16155ffd83dbSDimitry Andric     return true;
16165ffd83dbSDimitry Andric   }
16175ffd83dbSDimitry Andric 
16185ffd83dbSDimitry Andric   /// Returns the range of the built node.
buildTrailingReturn(FunctionProtoTypeLoc L)1619af732203SDimitry Andric   syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
16205ffd83dbSDimitry Andric     assert(L.getTypePtr()->hasTrailingReturn());
16215ffd83dbSDimitry Andric 
16225ffd83dbSDimitry Andric     auto ReturnedType = L.getReturnLoc();
16235ffd83dbSDimitry Andric     // Build node for the declarator, if any.
1624af732203SDimitry Andric     auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1625af732203SDimitry Andric                                              ReturnedType.getEndLoc());
16265ffd83dbSDimitry Andric     syntax::SimpleDeclarator *ReturnDeclarator = nullptr;
16275ffd83dbSDimitry Andric     if (ReturnDeclaratorRange.isValid()) {
16285ffd83dbSDimitry Andric       ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator;
16295ffd83dbSDimitry Andric       Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
16305ffd83dbSDimitry Andric                        ReturnDeclarator, nullptr);
16315ffd83dbSDimitry Andric     }
16325ffd83dbSDimitry Andric 
16335ffd83dbSDimitry Andric     // Build node for trailing return type.
16345ffd83dbSDimitry Andric     auto Return = Builder.getRange(ReturnedType.getSourceRange());
16355ffd83dbSDimitry Andric     const auto *Arrow = Return.begin() - 1;
16365ffd83dbSDimitry Andric     assert(Arrow->kind() == tok::arrow);
16375ffd83dbSDimitry Andric     auto Tokens = llvm::makeArrayRef(Arrow, Return.end());
16385ffd83dbSDimitry Andric     Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
16395ffd83dbSDimitry Andric     if (ReturnDeclarator)
1640af732203SDimitry Andric       Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
16415ffd83dbSDimitry Andric     auto *R = new (allocator()) syntax::TrailingReturnType;
16425ffd83dbSDimitry Andric     Builder.foldNode(Tokens, R, L);
16435ffd83dbSDimitry Andric     return R;
16445ffd83dbSDimitry Andric   }
16455ffd83dbSDimitry Andric 
foldExplicitTemplateInstantiation(ArrayRef<syntax::Token> Range,const syntax::Token * ExternKW,const syntax::Token * TemplateKW,syntax::SimpleDeclaration * InnerDeclaration,Decl * From)16465ffd83dbSDimitry Andric   void foldExplicitTemplateInstantiation(
16475ffd83dbSDimitry Andric       ArrayRef<syntax::Token> Range, const syntax::Token *ExternKW,
16485ffd83dbSDimitry Andric       const syntax::Token *TemplateKW,
16495ffd83dbSDimitry Andric       syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
16505ffd83dbSDimitry Andric     assert(!ExternKW || ExternKW->kind() == tok::kw_extern);
16515ffd83dbSDimitry Andric     assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
16525ffd83dbSDimitry Andric     Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
16535ffd83dbSDimitry Andric     Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1654af732203SDimitry Andric     Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
16555ffd83dbSDimitry Andric     Builder.foldNode(
16565ffd83dbSDimitry Andric         Range, new (allocator()) syntax::ExplicitTemplateInstantiation, From);
16575ffd83dbSDimitry Andric   }
16585ffd83dbSDimitry Andric 
foldTemplateDeclaration(ArrayRef<syntax::Token> Range,const syntax::Token * TemplateKW,ArrayRef<syntax::Token> TemplatedDeclaration,Decl * From)16595ffd83dbSDimitry Andric   syntax::TemplateDeclaration *foldTemplateDeclaration(
16605ffd83dbSDimitry Andric       ArrayRef<syntax::Token> Range, const syntax::Token *TemplateKW,
16615ffd83dbSDimitry Andric       ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
16625ffd83dbSDimitry Andric     assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
16635ffd83dbSDimitry Andric     Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
16645ffd83dbSDimitry Andric 
16655ffd83dbSDimitry Andric     auto *N = new (allocator()) syntax::TemplateDeclaration;
16665ffd83dbSDimitry Andric     Builder.foldNode(Range, N, From);
1667af732203SDimitry Andric     Builder.markChild(N, syntax::NodeRole::Declaration);
16685ffd83dbSDimitry Andric     return N;
16695ffd83dbSDimitry Andric   }
16705ffd83dbSDimitry Andric 
16710b57cec5SDimitry Andric   /// A small helper to save some typing.
allocator()16720b57cec5SDimitry Andric   llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); }
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   syntax::TreeBuilder &Builder;
16755ffd83dbSDimitry Andric   const ASTContext &Context;
16760b57cec5SDimitry Andric };
16770b57cec5SDimitry Andric } // namespace
16780b57cec5SDimitry Andric 
noticeDeclWithoutSemicolon(Decl * D)16795ffd83dbSDimitry Andric void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) {
1680480093f4SDimitry Andric   DeclsWithoutSemicolons.insert(D);
1681480093f4SDimitry Andric }
1682480093f4SDimitry Andric 
markChildToken(SourceLocation Loc,NodeRole Role)1683480093f4SDimitry Andric void syntax::TreeBuilder::markChildToken(SourceLocation Loc, NodeRole Role) {
16840b57cec5SDimitry Andric   if (Loc.isInvalid())
16850b57cec5SDimitry Andric     return;
16860b57cec5SDimitry Andric   Pending.assignRole(*findToken(Loc), Role);
16870b57cec5SDimitry Andric }
16880b57cec5SDimitry Andric 
markChildToken(const syntax::Token * T,NodeRole R)16895ffd83dbSDimitry Andric void syntax::TreeBuilder::markChildToken(const syntax::Token *T, NodeRole R) {
16905ffd83dbSDimitry Andric   if (!T)
16915ffd83dbSDimitry Andric     return;
16925ffd83dbSDimitry Andric   Pending.assignRole(*T, R);
16935ffd83dbSDimitry Andric }
16945ffd83dbSDimitry Andric 
markChild(syntax::Node * N,NodeRole R)16955ffd83dbSDimitry Andric void syntax::TreeBuilder::markChild(syntax::Node *N, NodeRole R) {
16965ffd83dbSDimitry Andric   assert(N);
16975ffd83dbSDimitry Andric   setRole(N, R);
16985ffd83dbSDimitry Andric }
16995ffd83dbSDimitry Andric 
markChild(ASTPtr N,NodeRole R)17005ffd83dbSDimitry Andric void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
17015ffd83dbSDimitry Andric   auto *SN = Mapping.find(N);
17025ffd83dbSDimitry Andric   assert(SN != nullptr);
17035ffd83dbSDimitry Andric   setRole(SN, R);
17045ffd83dbSDimitry Andric }
markChild(NestedNameSpecifierLoc NNSLoc,NodeRole R)1705af732203SDimitry Andric void syntax::TreeBuilder::markChild(NestedNameSpecifierLoc NNSLoc, NodeRole R) {
1706af732203SDimitry Andric   auto *SN = Mapping.find(NNSLoc);
1707af732203SDimitry Andric   assert(SN != nullptr);
1708af732203SDimitry Andric   setRole(SN, R);
1709af732203SDimitry Andric }
17105ffd83dbSDimitry Andric 
markStmtChild(Stmt * Child,NodeRole Role)1711480093f4SDimitry Andric void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) {
1712480093f4SDimitry Andric   if (!Child)
1713480093f4SDimitry Andric     return;
1714480093f4SDimitry Andric 
17155ffd83dbSDimitry Andric   syntax::Tree *ChildNode;
17165ffd83dbSDimitry Andric   if (Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1717480093f4SDimitry Andric     // This is an expression in a statement position, consume the trailing
1718480093f4SDimitry Andric     // semicolon and form an 'ExpressionStatement' node.
1719af732203SDimitry Andric     markExprChild(ChildExpr, NodeRole::Expression);
17205ffd83dbSDimitry Andric     ChildNode = new (allocator()) syntax::ExpressionStatement;
17215ffd83dbSDimitry Andric     // (!) 'getStmtRange()' ensures this covers a trailing semicolon.
17225ffd83dbSDimitry Andric     Pending.foldChildren(Arena, getStmtRange(Child), ChildNode);
17235ffd83dbSDimitry Andric   } else {
17245ffd83dbSDimitry Andric     ChildNode = Mapping.find(Child);
1725480093f4SDimitry Andric   }
17265ffd83dbSDimitry Andric   assert(ChildNode != nullptr);
17275ffd83dbSDimitry Andric   setRole(ChildNode, Role);
1728480093f4SDimitry Andric }
1729480093f4SDimitry Andric 
markExprChild(Expr * Child,NodeRole Role)1730480093f4SDimitry Andric void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) {
1731480093f4SDimitry Andric   if (!Child)
1732480093f4SDimitry Andric     return;
1733af732203SDimitry Andric   Child = IgnoreImplicit(Child);
1734480093f4SDimitry Andric 
17355ffd83dbSDimitry Andric   syntax::Tree *ChildNode = Mapping.find(Child);
17365ffd83dbSDimitry Andric   assert(ChildNode != nullptr);
17375ffd83dbSDimitry Andric   setRole(ChildNode, Role);
1738480093f4SDimitry Andric }
1739480093f4SDimitry Andric 
findToken(SourceLocation L) const17400b57cec5SDimitry Andric const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const {
17415ffd83dbSDimitry Andric   if (L.isInvalid())
17425ffd83dbSDimitry Andric     return nullptr;
1743af732203SDimitry Andric   auto It = LocationToToken.find(L);
1744480093f4SDimitry Andric   assert(It != LocationToToken.end());
1745480093f4SDimitry Andric   return It->second;
17460b57cec5SDimitry Andric }
17470b57cec5SDimitry Andric 
buildSyntaxTree(Arena & A,ASTContext & Context)1748af732203SDimitry Andric syntax::TranslationUnit *syntax::buildSyntaxTree(Arena &A,
1749af732203SDimitry Andric                                                  ASTContext &Context) {
17500b57cec5SDimitry Andric   TreeBuilder Builder(A);
1751af732203SDimitry Andric   BuildTreeVisitor(Context, Builder).TraverseAST(Context);
17520b57cec5SDimitry Andric   return std::move(Builder).finalize();
17530b57cec5SDimitry Andric }
1754