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