xref: /src/contrib/llvm-project/clang/lib/Tooling/Syntax/BuildTree.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
122989816SDimitry Andric //===- BuildTree.cpp ------------------------------------------*- C++ -*-=====//
222989816SDimitry Andric //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
622989816SDimitry Andric //
722989816SDimitry Andric //===----------------------------------------------------------------------===//
822989816SDimitry Andric #include "clang/Tooling/Syntax/BuildTree.h"
9cfca06d7SDimitry Andric #include "clang/AST/ASTFwd.h"
10706b4fc4SDimitry Andric #include "clang/AST/Decl.h"
11706b4fc4SDimitry Andric #include "clang/AST/DeclBase.h"
12cfca06d7SDimitry Andric #include "clang/AST/DeclCXX.h"
13cfca06d7SDimitry Andric #include "clang/AST/DeclarationName.h"
14cfca06d7SDimitry Andric #include "clang/AST/Expr.h"
15cfca06d7SDimitry Andric #include "clang/AST/ExprCXX.h"
16b60736ecSDimitry Andric #include "clang/AST/IgnoreExpr.h"
17b60736ecSDimitry Andric #include "clang/AST/OperationKinds.h"
1822989816SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
1922989816SDimitry Andric #include "clang/AST/Stmt.h"
20cfca06d7SDimitry Andric #include "clang/AST/TypeLoc.h"
21cfca06d7SDimitry Andric #include "clang/AST/TypeLocVisitor.h"
2222989816SDimitry Andric #include "clang/Basic/LLVM.h"
2322989816SDimitry Andric #include "clang/Basic/SourceLocation.h"
2422989816SDimitry Andric #include "clang/Basic/SourceManager.h"
25cfca06d7SDimitry Andric #include "clang/Basic/Specifiers.h"
2622989816SDimitry Andric #include "clang/Basic/TokenKinds.h"
2722989816SDimitry Andric #include "clang/Lex/Lexer.h"
28cfca06d7SDimitry Andric #include "clang/Lex/LiteralSupport.h"
2922989816SDimitry Andric #include "clang/Tooling/Syntax/Nodes.h"
304b4fe385SDimitry Andric #include "clang/Tooling/Syntax/TokenBufferTokenManager.h"
3122989816SDimitry Andric #include "clang/Tooling/Syntax/Tokens.h"
3222989816SDimitry Andric #include "clang/Tooling/Syntax/Tree.h"
3322989816SDimitry Andric #include "llvm/ADT/ArrayRef.h"
34cfca06d7SDimitry Andric #include "llvm/ADT/DenseMap.h"
35cfca06d7SDimitry Andric #include "llvm/ADT/PointerUnion.h"
3622989816SDimitry Andric #include "llvm/ADT/STLExtras.h"
37cfca06d7SDimitry Andric #include "llvm/ADT/ScopeExit.h"
3822989816SDimitry Andric #include "llvm/ADT/SmallVector.h"
3922989816SDimitry Andric #include "llvm/Support/Allocator.h"
4022989816SDimitry Andric #include "llvm/Support/Casting.h"
41706b4fc4SDimitry Andric #include "llvm/Support/Compiler.h"
4222989816SDimitry Andric #include "llvm/Support/FormatVariadic.h"
43706b4fc4SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
4422989816SDimitry Andric #include "llvm/Support/raw_ostream.h"
45cfca06d7SDimitry Andric #include <cstddef>
4622989816SDimitry Andric #include <map>
4722989816SDimitry Andric 
4822989816SDimitry Andric using namespace clang;
4922989816SDimitry Andric 
50b60736ecSDimitry Andric // Ignores the implicit `CXXConstructExpr` for copy/move constructor calls
51b60736ecSDimitry Andric // generated by the compiler, as well as in implicit conversions like the one
52b60736ecSDimitry Andric // wrapping `1` in `X x = 1;`.
IgnoreImplicitConstructorSingleStep(Expr * E)53b60736ecSDimitry Andric static Expr *IgnoreImplicitConstructorSingleStep(Expr *E) {
54b60736ecSDimitry Andric   if (auto *C = dyn_cast<CXXConstructExpr>(E)) {
55b60736ecSDimitry Andric     auto NumArgs = C->getNumArgs();
56b60736ecSDimitry Andric     if (NumArgs == 1 || (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) {
57b60736ecSDimitry Andric       Expr *A = C->getArg(0);
58b60736ecSDimitry Andric       if (C->getParenOrBraceRange().isInvalid())
59b60736ecSDimitry Andric         return A;
60b60736ecSDimitry Andric     }
61b60736ecSDimitry Andric   }
62b60736ecSDimitry Andric   return E;
63b60736ecSDimitry Andric }
64b60736ecSDimitry Andric 
65b60736ecSDimitry Andric // In:
66b60736ecSDimitry Andric // struct X {
67b60736ecSDimitry Andric //   X(int)
68b60736ecSDimitry Andric // };
69b60736ecSDimitry Andric // X x = X(1);
70b60736ecSDimitry Andric // Ignores the implicit `CXXFunctionalCastExpr` that wraps
71b60736ecSDimitry Andric // `CXXConstructExpr X(1)`.
IgnoreCXXFunctionalCastExprWrappingConstructor(Expr * E)72b60736ecSDimitry Andric static Expr *IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E) {
73b60736ecSDimitry Andric   if (auto *F = dyn_cast<CXXFunctionalCastExpr>(E)) {
74b60736ecSDimitry Andric     if (F->getCastKind() == CK_ConstructorConversion)
75b60736ecSDimitry Andric       return F->getSubExpr();
76b60736ecSDimitry Andric   }
77b60736ecSDimitry Andric   return E;
78b60736ecSDimitry Andric }
79b60736ecSDimitry Andric 
IgnoreImplicit(Expr * E)80b60736ecSDimitry Andric static Expr *IgnoreImplicit(Expr *E) {
81b60736ecSDimitry Andric   return IgnoreExprNodes(E, IgnoreImplicitSingleStep,
82b60736ecSDimitry Andric                          IgnoreImplicitConstructorSingleStep,
83b60736ecSDimitry Andric                          IgnoreCXXFunctionalCastExprWrappingConstructor);
84b60736ecSDimitry Andric }
85b60736ecSDimitry Andric 
86706b4fc4SDimitry Andric LLVM_ATTRIBUTE_UNUSED
isImplicitExpr(Expr * E)87b60736ecSDimitry Andric static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; }
88706b4fc4SDimitry Andric 
89cfca06d7SDimitry Andric namespace {
90cfca06d7SDimitry Andric /// Get start location of the Declarator from the TypeLoc.
91cfca06d7SDimitry Andric /// E.g.:
92cfca06d7SDimitry Andric ///   loc of `(` in `int (a)`
93cfca06d7SDimitry Andric ///   loc of `*` in `int *(a)`
94cfca06d7SDimitry Andric ///   loc of the first `(` in `int (*a)(int)`
95cfca06d7SDimitry Andric ///   loc of the `*` in `int *(a)(int)`
96cfca06d7SDimitry Andric ///   loc of the first `*` in `const int *const *volatile a;`
97cfca06d7SDimitry Andric ///
98cfca06d7SDimitry Andric /// It is non-trivial to get the start location because TypeLocs are stored
99cfca06d7SDimitry Andric /// inside out. In the example above `*volatile` is the TypeLoc returned
100cfca06d7SDimitry Andric /// by `Decl.getTypeSourceInfo()`, and `*const` is what `.getPointeeLoc()`
101cfca06d7SDimitry Andric /// returns.
102cfca06d7SDimitry Andric struct GetStartLoc : TypeLocVisitor<GetStartLoc, SourceLocation> {
VisitParenTypeLoc__anon99e135900111::GetStartLoc103cfca06d7SDimitry Andric   SourceLocation VisitParenTypeLoc(ParenTypeLoc T) {
104cfca06d7SDimitry Andric     auto L = Visit(T.getInnerLoc());
105cfca06d7SDimitry Andric     if (L.isValid())
106cfca06d7SDimitry Andric       return L;
107cfca06d7SDimitry Andric     return T.getLParenLoc();
108cfca06d7SDimitry Andric   }
109cfca06d7SDimitry Andric 
110cfca06d7SDimitry Andric   // Types spelled in the prefix part of the declarator.
VisitPointerTypeLoc__anon99e135900111::GetStartLoc111cfca06d7SDimitry Andric   SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) {
112cfca06d7SDimitry Andric     return HandlePointer(T);
113cfca06d7SDimitry Andric   }
114cfca06d7SDimitry Andric 
VisitMemberPointerTypeLoc__anon99e135900111::GetStartLoc115cfca06d7SDimitry Andric   SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
116cfca06d7SDimitry Andric     return HandlePointer(T);
117cfca06d7SDimitry Andric   }
118cfca06d7SDimitry Andric 
VisitBlockPointerTypeLoc__anon99e135900111::GetStartLoc119cfca06d7SDimitry Andric   SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
120cfca06d7SDimitry Andric     return HandlePointer(T);
121cfca06d7SDimitry Andric   }
122cfca06d7SDimitry Andric 
VisitReferenceTypeLoc__anon99e135900111::GetStartLoc123cfca06d7SDimitry Andric   SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) {
124cfca06d7SDimitry Andric     return HandlePointer(T);
125cfca06d7SDimitry Andric   }
126cfca06d7SDimitry Andric 
VisitObjCObjectPointerTypeLoc__anon99e135900111::GetStartLoc127cfca06d7SDimitry Andric   SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) {
128cfca06d7SDimitry Andric     return HandlePointer(T);
129cfca06d7SDimitry Andric   }
130cfca06d7SDimitry Andric 
131cfca06d7SDimitry Andric   // All other cases are not important, as they are either part of declaration
132cfca06d7SDimitry Andric   // specifiers (e.g. inheritors of TypeSpecTypeLoc) or introduce modifiers on
133cfca06d7SDimitry Andric   // existing declarators (e.g. QualifiedTypeLoc). They cannot start the
134cfca06d7SDimitry Andric   // declarator themselves, but their underlying type can.
VisitTypeLoc__anon99e135900111::GetStartLoc135cfca06d7SDimitry Andric   SourceLocation VisitTypeLoc(TypeLoc T) {
136cfca06d7SDimitry Andric     auto N = T.getNextTypeLoc();
137cfca06d7SDimitry Andric     if (!N)
138cfca06d7SDimitry Andric       return SourceLocation();
139cfca06d7SDimitry Andric     return Visit(N);
140cfca06d7SDimitry Andric   }
141cfca06d7SDimitry Andric 
VisitFunctionProtoTypeLoc__anon99e135900111::GetStartLoc142cfca06d7SDimitry Andric   SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) {
143cfca06d7SDimitry Andric     if (T.getTypePtr()->hasTrailingReturn())
144cfca06d7SDimitry Andric       return SourceLocation(); // avoid recursing into the suffix of declarator.
145cfca06d7SDimitry Andric     return VisitTypeLoc(T);
146cfca06d7SDimitry Andric   }
147cfca06d7SDimitry Andric 
148cfca06d7SDimitry Andric private:
HandlePointer__anon99e135900111::GetStartLoc149cfca06d7SDimitry Andric   template <class PtrLoc> SourceLocation HandlePointer(PtrLoc T) {
150cfca06d7SDimitry Andric     auto L = Visit(T.getPointeeLoc());
151cfca06d7SDimitry Andric     if (L.isValid())
152cfca06d7SDimitry Andric       return L;
153cfca06d7SDimitry Andric     return T.getLocalSourceRange().getBegin();
154cfca06d7SDimitry Andric   }
155cfca06d7SDimitry Andric };
156cfca06d7SDimitry Andric } // namespace
157cfca06d7SDimitry Andric 
dropDefaultArgs(CallExpr::arg_range Args)158b60736ecSDimitry Andric static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args) {
159c0981da4SDimitry Andric   auto FirstDefaultArg =
160c0981da4SDimitry Andric       llvm::find_if(Args, [](auto It) { return isa<CXXDefaultArgExpr>(It); });
161b60736ecSDimitry Andric   return llvm::make_range(Args.begin(), FirstDefaultArg);
162b60736ecSDimitry Andric }
163b60736ecSDimitry Andric 
getOperatorNodeKind(const CXXOperatorCallExpr & E)164cfca06d7SDimitry Andric static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) {
165cfca06d7SDimitry Andric   switch (E.getOperator()) {
166cfca06d7SDimitry Andric   // Comparison
167cfca06d7SDimitry Andric   case OO_EqualEqual:
168cfca06d7SDimitry Andric   case OO_ExclaimEqual:
169cfca06d7SDimitry Andric   case OO_Greater:
170cfca06d7SDimitry Andric   case OO_GreaterEqual:
171cfca06d7SDimitry Andric   case OO_Less:
172cfca06d7SDimitry Andric   case OO_LessEqual:
173cfca06d7SDimitry Andric   case OO_Spaceship:
174cfca06d7SDimitry Andric   // Assignment
175cfca06d7SDimitry Andric   case OO_Equal:
176cfca06d7SDimitry Andric   case OO_SlashEqual:
177cfca06d7SDimitry Andric   case OO_PercentEqual:
178cfca06d7SDimitry Andric   case OO_CaretEqual:
179cfca06d7SDimitry Andric   case OO_PipeEqual:
180cfca06d7SDimitry Andric   case OO_LessLessEqual:
181cfca06d7SDimitry Andric   case OO_GreaterGreaterEqual:
182cfca06d7SDimitry Andric   case OO_PlusEqual:
183cfca06d7SDimitry Andric   case OO_MinusEqual:
184cfca06d7SDimitry Andric   case OO_StarEqual:
185cfca06d7SDimitry Andric   case OO_AmpEqual:
186cfca06d7SDimitry Andric   // Binary computation
187cfca06d7SDimitry Andric   case OO_Slash:
188cfca06d7SDimitry Andric   case OO_Percent:
189cfca06d7SDimitry Andric   case OO_Caret:
190cfca06d7SDimitry Andric   case OO_Pipe:
191cfca06d7SDimitry Andric   case OO_LessLess:
192cfca06d7SDimitry Andric   case OO_GreaterGreater:
193cfca06d7SDimitry Andric   case OO_AmpAmp:
194cfca06d7SDimitry Andric   case OO_PipePipe:
195cfca06d7SDimitry Andric   case OO_ArrowStar:
196cfca06d7SDimitry Andric   case OO_Comma:
197cfca06d7SDimitry Andric     return syntax::NodeKind::BinaryOperatorExpression;
198cfca06d7SDimitry Andric   case OO_Tilde:
199cfca06d7SDimitry Andric   case OO_Exclaim:
200cfca06d7SDimitry Andric     return syntax::NodeKind::PrefixUnaryOperatorExpression;
201cfca06d7SDimitry Andric   // Prefix/Postfix increment/decrement
202cfca06d7SDimitry Andric   case OO_PlusPlus:
203cfca06d7SDimitry Andric   case OO_MinusMinus:
204cfca06d7SDimitry Andric     switch (E.getNumArgs()) {
205cfca06d7SDimitry Andric     case 1:
206cfca06d7SDimitry Andric       return syntax::NodeKind::PrefixUnaryOperatorExpression;
207cfca06d7SDimitry Andric     case 2:
208cfca06d7SDimitry Andric       return syntax::NodeKind::PostfixUnaryOperatorExpression;
209cfca06d7SDimitry Andric     default:
210cfca06d7SDimitry Andric       llvm_unreachable("Invalid number of arguments for operator");
211cfca06d7SDimitry Andric     }
212cfca06d7SDimitry Andric   // Operators that can be unary or binary
213cfca06d7SDimitry Andric   case OO_Plus:
214cfca06d7SDimitry Andric   case OO_Minus:
215cfca06d7SDimitry Andric   case OO_Star:
216cfca06d7SDimitry Andric   case OO_Amp:
217cfca06d7SDimitry Andric     switch (E.getNumArgs()) {
218cfca06d7SDimitry Andric     case 1:
219cfca06d7SDimitry Andric       return syntax::NodeKind::PrefixUnaryOperatorExpression;
220cfca06d7SDimitry Andric     case 2:
221cfca06d7SDimitry Andric       return syntax::NodeKind::BinaryOperatorExpression;
222cfca06d7SDimitry Andric     default:
223cfca06d7SDimitry Andric       llvm_unreachable("Invalid number of arguments for operator");
224cfca06d7SDimitry Andric     }
225cfca06d7SDimitry Andric     return syntax::NodeKind::BinaryOperatorExpression;
226cfca06d7SDimitry Andric   // Not yet supported by SyntaxTree
227cfca06d7SDimitry Andric   case OO_New:
228cfca06d7SDimitry Andric   case OO_Delete:
229cfca06d7SDimitry Andric   case OO_Array_New:
230cfca06d7SDimitry Andric   case OO_Array_Delete:
231cfca06d7SDimitry Andric   case OO_Coawait:
232cfca06d7SDimitry Andric   case OO_Subscript:
233cfca06d7SDimitry Andric   case OO_Arrow:
234cfca06d7SDimitry Andric     return syntax::NodeKind::UnknownExpression;
235b60736ecSDimitry Andric   case OO_Call:
236b60736ecSDimitry Andric     return syntax::NodeKind::CallExpression;
237cfca06d7SDimitry Andric   case OO_Conditional: // not overloadable
238cfca06d7SDimitry Andric   case NUM_OVERLOADED_OPERATORS:
239cfca06d7SDimitry Andric   case OO_None:
240cfca06d7SDimitry Andric     llvm_unreachable("Not an overloadable operator");
241cfca06d7SDimitry Andric   }
242cfca06d7SDimitry Andric   llvm_unreachable("Unknown OverloadedOperatorKind enum");
243cfca06d7SDimitry Andric }
244cfca06d7SDimitry Andric 
245b60736ecSDimitry Andric /// Get the start of the qualified name. In the examples below it gives the
246b60736ecSDimitry Andric /// location of the `^`:
247b60736ecSDimitry Andric ///     `int ^a;`
248b60736ecSDimitry Andric ///     `int *^a;`
249b60736ecSDimitry Andric ///     `int ^a::S::f(){}`
getQualifiedNameStart(NamedDecl * D)250b60736ecSDimitry Andric static SourceLocation getQualifiedNameStart(NamedDecl *D) {
251b60736ecSDimitry Andric   assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) &&
252b60736ecSDimitry Andric          "only DeclaratorDecl and TypedefNameDecl are supported.");
253b60736ecSDimitry Andric 
254b60736ecSDimitry Andric   auto DN = D->getDeclName();
255b60736ecSDimitry Andric   bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo();
256b60736ecSDimitry Andric   if (IsAnonymous)
257b60736ecSDimitry Andric     return SourceLocation();
258b60736ecSDimitry Andric 
259b60736ecSDimitry Andric   if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
260b60736ecSDimitry Andric     if (DD->getQualifierLoc()) {
261b60736ecSDimitry Andric       return DD->getQualifierLoc().getBeginLoc();
262b60736ecSDimitry Andric     }
263b60736ecSDimitry Andric   }
264b60736ecSDimitry Andric 
265b60736ecSDimitry Andric   return D->getLocation();
266b60736ecSDimitry Andric }
267b60736ecSDimitry Andric 
268b60736ecSDimitry Andric /// Gets the range of the initializer inside an init-declarator C++ [dcl.decl].
269b60736ecSDimitry Andric ///     `int a;` -> range of ``,
270b60736ecSDimitry Andric ///     `int *a = nullptr` -> range of `= nullptr`.
271b60736ecSDimitry Andric ///     `int a{}` -> range of `{}`.
272b60736ecSDimitry Andric ///     `int a()` -> range of `()`.
getInitializerRange(Decl * D)273b60736ecSDimitry Andric static SourceRange getInitializerRange(Decl *D) {
274b60736ecSDimitry Andric   if (auto *V = dyn_cast<VarDecl>(D)) {
275b60736ecSDimitry Andric     auto *I = V->getInit();
276b60736ecSDimitry Andric     // Initializers in range-based-for are not part of the declarator
277b60736ecSDimitry Andric     if (I && !V->isCXXForRangeDecl())
278b60736ecSDimitry Andric       return I->getSourceRange();
279b60736ecSDimitry Andric   }
280b60736ecSDimitry Andric 
281b60736ecSDimitry Andric   return SourceRange();
282b60736ecSDimitry Andric }
283b60736ecSDimitry Andric 
284cfca06d7SDimitry Andric /// Gets the range of declarator as defined by the C++ grammar. E.g.
285cfca06d7SDimitry Andric ///     `int a;` -> range of `a`,
286cfca06d7SDimitry Andric ///     `int *a;` -> range of `*a`,
287cfca06d7SDimitry Andric ///     `int a[10];` -> range of `a[10]`,
288cfca06d7SDimitry Andric ///     `int a[1][2][3];` -> range of `a[1][2][3]`,
289cfca06d7SDimitry Andric ///     `int *a = nullptr` -> range of `*a = nullptr`.
290b60736ecSDimitry Andric ///     `int S::f(){}` -> range of `S::f()`.
291b60736ecSDimitry Andric /// FIXME: \p Name must be a source range.
getDeclaratorRange(const SourceManager & SM,TypeLoc T,SourceLocation Name,SourceRange Initializer)292cfca06d7SDimitry Andric static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T,
293cfca06d7SDimitry Andric                                       SourceLocation Name,
294cfca06d7SDimitry Andric                                       SourceRange Initializer) {
295cfca06d7SDimitry Andric   SourceLocation Start = GetStartLoc().Visit(T);
296b60736ecSDimitry Andric   SourceLocation End = T.getEndLoc();
297cfca06d7SDimitry Andric   if (Name.isValid()) {
298cfca06d7SDimitry Andric     if (Start.isInvalid())
299cfca06d7SDimitry Andric       Start = Name;
300344a3780SDimitry Andric     // End of TypeLoc could be invalid if the type is invalid, fallback to the
301344a3780SDimitry Andric     // NameLoc.
302344a3780SDimitry Andric     if (End.isInvalid() || SM.isBeforeInTranslationUnit(End, Name))
303cfca06d7SDimitry Andric       End = Name;
304cfca06d7SDimitry Andric   }
305cfca06d7SDimitry Andric   if (Initializer.isValid()) {
306cfca06d7SDimitry Andric     auto InitializerEnd = Initializer.getEnd();
307cfca06d7SDimitry Andric     assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) ||
308cfca06d7SDimitry Andric            End == InitializerEnd);
309cfca06d7SDimitry Andric     End = InitializerEnd;
310cfca06d7SDimitry Andric   }
311cfca06d7SDimitry Andric   return SourceRange(Start, End);
312cfca06d7SDimitry Andric }
313cfca06d7SDimitry Andric 
314cfca06d7SDimitry Andric namespace {
315cfca06d7SDimitry Andric /// All AST hierarchy roots that can be represented as pointers.
316cfca06d7SDimitry Andric using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>;
317cfca06d7SDimitry Andric /// Maintains a mapping from AST to syntax tree nodes. This class will get more
318cfca06d7SDimitry Andric /// complicated as we support more kinds of AST nodes, e.g. TypeLocs.
319cfca06d7SDimitry Andric /// FIXME: expose this as public API.
320cfca06d7SDimitry Andric class ASTToSyntaxMapping {
321cfca06d7SDimitry Andric public:
add(ASTPtr From,syntax::Tree * To)322cfca06d7SDimitry Andric   void add(ASTPtr From, syntax::Tree *To) {
323cfca06d7SDimitry Andric     assert(To != nullptr);
324cfca06d7SDimitry Andric     assert(!From.isNull());
325cfca06d7SDimitry Andric 
326cfca06d7SDimitry Andric     bool Added = Nodes.insert({From, To}).second;
327cfca06d7SDimitry Andric     (void)Added;
328cfca06d7SDimitry Andric     assert(Added && "mapping added twice");
329cfca06d7SDimitry Andric   }
330cfca06d7SDimitry Andric 
add(NestedNameSpecifierLoc From,syntax::Tree * To)331b60736ecSDimitry Andric   void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
332b60736ecSDimitry Andric     assert(To != nullptr);
333b60736ecSDimitry Andric     assert(From.hasQualifier());
334b60736ecSDimitry Andric 
335b60736ecSDimitry Andric     bool Added = NNSNodes.insert({From, To}).second;
336b60736ecSDimitry Andric     (void)Added;
337b60736ecSDimitry Andric     assert(Added && "mapping added twice");
338b60736ecSDimitry Andric   }
339b60736ecSDimitry Andric 
find(ASTPtr P) const340cfca06d7SDimitry Andric   syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }
341cfca06d7SDimitry Andric 
find(NestedNameSpecifierLoc P) const342b60736ecSDimitry Andric   syntax::Tree *find(NestedNameSpecifierLoc P) const {
343b60736ecSDimitry Andric     return NNSNodes.lookup(P);
344b60736ecSDimitry Andric   }
345b60736ecSDimitry Andric 
346cfca06d7SDimitry Andric private:
347cfca06d7SDimitry Andric   llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes;
348b60736ecSDimitry Andric   llvm::DenseMap<NestedNameSpecifierLoc, syntax::Tree *> NNSNodes;
349cfca06d7SDimitry Andric };
350cfca06d7SDimitry Andric } // namespace
351cfca06d7SDimitry Andric 
35222989816SDimitry Andric /// A helper class for constructing the syntax tree while traversing a clang
35322989816SDimitry Andric /// AST.
35422989816SDimitry Andric ///
35522989816SDimitry Andric /// At each point of the traversal we maintain a list of pending nodes.
35622989816SDimitry Andric /// Initially all tokens are added as pending nodes. When processing a clang AST
35722989816SDimitry Andric /// node, the clients need to:
35822989816SDimitry Andric ///   - create a corresponding syntax node,
35922989816SDimitry Andric ///   - assign roles to all pending child nodes with 'markChild' and
36022989816SDimitry Andric ///     'markChildToken',
36122989816SDimitry Andric ///   - replace the child nodes with the new syntax node in the pending list
36222989816SDimitry Andric ///     with 'foldNode'.
36322989816SDimitry Andric ///
36422989816SDimitry Andric /// Note that all children are expected to be processed when building a node.
36522989816SDimitry Andric ///
36622989816SDimitry Andric /// Call finalize() to finish building the tree and consume the root node.
36722989816SDimitry Andric class syntax::TreeBuilder {
36822989816SDimitry Andric public:
TreeBuilder(syntax::Arena & Arena,TokenBufferTokenManager & TBTM)3694b4fe385SDimitry Andric   TreeBuilder(syntax::Arena &Arena, TokenBufferTokenManager& TBTM)
3704b4fe385SDimitry Andric       : Arena(Arena),
3714b4fe385SDimitry Andric         TBTM(TBTM),
3724b4fe385SDimitry Andric         Pending(Arena, TBTM.tokenBuffer()) {
3734b4fe385SDimitry Andric     for (const auto &T : TBTM.tokenBuffer().expandedTokens())
374b60736ecSDimitry Andric       LocationToToken.insert({T.location(), &T});
375706b4fc4SDimitry Andric   }
37622989816SDimitry Andric 
allocator()377b60736ecSDimitry Andric   llvm::BumpPtrAllocator &allocator() { return Arena.getAllocator(); }
sourceManager() const378b60736ecSDimitry Andric   const SourceManager &sourceManager() const {
3794b4fe385SDimitry Andric     return TBTM.sourceManager();
380b60736ecSDimitry Andric   }
38122989816SDimitry Andric 
38222989816SDimitry Andric   /// Populate children for \p New node, assuming it covers tokens from \p
38322989816SDimitry Andric   /// Range.
foldNode(ArrayRef<syntax::Token> Range,syntax::Tree * New,ASTPtr From)384b60736ecSDimitry Andric   void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, ASTPtr From) {
385cfca06d7SDimitry Andric     assert(New);
3864b4fe385SDimitry Andric     Pending.foldChildren(TBTM.tokenBuffer(), Range, New);
387cfca06d7SDimitry Andric     if (From)
388cfca06d7SDimitry Andric       Mapping.add(From, New);
389cfca06d7SDimitry Andric   }
390b60736ecSDimitry Andric 
foldNode(ArrayRef<syntax::Token> Range,syntax::Tree * New,TypeLoc L)391b60736ecSDimitry Andric   void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, TypeLoc L) {
392cfca06d7SDimitry Andric     // FIXME: add mapping for TypeLocs
393cfca06d7SDimitry Andric     foldNode(Range, New, nullptr);
394cfca06d7SDimitry Andric   }
395706b4fc4SDimitry Andric 
foldNode(llvm::ArrayRef<syntax::Token> Range,syntax::Tree * New,NestedNameSpecifierLoc From)396b60736ecSDimitry Andric   void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New,
397b60736ecSDimitry Andric                 NestedNameSpecifierLoc From) {
398b60736ecSDimitry Andric     assert(New);
3994b4fe385SDimitry Andric     Pending.foldChildren(TBTM.tokenBuffer(), Range, New);
400b60736ecSDimitry Andric     if (From)
401b60736ecSDimitry Andric       Mapping.add(From, New);
402b60736ecSDimitry Andric   }
403b60736ecSDimitry Andric 
404b60736ecSDimitry Andric   /// Populate children for \p New list, assuming it covers tokens from a
405b60736ecSDimitry Andric   /// subrange of \p SuperRange.
foldList(ArrayRef<syntax::Token> SuperRange,syntax::List * New,ASTPtr From)406b60736ecSDimitry Andric   void foldList(ArrayRef<syntax::Token> SuperRange, syntax::List *New,
407b60736ecSDimitry Andric                 ASTPtr From) {
408b60736ecSDimitry Andric     assert(New);
409b60736ecSDimitry Andric     auto ListRange = Pending.shrinkToFitList(SuperRange);
4104b4fe385SDimitry Andric     Pending.foldChildren(TBTM.tokenBuffer(), ListRange, New);
411b60736ecSDimitry Andric     if (From)
412b60736ecSDimitry Andric       Mapping.add(From, New);
413b60736ecSDimitry Andric   }
414b60736ecSDimitry Andric 
415706b4fc4SDimitry Andric   /// Notifies that we should not consume trailing semicolon when computing
416706b4fc4SDimitry Andric   /// token range of \p D.
417cfca06d7SDimitry Andric   void noticeDeclWithoutSemicolon(Decl *D);
418706b4fc4SDimitry Andric 
419706b4fc4SDimitry Andric   /// Mark the \p Child node with a corresponding \p Role. All marked children
420706b4fc4SDimitry Andric   /// should be consumed by foldNode.
421cfca06d7SDimitry Andric   /// When called on expressions (clang::Expr is derived from clang::Stmt),
422706b4fc4SDimitry Andric   /// wraps expressions into expression statement.
423706b4fc4SDimitry Andric   void markStmtChild(Stmt *Child, NodeRole Role);
424706b4fc4SDimitry Andric   /// Should be called for expressions in non-statement position to avoid
425706b4fc4SDimitry Andric   /// wrapping into expression statement.
426706b4fc4SDimitry Andric   void markExprChild(Expr *Child, NodeRole Role);
42722989816SDimitry Andric   /// Set role for a token starting at \p Loc.
428706b4fc4SDimitry Andric   void markChildToken(SourceLocation Loc, NodeRole R);
429cfca06d7SDimitry Andric   /// Set role for \p T.
430cfca06d7SDimitry Andric   void markChildToken(const syntax::Token *T, NodeRole R);
431cfca06d7SDimitry Andric 
432cfca06d7SDimitry Andric   /// Set role for \p N.
433cfca06d7SDimitry Andric   void markChild(syntax::Node *N, NodeRole R);
434cfca06d7SDimitry Andric   /// Set role for the syntax node matching \p N.
435cfca06d7SDimitry Andric   void markChild(ASTPtr N, NodeRole R);
436b60736ecSDimitry Andric   /// Set role for the syntax node matching \p N.
437b60736ecSDimitry Andric   void markChild(NestedNameSpecifierLoc N, NodeRole R);
43822989816SDimitry Andric 
43922989816SDimitry Andric   /// Finish building the tree and consume the root node.
finalize()44022989816SDimitry Andric   syntax::TranslationUnit *finalize() && {
4414b4fe385SDimitry Andric     auto Tokens = TBTM.tokenBuffer().expandedTokens();
442519fc96cSDimitry Andric     assert(!Tokens.empty());
443519fc96cSDimitry Andric     assert(Tokens.back().kind() == tok::eof);
444519fc96cSDimitry Andric 
44522989816SDimitry Andric     // Build the root of the tree, consuming all the children.
4464b4fe385SDimitry Andric     Pending.foldChildren(TBTM.tokenBuffer(), Tokens.drop_back(),
447b60736ecSDimitry Andric                          new (Arena.getAllocator()) syntax::TranslationUnit);
44822989816SDimitry Andric 
449706b4fc4SDimitry Andric     auto *TU = cast<syntax::TranslationUnit>(std::move(Pending).finalize());
450706b4fc4SDimitry Andric     TU->assertInvariantsRecursive();
451706b4fc4SDimitry Andric     return TU;
45222989816SDimitry Andric   }
45322989816SDimitry Andric 
454cfca06d7SDimitry Andric   /// Finds a token starting at \p L. The token must exist if \p L is valid.
455cfca06d7SDimitry Andric   const syntax::Token *findToken(SourceLocation L) const;
456cfca06d7SDimitry Andric 
457cfca06d7SDimitry Andric   /// Finds the syntax tokens corresponding to the \p SourceRange.
getRange(SourceRange Range) const458b60736ecSDimitry Andric   ArrayRef<syntax::Token> getRange(SourceRange Range) const {
459cfca06d7SDimitry Andric     assert(Range.isValid());
460cfca06d7SDimitry Andric     return getRange(Range.getBegin(), Range.getEnd());
461cfca06d7SDimitry Andric   }
462cfca06d7SDimitry Andric 
463cfca06d7SDimitry Andric   /// Finds the syntax tokens corresponding to the passed source locations.
46422989816SDimitry Andric   /// \p First is the start position of the first token and \p Last is the start
46522989816SDimitry Andric   /// position of the last token.
getRange(SourceLocation First,SourceLocation Last) const466b60736ecSDimitry Andric   ArrayRef<syntax::Token> getRange(SourceLocation First,
46722989816SDimitry Andric                                    SourceLocation Last) const {
46822989816SDimitry Andric     assert(First.isValid());
46922989816SDimitry Andric     assert(Last.isValid());
47022989816SDimitry Andric     assert(First == Last ||
4714b4fe385SDimitry Andric            TBTM.sourceManager().isBeforeInTranslationUnit(First, Last));
472e3b55780SDimitry Andric     return llvm::ArrayRef(findToken(First), std::next(findToken(Last)));
47322989816SDimitry Andric   }
474cfca06d7SDimitry Andric 
475b60736ecSDimitry Andric   ArrayRef<syntax::Token>
getTemplateRange(const ClassTemplateSpecializationDecl * D) const476cfca06d7SDimitry Andric   getTemplateRange(const ClassTemplateSpecializationDecl *D) const {
477cfca06d7SDimitry Andric     auto Tokens = getRange(D->getSourceRange());
478cfca06d7SDimitry Andric     return maybeAppendSemicolon(Tokens, D);
47922989816SDimitry Andric   }
480cfca06d7SDimitry Andric 
481cfca06d7SDimitry Andric   /// Returns true if \p D is the last declarator in a chain and is thus
482cfca06d7SDimitry Andric   /// reponsible for creating SimpleDeclaration for the whole chain.
isResponsibleForCreatingDeclaration(const Decl * D) const483b60736ecSDimitry Andric   bool isResponsibleForCreatingDeclaration(const Decl *D) const {
484b60736ecSDimitry Andric     assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) &&
485cfca06d7SDimitry Andric            "only DeclaratorDecl and TypedefNameDecl are supported.");
486cfca06d7SDimitry Andric 
487cfca06d7SDimitry Andric     const Decl *Next = D->getNextDeclInContext();
488cfca06d7SDimitry Andric 
489cfca06d7SDimitry Andric     // There's no next sibling, this one is responsible.
490cfca06d7SDimitry Andric     if (Next == nullptr) {
491cfca06d7SDimitry Andric       return true;
492cfca06d7SDimitry Andric     }
493cfca06d7SDimitry Andric 
494cfca06d7SDimitry Andric     // Next sibling is not the same type, this one is responsible.
495b60736ecSDimitry Andric     if (D->getKind() != Next->getKind()) {
496cfca06d7SDimitry Andric       return true;
497cfca06d7SDimitry Andric     }
498cfca06d7SDimitry Andric     // Next sibling doesn't begin at the same loc, it must be a different
499cfca06d7SDimitry Andric     // declaration, so this declarator is responsible.
500b60736ecSDimitry Andric     if (Next->getBeginLoc() != D->getBeginLoc()) {
501cfca06d7SDimitry Andric       return true;
502cfca06d7SDimitry Andric     }
503cfca06d7SDimitry Andric 
504cfca06d7SDimitry Andric     // NextT is a member of the same declaration, and we need the last member to
505cfca06d7SDimitry Andric     // create declaration. This one is not responsible.
506cfca06d7SDimitry Andric     return false;
507cfca06d7SDimitry Andric   }
508cfca06d7SDimitry Andric 
getDeclarationRange(Decl * D)509b60736ecSDimitry Andric   ArrayRef<syntax::Token> getDeclarationRange(Decl *D) {
510b60736ecSDimitry Andric     ArrayRef<syntax::Token> Tokens;
511cfca06d7SDimitry Andric     // We want to drop the template parameters for specializations.
512b60736ecSDimitry Andric     if (const auto *S = dyn_cast<TagDecl>(D))
513cfca06d7SDimitry Andric       Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());
514cfca06d7SDimitry Andric     else
515cfca06d7SDimitry Andric       Tokens = getRange(D->getSourceRange());
516cfca06d7SDimitry Andric     return maybeAppendSemicolon(Tokens, D);
517cfca06d7SDimitry Andric   }
518cfca06d7SDimitry Andric 
getExprRange(const Expr * E) const519b60736ecSDimitry Andric   ArrayRef<syntax::Token> getExprRange(const Expr *E) const {
520cfca06d7SDimitry Andric     return getRange(E->getSourceRange());
521706b4fc4SDimitry Andric   }
522cfca06d7SDimitry Andric 
523706b4fc4SDimitry Andric   /// Find the adjusted range for the statement, consuming the trailing
524706b4fc4SDimitry Andric   /// semicolon when needed.
getStmtRange(const Stmt * S) const525b60736ecSDimitry Andric   ArrayRef<syntax::Token> getStmtRange(const Stmt *S) const {
526cfca06d7SDimitry Andric     auto Tokens = getRange(S->getSourceRange());
527706b4fc4SDimitry Andric     if (isa<CompoundStmt>(S))
528706b4fc4SDimitry Andric       return Tokens;
529706b4fc4SDimitry Andric 
530706b4fc4SDimitry Andric     // Some statements miss a trailing semicolon, e.g. 'return', 'continue' and
531706b4fc4SDimitry Andric     // all statements that end with those. Consume this semicolon here.
532706b4fc4SDimitry Andric     if (Tokens.back().kind() == tok::semi)
533706b4fc4SDimitry Andric       return Tokens;
534706b4fc4SDimitry Andric     return withTrailingSemicolon(Tokens);
53522989816SDimitry Andric   }
53622989816SDimitry Andric 
53722989816SDimitry Andric private:
maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,const Decl * D) const538b60736ecSDimitry Andric   ArrayRef<syntax::Token> maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,
539cfca06d7SDimitry Andric                                                const Decl *D) const {
540b60736ecSDimitry Andric     if (isa<NamespaceDecl>(D))
541cfca06d7SDimitry Andric       return Tokens;
542cfca06d7SDimitry Andric     if (DeclsWithoutSemicolons.count(D))
543cfca06d7SDimitry Andric       return Tokens;
544cfca06d7SDimitry Andric     // FIXME: do not consume trailing semicolon on function definitions.
545cfca06d7SDimitry Andric     // Most declarations own a semicolon in syntax trees, but not in clang AST.
546cfca06d7SDimitry Andric     return withTrailingSemicolon(Tokens);
547cfca06d7SDimitry Andric   }
548cfca06d7SDimitry Andric 
549b60736ecSDimitry Andric   ArrayRef<syntax::Token>
withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const550b60736ecSDimitry Andric   withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const {
551706b4fc4SDimitry Andric     assert(!Tokens.empty());
552706b4fc4SDimitry Andric     assert(Tokens.back().kind() != tok::eof);
553cfca06d7SDimitry Andric     // We never consume 'eof', so looking at the next token is ok.
554706b4fc4SDimitry Andric     if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi)
555e3b55780SDimitry Andric       return llvm::ArrayRef(Tokens.begin(), Tokens.end() + 1);
556706b4fc4SDimitry Andric     return Tokens;
557706b4fc4SDimitry Andric   }
558706b4fc4SDimitry Andric 
setRole(syntax::Node * N,NodeRole R)559cfca06d7SDimitry Andric   void setRole(syntax::Node *N, NodeRole R) {
560b60736ecSDimitry Andric     assert(N->getRole() == NodeRole::Detached);
561cfca06d7SDimitry Andric     N->setRole(R);
562cfca06d7SDimitry Andric   }
56322989816SDimitry Andric 
56422989816SDimitry Andric   /// A collection of trees covering the input tokens.
56522989816SDimitry Andric   /// When created, each tree corresponds to a single token in the file.
56622989816SDimitry Andric   /// Clients call 'foldChildren' to attach one or more subtrees to a parent
56722989816SDimitry Andric   /// node and update the list of trees accordingly.
56822989816SDimitry Andric   ///
56922989816SDimitry Andric   /// Ensures that added nodes properly nest and cover the whole token stream.
57022989816SDimitry Andric   struct Forest {
Forestsyntax::TreeBuilder::Forest5714b4fe385SDimitry Andric     Forest(syntax::Arena &A, const syntax::TokenBuffer &TB) {
5724b4fe385SDimitry Andric       assert(!TB.expandedTokens().empty());
5734b4fe385SDimitry Andric       assert(TB.expandedTokens().back().kind() == tok::eof);
57422989816SDimitry Andric       // Create all leaf nodes.
575519fc96cSDimitry Andric       // Note that we do not have 'eof' in the tree.
5764b4fe385SDimitry Andric       for (const auto &T : TB.expandedTokens().drop_back()) {
5774b4fe385SDimitry Andric         auto *L = new (A.getAllocator())
5784b4fe385SDimitry Andric             syntax::Leaf(reinterpret_cast<TokenManager::Key>(&T));
579706b4fc4SDimitry Andric         L->Original = true;
5804b4fe385SDimitry Andric         L->CanModify = TB.spelledForExpanded(T).has_value();
581cfca06d7SDimitry Andric         Trees.insert(Trees.end(), {&T, L});
58222989816SDimitry Andric       }
583706b4fc4SDimitry Andric     }
584706b4fc4SDimitry Andric 
assignRolesyntax::TreeBuilder::Forest585b60736ecSDimitry Andric     void assignRole(ArrayRef<syntax::Token> Range, syntax::NodeRole Role) {
58622989816SDimitry Andric       assert(!Range.empty());
58722989816SDimitry Andric       auto It = Trees.lower_bound(Range.begin());
58822989816SDimitry Andric       assert(It != Trees.end() && "no node found");
58922989816SDimitry Andric       assert(It->first == Range.begin() && "no child with the specified range");
59022989816SDimitry Andric       assert((std::next(It) == Trees.end() ||
59122989816SDimitry Andric               std::next(It)->first == Range.end()) &&
59222989816SDimitry Andric              "no child with the specified range");
593b60736ecSDimitry Andric       assert(It->second->getRole() == NodeRole::Detached &&
594cfca06d7SDimitry Andric              "re-assigning role for a child");
595cfca06d7SDimitry Andric       It->second->setRole(Role);
59622989816SDimitry Andric     }
59722989816SDimitry Andric 
598b60736ecSDimitry Andric     /// Shrink \p Range to a subrange that only contains tokens of a list.
599b60736ecSDimitry Andric     /// List elements and delimiters should already have correct roles.
shrinkToFitListsyntax::TreeBuilder::Forest600b60736ecSDimitry Andric     ArrayRef<syntax::Token> shrinkToFitList(ArrayRef<syntax::Token> Range) {
601b60736ecSDimitry Andric       auto BeginChildren = Trees.lower_bound(Range.begin());
602b60736ecSDimitry Andric       assert((BeginChildren == Trees.end() ||
603b60736ecSDimitry Andric               BeginChildren->first == Range.begin()) &&
604b60736ecSDimitry Andric              "Range crosses boundaries of existing subtrees");
605b60736ecSDimitry Andric 
606b60736ecSDimitry Andric       auto EndChildren = Trees.lower_bound(Range.end());
607b60736ecSDimitry Andric       assert(
608b60736ecSDimitry Andric           (EndChildren == Trees.end() || EndChildren->first == Range.end()) &&
609b60736ecSDimitry Andric           "Range crosses boundaries of existing subtrees");
610b60736ecSDimitry Andric 
611b60736ecSDimitry Andric       auto BelongsToList = [](decltype(Trees)::value_type KV) {
612b60736ecSDimitry Andric         auto Role = KV.second->getRole();
613b60736ecSDimitry Andric         return Role == syntax::NodeRole::ListElement ||
614b60736ecSDimitry Andric                Role == syntax::NodeRole::ListDelimiter;
615b60736ecSDimitry Andric       };
616b60736ecSDimitry Andric 
617b60736ecSDimitry Andric       auto BeginListChildren =
618b60736ecSDimitry Andric           std::find_if(BeginChildren, EndChildren, BelongsToList);
619b60736ecSDimitry Andric 
620b60736ecSDimitry Andric       auto EndListChildren =
621b60736ecSDimitry Andric           std::find_if_not(BeginListChildren, EndChildren, BelongsToList);
622b60736ecSDimitry Andric 
623b60736ecSDimitry Andric       return ArrayRef<syntax::Token>(BeginListChildren->first,
624b60736ecSDimitry Andric                                      EndListChildren->first);
625b60736ecSDimitry Andric     }
626b60736ecSDimitry Andric 
627706b4fc4SDimitry Andric     /// Add \p Node to the forest and attach child nodes based on \p Tokens.
foldChildrensyntax::TreeBuilder::Forest6284b4fe385SDimitry Andric     void foldChildren(const syntax::TokenBuffer &TB,
6294b4fe385SDimitry Andric                       ArrayRef<syntax::Token> Tokens, syntax::Tree *Node) {
630706b4fc4SDimitry Andric       // Attach children to `Node`.
631b60736ecSDimitry Andric       assert(Node->getFirstChild() == nullptr && "node already has children");
632cfca06d7SDimitry Andric 
633cfca06d7SDimitry Andric       auto *FirstToken = Tokens.begin();
634cfca06d7SDimitry Andric       auto BeginChildren = Trees.lower_bound(FirstToken);
635cfca06d7SDimitry Andric 
636cfca06d7SDimitry Andric       assert((BeginChildren == Trees.end() ||
637cfca06d7SDimitry Andric               BeginChildren->first == FirstToken) &&
638cfca06d7SDimitry Andric              "fold crosses boundaries of existing subtrees");
639cfca06d7SDimitry Andric       auto EndChildren = Trees.lower_bound(Tokens.end());
640cfca06d7SDimitry Andric       assert(
641cfca06d7SDimitry Andric           (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&
642cfca06d7SDimitry Andric           "fold crosses boundaries of existing subtrees");
643cfca06d7SDimitry Andric 
644b60736ecSDimitry Andric       for (auto It = BeginChildren; It != EndChildren; ++It) {
645b60736ecSDimitry Andric         auto *C = It->second;
646b60736ecSDimitry Andric         if (C->getRole() == NodeRole::Detached)
647cfca06d7SDimitry Andric           C->setRole(NodeRole::Unknown);
648b60736ecSDimitry Andric         Node->appendChildLowLevel(C);
649706b4fc4SDimitry Andric       }
65022989816SDimitry Andric 
651cfca06d7SDimitry Andric       // Mark that this node came from the AST and is backed by the source code.
652cfca06d7SDimitry Andric       Node->Original = true;
653b60736ecSDimitry Andric       Node->CanModify =
6544b4fe385SDimitry Andric           TB.spelledForExpanded(Tokens).has_value();
65522989816SDimitry Andric 
656cfca06d7SDimitry Andric       Trees.erase(BeginChildren, EndChildren);
657cfca06d7SDimitry Andric       Trees.insert({FirstToken, Node});
65822989816SDimitry Andric     }
65922989816SDimitry Andric 
66022989816SDimitry Andric     // EXPECTS: all tokens were consumed and are owned by a single root node.
finalizesyntax::TreeBuilder::Forest66122989816SDimitry Andric     syntax::Node *finalize() && {
66222989816SDimitry Andric       assert(Trees.size() == 1);
663cfca06d7SDimitry Andric       auto *Root = Trees.begin()->second;
66422989816SDimitry Andric       Trees = {};
66522989816SDimitry Andric       return Root;
66622989816SDimitry Andric     }
66722989816SDimitry Andric 
strsyntax::TreeBuilder::Forest6684b4fe385SDimitry Andric     std::string str(const syntax::TokenBufferTokenManager &STM) const {
66922989816SDimitry Andric       std::string R;
67022989816SDimitry Andric       for (auto It = Trees.begin(); It != Trees.end(); ++It) {
67122989816SDimitry Andric         unsigned CoveredTokens =
67222989816SDimitry Andric             It != Trees.end()
67322989816SDimitry Andric                 ? (std::next(It)->first - It->first)
6744b4fe385SDimitry Andric                 : STM.tokenBuffer().expandedTokens().end() - It->first;
67522989816SDimitry Andric 
676b60736ecSDimitry Andric         R += std::string(
677b60736ecSDimitry Andric             formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(),
6784b4fe385SDimitry Andric                     It->first->text(STM.sourceManager()), CoveredTokens));
6794b4fe385SDimitry Andric         R += It->second->dump(STM);
68022989816SDimitry Andric       }
68122989816SDimitry Andric       return R;
68222989816SDimitry Andric     }
68322989816SDimitry Andric 
68422989816SDimitry Andric   private:
68522989816SDimitry Andric     /// Maps from the start token to a subtree starting at that token.
686706b4fc4SDimitry Andric     /// Keys in the map are pointers into the array of expanded tokens, so
687706b4fc4SDimitry Andric     /// pointer order corresponds to the order of preprocessor tokens.
688cfca06d7SDimitry Andric     std::map<const syntax::Token *, syntax::Node *> Trees;
68922989816SDimitry Andric   };
69022989816SDimitry Andric 
69122989816SDimitry Andric   /// For debugging purposes.
str()6924b4fe385SDimitry Andric   std::string str() { return Pending.str(TBTM); }
69322989816SDimitry Andric 
69422989816SDimitry Andric   syntax::Arena &Arena;
6954b4fe385SDimitry Andric   TokenBufferTokenManager& TBTM;
696706b4fc4SDimitry Andric   /// To quickly find tokens by their start location.
697b60736ecSDimitry Andric   llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken;
69822989816SDimitry Andric   Forest Pending;
699706b4fc4SDimitry Andric   llvm::DenseSet<Decl *> DeclsWithoutSemicolons;
700cfca06d7SDimitry Andric   ASTToSyntaxMapping Mapping;
70122989816SDimitry Andric };
70222989816SDimitry Andric 
70322989816SDimitry Andric namespace {
70422989816SDimitry Andric class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
70522989816SDimitry Andric public:
BuildTreeVisitor(ASTContext & Context,syntax::TreeBuilder & Builder)706cfca06d7SDimitry Andric   explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
707cfca06d7SDimitry Andric       : Builder(Builder), Context(Context) {}
70822989816SDimitry Andric 
shouldTraversePostOrder() const70922989816SDimitry Andric   bool shouldTraversePostOrder() const { return true; }
71022989816SDimitry Andric 
WalkUpFromDeclaratorDecl(DeclaratorDecl * DD)711cfca06d7SDimitry Andric   bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {
712cfca06d7SDimitry Andric     return processDeclaratorAndDeclaration(DD);
713706b4fc4SDimitry Andric   }
714cfca06d7SDimitry Andric 
WalkUpFromTypedefNameDecl(TypedefNameDecl * TD)715cfca06d7SDimitry Andric   bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) {
716cfca06d7SDimitry Andric     return processDeclaratorAndDeclaration(TD);
71722989816SDimitry Andric   }
71822989816SDimitry Andric 
VisitDecl(Decl * D)71922989816SDimitry Andric   bool VisitDecl(Decl *D) {
72022989816SDimitry Andric     assert(!D->isImplicit());
721cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(D),
722cfca06d7SDimitry Andric                      new (allocator()) syntax::UnknownDeclaration(), D);
723cfca06d7SDimitry Andric     return true;
724cfca06d7SDimitry Andric   }
725cfca06d7SDimitry Andric 
726cfca06d7SDimitry Andric   // RAV does not call WalkUpFrom* on explicit instantiations, so we have to
727cfca06d7SDimitry Andric   // override Traverse.
728cfca06d7SDimitry Andric   // FIXME: make RAV call WalkUpFrom* instead.
729cfca06d7SDimitry Andric   bool
TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * C)730cfca06d7SDimitry Andric   TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {
731cfca06d7SDimitry Andric     if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C))
732cfca06d7SDimitry Andric       return false;
733cfca06d7SDimitry Andric     if (C->isExplicitSpecialization())
734cfca06d7SDimitry Andric       return true; // we are only interested in explicit instantiations.
735cfca06d7SDimitry Andric     auto *Declaration =
736cfca06d7SDimitry Andric         cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C));
737cfca06d7SDimitry Andric     foldExplicitTemplateInstantiation(
738ac9a064cSDimitry Andric         Builder.getTemplateRange(C),
739ac9a064cSDimitry Andric         Builder.findToken(C->getExternKeywordLoc()),
740cfca06d7SDimitry Andric         Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C);
741cfca06d7SDimitry Andric     return true;
742cfca06d7SDimitry Andric   }
743cfca06d7SDimitry Andric 
WalkUpFromTemplateDecl(TemplateDecl * S)744cfca06d7SDimitry Andric   bool WalkUpFromTemplateDecl(TemplateDecl *S) {
745cfca06d7SDimitry Andric     foldTemplateDeclaration(
746cfca06d7SDimitry Andric         Builder.getDeclarationRange(S),
747cfca06d7SDimitry Andric         Builder.findToken(S->getTemplateParameters()->getTemplateLoc()),
748cfca06d7SDimitry Andric         Builder.getDeclarationRange(S->getTemplatedDecl()), S);
749706b4fc4SDimitry Andric     return true;
750706b4fc4SDimitry Andric   }
751706b4fc4SDimitry Andric 
WalkUpFromTagDecl(TagDecl * C)752706b4fc4SDimitry Andric   bool WalkUpFromTagDecl(TagDecl *C) {
753706b4fc4SDimitry Andric     // FIXME: build the ClassSpecifier node.
754cfca06d7SDimitry Andric     if (!C->isFreeStanding()) {
755cfca06d7SDimitry Andric       assert(C->getNumTemplateParameterLists() == 0);
756706b4fc4SDimitry Andric       return true;
757706b4fc4SDimitry Andric     }
758cfca06d7SDimitry Andric     handleFreeStandingTagDecl(C);
75922989816SDimitry Andric     return true;
76022989816SDimitry Andric   }
76122989816SDimitry Andric 
handleFreeStandingTagDecl(TagDecl * C)762cfca06d7SDimitry Andric   syntax::Declaration *handleFreeStandingTagDecl(TagDecl *C) {
763cfca06d7SDimitry Andric     assert(C->isFreeStanding());
764cfca06d7SDimitry Andric     // Class is a declaration specifier and needs a spanning declaration node.
765cfca06d7SDimitry Andric     auto DeclarationRange = Builder.getDeclarationRange(C);
766cfca06d7SDimitry Andric     syntax::Declaration *Result = new (allocator()) syntax::SimpleDeclaration;
767cfca06d7SDimitry Andric     Builder.foldNode(DeclarationRange, Result, nullptr);
768cfca06d7SDimitry Andric 
769cfca06d7SDimitry Andric     // Build TemplateDeclaration nodes if we had template parameters.
770cfca06d7SDimitry Andric     auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) {
771cfca06d7SDimitry Andric       const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
772e3b55780SDimitry Andric       auto R = llvm::ArrayRef(TemplateKW, DeclarationRange.end());
773cfca06d7SDimitry Andric       Result =
774cfca06d7SDimitry Andric           foldTemplateDeclaration(R, TemplateKW, DeclarationRange, nullptr);
775cfca06d7SDimitry Andric       DeclarationRange = R;
776cfca06d7SDimitry Andric     };
777b60736ecSDimitry Andric     if (auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(C))
778cfca06d7SDimitry Andric       ConsumeTemplateParameters(*S->getTemplateParameters());
779cfca06d7SDimitry Andric     for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I)
780cfca06d7SDimitry Andric       ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1));
781cfca06d7SDimitry Andric     return Result;
782cfca06d7SDimitry Andric   }
783cfca06d7SDimitry Andric 
WalkUpFromTranslationUnitDecl(TranslationUnitDecl * TU)78422989816SDimitry Andric   bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
785cfca06d7SDimitry Andric     // We do not want to call VisitDecl(), the declaration for translation
78622989816SDimitry Andric     // unit is built by finalize().
78722989816SDimitry Andric     return true;
78822989816SDimitry Andric   }
78922989816SDimitry Andric 
WalkUpFromCompoundStmt(CompoundStmt * S)79022989816SDimitry Andric   bool WalkUpFromCompoundStmt(CompoundStmt *S) {
79122989816SDimitry Andric     using NodeRole = syntax::NodeRole;
79222989816SDimitry Andric 
793706b4fc4SDimitry Andric     Builder.markChildToken(S->getLBracLoc(), NodeRole::OpenParen);
794706b4fc4SDimitry Andric     for (auto *Child : S->body())
795b60736ecSDimitry Andric       Builder.markStmtChild(Child, NodeRole::Statement);
796706b4fc4SDimitry Andric     Builder.markChildToken(S->getRBracLoc(), NodeRole::CloseParen);
79722989816SDimitry Andric 
798706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
799cfca06d7SDimitry Andric                      new (allocator()) syntax::CompoundStatement, S);
80022989816SDimitry Andric     return true;
80122989816SDimitry Andric   }
80222989816SDimitry Andric 
803706b4fc4SDimitry Andric   // Some statements are not yet handled by syntax trees.
WalkUpFromStmt(Stmt * S)804706b4fc4SDimitry Andric   bool WalkUpFromStmt(Stmt *S) {
805706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
806cfca06d7SDimitry Andric                      new (allocator()) syntax::UnknownStatement, S);
807706b4fc4SDimitry Andric     return true;
808706b4fc4SDimitry Andric   }
809706b4fc4SDimitry Andric 
TraverseIfStmt(IfStmt * S)810344a3780SDimitry Andric   bool TraverseIfStmt(IfStmt *S) {
811344a3780SDimitry Andric     bool Result = [&, this]() {
812344a3780SDimitry Andric       if (S->getInit() && !TraverseStmt(S->getInit())) {
813344a3780SDimitry Andric         return false;
814344a3780SDimitry Andric       }
815344a3780SDimitry Andric       // In cases where the condition is an initialized declaration in a
816344a3780SDimitry Andric       // statement, we want to preserve the declaration and ignore the
817344a3780SDimitry Andric       // implicit condition expression in the syntax tree.
818344a3780SDimitry Andric       if (S->hasVarStorage()) {
819344a3780SDimitry Andric         if (!TraverseStmt(S->getConditionVariableDeclStmt()))
820344a3780SDimitry Andric           return false;
821344a3780SDimitry Andric       } else if (S->getCond() && !TraverseStmt(S->getCond()))
822344a3780SDimitry Andric         return false;
823344a3780SDimitry Andric 
824344a3780SDimitry Andric       if (S->getThen() && !TraverseStmt(S->getThen()))
825344a3780SDimitry Andric         return false;
826344a3780SDimitry Andric       if (S->getElse() && !TraverseStmt(S->getElse()))
827344a3780SDimitry Andric         return false;
828344a3780SDimitry Andric       return true;
829344a3780SDimitry Andric     }();
830344a3780SDimitry Andric     WalkUpFromIfStmt(S);
831344a3780SDimitry Andric     return Result;
832344a3780SDimitry Andric   }
833344a3780SDimitry Andric 
TraverseCXXForRangeStmt(CXXForRangeStmt * S)834706b4fc4SDimitry Andric   bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
835706b4fc4SDimitry Andric     // We override to traverse range initializer as VarDecl.
836706b4fc4SDimitry Andric     // RAV traverses it as a statement, we produce invalid node kinds in that
837706b4fc4SDimitry Andric     // case.
838706b4fc4SDimitry Andric     // FIXME: should do this in RAV instead?
839cfca06d7SDimitry Andric     bool Result = [&, this]() {
840706b4fc4SDimitry Andric       if (S->getInit() && !TraverseStmt(S->getInit()))
841706b4fc4SDimitry Andric         return false;
842706b4fc4SDimitry Andric       if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable()))
843706b4fc4SDimitry Andric         return false;
844706b4fc4SDimitry Andric       if (S->getRangeInit() && !TraverseStmt(S->getRangeInit()))
845706b4fc4SDimitry Andric         return false;
846706b4fc4SDimitry Andric       if (S->getBody() && !TraverseStmt(S->getBody()))
847706b4fc4SDimitry Andric         return false;
848706b4fc4SDimitry Andric       return true;
849cfca06d7SDimitry Andric     }();
850cfca06d7SDimitry Andric     WalkUpFromCXXForRangeStmt(S);
851cfca06d7SDimitry Andric     return Result;
852706b4fc4SDimitry Andric   }
853706b4fc4SDimitry Andric 
TraverseStmt(Stmt * S)854706b4fc4SDimitry Andric   bool TraverseStmt(Stmt *S) {
855b60736ecSDimitry Andric     if (auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
856706b4fc4SDimitry Andric       // We want to consume the semicolon, make sure SimpleDeclaration does not.
857706b4fc4SDimitry Andric       for (auto *D : DS->decls())
858cfca06d7SDimitry Andric         Builder.noticeDeclWithoutSemicolon(D);
859b60736ecSDimitry Andric     } else if (auto *E = dyn_cast_or_null<Expr>(S)) {
860b60736ecSDimitry Andric       return RecursiveASTVisitor::TraverseStmt(IgnoreImplicit(E));
861706b4fc4SDimitry Andric     }
862706b4fc4SDimitry Andric     return RecursiveASTVisitor::TraverseStmt(S);
863706b4fc4SDimitry Andric   }
864706b4fc4SDimitry Andric 
TraverseOpaqueValueExpr(OpaqueValueExpr * VE)865344a3780SDimitry Andric   bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
866344a3780SDimitry Andric     // OpaqueValue doesn't correspond to concrete syntax, ignore it.
867344a3780SDimitry Andric     return true;
868344a3780SDimitry Andric   }
869344a3780SDimitry Andric 
870706b4fc4SDimitry Andric   // Some expressions are not yet handled by syntax trees.
WalkUpFromExpr(Expr * E)871706b4fc4SDimitry Andric   bool WalkUpFromExpr(Expr *E) {
872706b4fc4SDimitry Andric     assert(!isImplicitExpr(E) && "should be handled by TraverseStmt");
873706b4fc4SDimitry Andric     Builder.foldNode(Builder.getExprRange(E),
874cfca06d7SDimitry Andric                      new (allocator()) syntax::UnknownExpression, E);
875706b4fc4SDimitry Andric     return true;
876706b4fc4SDimitry Andric   }
877706b4fc4SDimitry Andric 
TraverseUserDefinedLiteral(UserDefinedLiteral * S)878cfca06d7SDimitry Andric   bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
879cfca06d7SDimitry Andric     // The semantic AST node `UserDefinedLiteral` (UDL) may have one child node
880cfca06d7SDimitry Andric     // referencing the location of the UDL suffix (`_w` in `1.2_w`). The
881cfca06d7SDimitry Andric     // UDL suffix location does not point to the beginning of a token, so we
882cfca06d7SDimitry Andric     // can't represent the UDL suffix as a separate syntax tree node.
883cfca06d7SDimitry Andric 
884cfca06d7SDimitry Andric     return WalkUpFromUserDefinedLiteral(S);
885cfca06d7SDimitry Andric   }
886cfca06d7SDimitry Andric 
887cfca06d7SDimitry Andric   syntax::UserDefinedLiteralExpression *
buildUserDefinedLiteral(UserDefinedLiteral * S)888cfca06d7SDimitry Andric   buildUserDefinedLiteral(UserDefinedLiteral *S) {
889cfca06d7SDimitry Andric     switch (S->getLiteralOperatorKind()) {
890b60736ecSDimitry Andric     case UserDefinedLiteral::LOK_Integer:
891cfca06d7SDimitry Andric       return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
892b60736ecSDimitry Andric     case UserDefinedLiteral::LOK_Floating:
893cfca06d7SDimitry Andric       return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
894b60736ecSDimitry Andric     case UserDefinedLiteral::LOK_Character:
895cfca06d7SDimitry Andric       return new (allocator()) syntax::CharUserDefinedLiteralExpression;
896b60736ecSDimitry Andric     case UserDefinedLiteral::LOK_String:
897cfca06d7SDimitry Andric       return new (allocator()) syntax::StringUserDefinedLiteralExpression;
898b60736ecSDimitry Andric     case UserDefinedLiteral::LOK_Raw:
899b60736ecSDimitry Andric     case UserDefinedLiteral::LOK_Template:
900cfca06d7SDimitry Andric       // For raw literal operator and numeric literal operator template we
901cfca06d7SDimitry Andric       // cannot get the type of the operand in the semantic AST. We get this
902cfca06d7SDimitry Andric       // information from the token. As integer and floating point have the same
903cfca06d7SDimitry Andric       // token kind, we run `NumericLiteralParser` again to distinguish them.
904cfca06d7SDimitry Andric       auto TokLoc = S->getBeginLoc();
905cfca06d7SDimitry Andric       auto TokSpelling =
906cfca06d7SDimitry Andric           Builder.findToken(TokLoc)->text(Context.getSourceManager());
907cfca06d7SDimitry Andric       auto Literal =
908cfca06d7SDimitry Andric           NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(),
909cfca06d7SDimitry Andric                                Context.getLangOpts(), Context.getTargetInfo(),
910cfca06d7SDimitry Andric                                Context.getDiagnostics());
911cfca06d7SDimitry Andric       if (Literal.isIntegerLiteral())
912cfca06d7SDimitry Andric         return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
913cfca06d7SDimitry Andric       else {
914cfca06d7SDimitry Andric         assert(Literal.isFloatingLiteral());
915cfca06d7SDimitry Andric         return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
916cfca06d7SDimitry Andric       }
917cfca06d7SDimitry Andric     }
918cfca06d7SDimitry Andric     llvm_unreachable("Unknown literal operator kind.");
919cfca06d7SDimitry Andric   }
920cfca06d7SDimitry Andric 
WalkUpFromUserDefinedLiteral(UserDefinedLiteral * S)921cfca06d7SDimitry Andric   bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
922cfca06d7SDimitry Andric     Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
923cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
924cfca06d7SDimitry Andric     return true;
925cfca06d7SDimitry Andric   }
926cfca06d7SDimitry Andric 
927b60736ecSDimitry Andric   // FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the
928b60736ecSDimitry Andric   // `DependentTemplateSpecializationType` case.
929b60736ecSDimitry Andric   /// Given a nested-name-specifier return the range for the last name
930b60736ecSDimitry Andric   /// specifier.
931b60736ecSDimitry Andric   ///
932b60736ecSDimitry Andric   /// e.g. `std::T::template X<U>::` => `template X<U>::`
getLocalSourceRange(const NestedNameSpecifierLoc & NNSLoc)933b60736ecSDimitry Andric   SourceRange getLocalSourceRange(const NestedNameSpecifierLoc &NNSLoc) {
934b60736ecSDimitry Andric     auto SR = NNSLoc.getLocalSourceRange();
935cfca06d7SDimitry Andric 
936b60736ecSDimitry Andric     // The method `NestedNameSpecifierLoc::getLocalSourceRange` *should*
937b60736ecSDimitry Andric     // return the desired `SourceRange`, but there is a corner case. For a
938b60736ecSDimitry Andric     // `DependentTemplateSpecializationType` this method returns its
939b60736ecSDimitry Andric     // qualifiers as well, in other words in the example above this method
940b60736ecSDimitry Andric     // returns `T::template X<U>::` instead of only `template X<U>::`
941b60736ecSDimitry Andric     if (auto TL = NNSLoc.getTypeLoc()) {
942b60736ecSDimitry Andric       if (auto DependentTL =
943b60736ecSDimitry Andric               TL.getAs<DependentTemplateSpecializationTypeLoc>()) {
944b60736ecSDimitry Andric         // The 'template' keyword is always present in dependent template
945b60736ecSDimitry Andric         // specializations. Except in the case of incorrect code
946b60736ecSDimitry Andric         // TODO: Treat the case of incorrect code.
947b60736ecSDimitry Andric         SR.setBegin(DependentTL.getTemplateKeywordLoc());
948cfca06d7SDimitry Andric       }
949b60736ecSDimitry Andric     }
950b60736ecSDimitry Andric 
951b60736ecSDimitry Andric     return SR;
952b60736ecSDimitry Andric   }
953b60736ecSDimitry Andric 
getNameSpecifierKind(const NestedNameSpecifier & NNS)954b60736ecSDimitry Andric   syntax::NodeKind getNameSpecifierKind(const NestedNameSpecifier &NNS) {
955b60736ecSDimitry Andric     switch (NNS.getKind()) {
956b60736ecSDimitry Andric     case NestedNameSpecifier::Global:
957b60736ecSDimitry Andric       return syntax::NodeKind::GlobalNameSpecifier;
958b60736ecSDimitry Andric     case NestedNameSpecifier::Namespace:
959b60736ecSDimitry Andric     case NestedNameSpecifier::NamespaceAlias:
960b60736ecSDimitry Andric     case NestedNameSpecifier::Identifier:
961b60736ecSDimitry Andric       return syntax::NodeKind::IdentifierNameSpecifier;
962b60736ecSDimitry Andric     case NestedNameSpecifier::TypeSpecWithTemplate:
963b60736ecSDimitry Andric       return syntax::NodeKind::SimpleTemplateNameSpecifier;
964b60736ecSDimitry Andric     case NestedNameSpecifier::TypeSpec: {
965b60736ecSDimitry Andric       const auto *NNSType = NNS.getAsType();
966b60736ecSDimitry Andric       assert(NNSType);
967b60736ecSDimitry Andric       if (isa<DecltypeType>(NNSType))
968b60736ecSDimitry Andric         return syntax::NodeKind::DecltypeNameSpecifier;
969b60736ecSDimitry Andric       if (isa<TemplateSpecializationType, DependentTemplateSpecializationType>(
970b60736ecSDimitry Andric               NNSType))
971b60736ecSDimitry Andric         return syntax::NodeKind::SimpleTemplateNameSpecifier;
972b60736ecSDimitry Andric       return syntax::NodeKind::IdentifierNameSpecifier;
973b60736ecSDimitry Andric     }
974b60736ecSDimitry Andric     default:
975b60736ecSDimitry Andric       // FIXME: Support Microsoft's __super
976b60736ecSDimitry Andric       llvm::report_fatal_error("We don't yet support the __super specifier",
977b60736ecSDimitry Andric                                true);
978b60736ecSDimitry Andric     }
979b60736ecSDimitry Andric   }
980b60736ecSDimitry Andric 
981b60736ecSDimitry Andric   syntax::NameSpecifier *
buildNameSpecifier(const NestedNameSpecifierLoc & NNSLoc)982b60736ecSDimitry Andric   buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {
983b60736ecSDimitry Andric     assert(NNSLoc.hasQualifier());
984b60736ecSDimitry Andric     auto NameSpecifierTokens =
985b60736ecSDimitry Andric         Builder.getRange(getLocalSourceRange(NNSLoc)).drop_back();
986b60736ecSDimitry Andric     switch (getNameSpecifierKind(*NNSLoc.getNestedNameSpecifier())) {
987b60736ecSDimitry Andric     case syntax::NodeKind::GlobalNameSpecifier:
988b60736ecSDimitry Andric       return new (allocator()) syntax::GlobalNameSpecifier;
989b60736ecSDimitry Andric     case syntax::NodeKind::IdentifierNameSpecifier: {
990b60736ecSDimitry Andric       assert(NameSpecifierTokens.size() == 1);
991b60736ecSDimitry Andric       Builder.markChildToken(NameSpecifierTokens.begin(),
992b60736ecSDimitry Andric                              syntax::NodeRole::Unknown);
993b60736ecSDimitry Andric       auto *NS = new (allocator()) syntax::IdentifierNameSpecifier;
994b60736ecSDimitry Andric       Builder.foldNode(NameSpecifierTokens, NS, nullptr);
995b60736ecSDimitry Andric       return NS;
996b60736ecSDimitry Andric     }
997b60736ecSDimitry Andric     case syntax::NodeKind::SimpleTemplateNameSpecifier: {
998b60736ecSDimitry Andric       // TODO: Build `SimpleTemplateNameSpecifier` children and implement
999b60736ecSDimitry Andric       // accessors to them.
1000b60736ecSDimitry Andric       // Be aware, we cannot do that simply by calling `TraverseTypeLoc`,
1001b60736ecSDimitry Andric       // some `TypeLoc`s have inside them the previous name specifier and
1002b60736ecSDimitry Andric       // we want to treat them independently.
1003b60736ecSDimitry Andric       auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier;
1004b60736ecSDimitry Andric       Builder.foldNode(NameSpecifierTokens, NS, nullptr);
1005b60736ecSDimitry Andric       return NS;
1006b60736ecSDimitry Andric     }
1007b60736ecSDimitry Andric     case syntax::NodeKind::DecltypeNameSpecifier: {
1008b60736ecSDimitry Andric       const auto TL = NNSLoc.getTypeLoc().castAs<DecltypeTypeLoc>();
1009b60736ecSDimitry Andric       if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL))
1010b60736ecSDimitry Andric         return nullptr;
1011b60736ecSDimitry Andric       auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;
1012b60736ecSDimitry Andric       // TODO: Implement accessor to `DecltypeNameSpecifier` inner
1013b60736ecSDimitry Andric       // `DecltypeTypeLoc`.
1014b60736ecSDimitry Andric       // For that add mapping from `TypeLoc` to `syntax::Node*` then:
1015b60736ecSDimitry Andric       // Builder.markChild(TypeLoc, syntax::NodeRole);
1016b60736ecSDimitry Andric       Builder.foldNode(NameSpecifierTokens, NS, nullptr);
1017b60736ecSDimitry Andric       return NS;
1018b60736ecSDimitry Andric     }
1019b60736ecSDimitry Andric     default:
1020b60736ecSDimitry Andric       llvm_unreachable("getChildKind() does not return this value");
1021b60736ecSDimitry Andric     }
1022b60736ecSDimitry Andric   }
1023b60736ecSDimitry Andric 
1024b60736ecSDimitry Andric   // To build syntax tree nodes for NestedNameSpecifierLoc we override
1025b60736ecSDimitry Andric   // Traverse instead of WalkUpFrom because we want to traverse the children
1026b60736ecSDimitry Andric   // ourselves and build a list instead of a nested tree of name specifier
1027b60736ecSDimitry Andric   // prefixes.
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)1028b60736ecSDimitry Andric   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1029b60736ecSDimitry Andric     if (!QualifierLoc)
1030b60736ecSDimitry Andric       return true;
1031b60736ecSDimitry Andric     for (auto It = QualifierLoc; It; It = It.getPrefix()) {
1032b60736ecSDimitry Andric       auto *NS = buildNameSpecifier(It);
1033b60736ecSDimitry Andric       if (!NS)
1034b60736ecSDimitry Andric         return false;
1035b60736ecSDimitry Andric       Builder.markChild(NS, syntax::NodeRole::ListElement);
1036b60736ecSDimitry Andric       Builder.markChildToken(It.getEndLoc(), syntax::NodeRole::ListDelimiter);
1037b60736ecSDimitry Andric     }
1038b60736ecSDimitry Andric     Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),
1039b60736ecSDimitry Andric                      new (allocator()) syntax::NestedNameSpecifier,
1040b60736ecSDimitry Andric                      QualifierLoc);
1041b60736ecSDimitry Andric     return true;
1042b60736ecSDimitry Andric   }
1043b60736ecSDimitry Andric 
buildIdExpression(NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKeywordLoc,SourceRange UnqualifiedIdLoc,ASTPtr From)1044b60736ecSDimitry Andric   syntax::IdExpression *buildIdExpression(NestedNameSpecifierLoc QualifierLoc,
1045b60736ecSDimitry Andric                                           SourceLocation TemplateKeywordLoc,
1046b60736ecSDimitry Andric                                           SourceRange UnqualifiedIdLoc,
1047b60736ecSDimitry Andric                                           ASTPtr From) {
1048b60736ecSDimitry Andric     if (QualifierLoc) {
1049b60736ecSDimitry Andric       Builder.markChild(QualifierLoc, syntax::NodeRole::Qualifier);
1050b60736ecSDimitry Andric       if (TemplateKeywordLoc.isValid())
1051b60736ecSDimitry Andric         Builder.markChildToken(TemplateKeywordLoc,
1052b60736ecSDimitry Andric                                syntax::NodeRole::TemplateKeyword);
1053b60736ecSDimitry Andric     }
1054b60736ecSDimitry Andric 
1055b60736ecSDimitry Andric     auto *TheUnqualifiedId = new (allocator()) syntax::UnqualifiedId;
1056b60736ecSDimitry Andric     Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1057b60736ecSDimitry Andric                      nullptr);
1058b60736ecSDimitry Andric     Builder.markChild(TheUnqualifiedId, syntax::NodeRole::UnqualifiedId);
1059b60736ecSDimitry Andric 
1060b60736ecSDimitry Andric     auto IdExpressionBeginLoc =
1061b60736ecSDimitry Andric         QualifierLoc ? QualifierLoc.getBeginLoc() : UnqualifiedIdLoc.getBegin();
1062b60736ecSDimitry Andric 
1063b60736ecSDimitry Andric     auto *TheIdExpression = new (allocator()) syntax::IdExpression;
1064b60736ecSDimitry Andric     Builder.foldNode(
1065b60736ecSDimitry Andric         Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.getEnd()),
1066b60736ecSDimitry Andric         TheIdExpression, From);
1067b60736ecSDimitry Andric 
1068b60736ecSDimitry Andric     return TheIdExpression;
1069b60736ecSDimitry Andric   }
1070b60736ecSDimitry Andric 
WalkUpFromMemberExpr(MemberExpr * S)1071b60736ecSDimitry Andric   bool WalkUpFromMemberExpr(MemberExpr *S) {
1072b60736ecSDimitry Andric     // For `MemberExpr` with implicit `this->` we generate a simple
1073b60736ecSDimitry Andric     // `id-expression` syntax node, beacuse an implicit `member-expression` is
1074b60736ecSDimitry Andric     // syntactically undistinguishable from an `id-expression`
1075b60736ecSDimitry Andric     if (S->isImplicitAccess()) {
1076b60736ecSDimitry Andric       buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1077b60736ecSDimitry Andric                         SourceRange(S->getMemberLoc(), S->getEndLoc()), S);
1078b60736ecSDimitry Andric       return true;
1079b60736ecSDimitry Andric     }
1080b60736ecSDimitry Andric 
1081b60736ecSDimitry Andric     auto *TheIdExpression = buildIdExpression(
1082b60736ecSDimitry Andric         S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1083b60736ecSDimitry Andric         SourceRange(S->getMemberLoc(), S->getEndLoc()), nullptr);
1084b60736ecSDimitry Andric 
1085b60736ecSDimitry Andric     Builder.markChild(TheIdExpression, syntax::NodeRole::Member);
1086b60736ecSDimitry Andric 
1087b60736ecSDimitry Andric     Builder.markExprChild(S->getBase(), syntax::NodeRole::Object);
1088b60736ecSDimitry Andric     Builder.markChildToken(S->getOperatorLoc(), syntax::NodeRole::AccessToken);
1089cfca06d7SDimitry Andric 
1090cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1091b60736ecSDimitry Andric                      new (allocator()) syntax::MemberExpression, S);
1092b60736ecSDimitry Andric     return true;
1093b60736ecSDimitry Andric   }
1094b60736ecSDimitry Andric 
WalkUpFromDeclRefExpr(DeclRefExpr * S)1095b60736ecSDimitry Andric   bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
1096b60736ecSDimitry Andric     buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1097b60736ecSDimitry Andric                       SourceRange(S->getLocation(), S->getEndLoc()), S);
1098b60736ecSDimitry Andric 
1099b60736ecSDimitry Andric     return true;
1100b60736ecSDimitry Andric   }
1101b60736ecSDimitry Andric 
1102b60736ecSDimitry Andric   // Same logic as DeclRefExpr.
WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr * S)1103b60736ecSDimitry Andric   bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
1104b60736ecSDimitry Andric     buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1105b60736ecSDimitry Andric                       SourceRange(S->getLocation(), S->getEndLoc()), S);
1106b60736ecSDimitry Andric 
1107b60736ecSDimitry Andric     return true;
1108b60736ecSDimitry Andric   }
1109b60736ecSDimitry Andric 
WalkUpFromCXXThisExpr(CXXThisExpr * S)1110b60736ecSDimitry Andric   bool WalkUpFromCXXThisExpr(CXXThisExpr *S) {
1111b60736ecSDimitry Andric     if (!S->isImplicit()) {
1112b60736ecSDimitry Andric       Builder.markChildToken(S->getLocation(),
1113b60736ecSDimitry Andric                              syntax::NodeRole::IntroducerKeyword);
1114b60736ecSDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1115b60736ecSDimitry Andric                        new (allocator()) syntax::ThisExpression, S);
1116b60736ecSDimitry Andric     }
1117cfca06d7SDimitry Andric     return true;
1118cfca06d7SDimitry Andric   }
1119cfca06d7SDimitry Andric 
WalkUpFromParenExpr(ParenExpr * S)1120cfca06d7SDimitry Andric   bool WalkUpFromParenExpr(ParenExpr *S) {
1121cfca06d7SDimitry Andric     Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
1122b60736ecSDimitry Andric     Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::SubExpression);
1123cfca06d7SDimitry Andric     Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen);
1124cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1125cfca06d7SDimitry Andric                      new (allocator()) syntax::ParenExpression, S);
1126cfca06d7SDimitry Andric     return true;
1127cfca06d7SDimitry Andric   }
1128cfca06d7SDimitry Andric 
WalkUpFromIntegerLiteral(IntegerLiteral * S)1129cfca06d7SDimitry Andric   bool WalkUpFromIntegerLiteral(IntegerLiteral *S) {
1130cfca06d7SDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1131cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1132cfca06d7SDimitry Andric                      new (allocator()) syntax::IntegerLiteralExpression, S);
1133cfca06d7SDimitry Andric     return true;
1134cfca06d7SDimitry Andric   }
1135cfca06d7SDimitry Andric 
WalkUpFromCharacterLiteral(CharacterLiteral * S)1136cfca06d7SDimitry Andric   bool WalkUpFromCharacterLiteral(CharacterLiteral *S) {
1137cfca06d7SDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1138cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1139cfca06d7SDimitry Andric                      new (allocator()) syntax::CharacterLiteralExpression, S);
1140cfca06d7SDimitry Andric     return true;
1141cfca06d7SDimitry Andric   }
1142cfca06d7SDimitry Andric 
WalkUpFromFloatingLiteral(FloatingLiteral * S)1143cfca06d7SDimitry Andric   bool WalkUpFromFloatingLiteral(FloatingLiteral *S) {
1144cfca06d7SDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1145cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1146cfca06d7SDimitry Andric                      new (allocator()) syntax::FloatingLiteralExpression, S);
1147cfca06d7SDimitry Andric     return true;
1148cfca06d7SDimitry Andric   }
1149cfca06d7SDimitry Andric 
WalkUpFromStringLiteral(StringLiteral * S)1150cfca06d7SDimitry Andric   bool WalkUpFromStringLiteral(StringLiteral *S) {
1151cfca06d7SDimitry Andric     Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
1152cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1153cfca06d7SDimitry Andric                      new (allocator()) syntax::StringLiteralExpression, S);
1154cfca06d7SDimitry Andric     return true;
1155cfca06d7SDimitry Andric   }
1156cfca06d7SDimitry Andric 
WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr * S)1157cfca06d7SDimitry Andric   bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
1158cfca06d7SDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1159cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1160cfca06d7SDimitry Andric                      new (allocator()) syntax::BoolLiteralExpression, S);
1161cfca06d7SDimitry Andric     return true;
1162cfca06d7SDimitry Andric   }
1163cfca06d7SDimitry Andric 
WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr * S)1164cfca06d7SDimitry Andric   bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
1165cfca06d7SDimitry Andric     Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1166cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1167cfca06d7SDimitry Andric                      new (allocator()) syntax::CxxNullPtrExpression, S);
1168cfca06d7SDimitry Andric     return true;
1169cfca06d7SDimitry Andric   }
1170cfca06d7SDimitry Andric 
WalkUpFromUnaryOperator(UnaryOperator * S)1171cfca06d7SDimitry Andric   bool WalkUpFromUnaryOperator(UnaryOperator *S) {
1172cfca06d7SDimitry Andric     Builder.markChildToken(S->getOperatorLoc(),
1173b60736ecSDimitry Andric                            syntax::NodeRole::OperatorToken);
1174b60736ecSDimitry Andric     Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::Operand);
1175cfca06d7SDimitry Andric 
1176cfca06d7SDimitry Andric     if (S->isPostfix())
1177cfca06d7SDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1178cfca06d7SDimitry Andric                        new (allocator()) syntax::PostfixUnaryOperatorExpression,
1179cfca06d7SDimitry Andric                        S);
1180cfca06d7SDimitry Andric     else
1181cfca06d7SDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1182cfca06d7SDimitry Andric                        new (allocator()) syntax::PrefixUnaryOperatorExpression,
1183cfca06d7SDimitry Andric                        S);
1184cfca06d7SDimitry Andric 
1185cfca06d7SDimitry Andric     return true;
1186cfca06d7SDimitry Andric   }
1187cfca06d7SDimitry Andric 
WalkUpFromBinaryOperator(BinaryOperator * S)1188cfca06d7SDimitry Andric   bool WalkUpFromBinaryOperator(BinaryOperator *S) {
1189b60736ecSDimitry Andric     Builder.markExprChild(S->getLHS(), syntax::NodeRole::LeftHandSide);
1190cfca06d7SDimitry Andric     Builder.markChildToken(S->getOperatorLoc(),
1191b60736ecSDimitry Andric                            syntax::NodeRole::OperatorToken);
1192b60736ecSDimitry Andric     Builder.markExprChild(S->getRHS(), syntax::NodeRole::RightHandSide);
1193cfca06d7SDimitry Andric     Builder.foldNode(Builder.getExprRange(S),
1194cfca06d7SDimitry Andric                      new (allocator()) syntax::BinaryOperatorExpression, S);
1195cfca06d7SDimitry Andric     return true;
1196cfca06d7SDimitry Andric   }
1197cfca06d7SDimitry Andric 
1198b60736ecSDimitry Andric   /// Builds `CallArguments` syntax node from arguments that appear in source
1199b60736ecSDimitry Andric   /// code, i.e. not default arguments.
1200b60736ecSDimitry Andric   syntax::CallArguments *
buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs)1201b60736ecSDimitry Andric   buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs) {
1202b60736ecSDimitry Andric     auto Args = dropDefaultArgs(ArgsAndDefaultArgs);
1203b60736ecSDimitry Andric     for (auto *Arg : Args) {
1204b60736ecSDimitry Andric       Builder.markExprChild(Arg, syntax::NodeRole::ListElement);
1205b60736ecSDimitry Andric       const auto *DelimiterToken =
1206b60736ecSDimitry Andric           std::next(Builder.findToken(Arg->getEndLoc()));
1207b60736ecSDimitry Andric       if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1208b60736ecSDimitry Andric         Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1209b60736ecSDimitry Andric     }
1210b60736ecSDimitry Andric 
1211b60736ecSDimitry Andric     auto *Arguments = new (allocator()) syntax::CallArguments;
1212b60736ecSDimitry Andric     if (!Args.empty())
1213b60736ecSDimitry Andric       Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1214b60736ecSDimitry Andric                                         (*(Args.end() - 1))->getEndLoc()),
1215b60736ecSDimitry Andric                        Arguments, nullptr);
1216b60736ecSDimitry Andric 
1217b60736ecSDimitry Andric     return Arguments;
1218b60736ecSDimitry Andric   }
1219b60736ecSDimitry Andric 
WalkUpFromCallExpr(CallExpr * S)1220b60736ecSDimitry Andric   bool WalkUpFromCallExpr(CallExpr *S) {
1221b60736ecSDimitry Andric     Builder.markExprChild(S->getCallee(), syntax::NodeRole::Callee);
1222b60736ecSDimitry Andric 
1223b60736ecSDimitry Andric     const auto *LParenToken =
1224b60736ecSDimitry Andric         std::next(Builder.findToken(S->getCallee()->getEndLoc()));
1225b60736ecSDimitry Andric     // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have fixed
1226b60736ecSDimitry Andric     // the test on decltype desctructors.
1227b60736ecSDimitry Andric     if (LParenToken->kind() == clang::tok::l_paren)
1228b60736ecSDimitry Andric       Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
1229b60736ecSDimitry Andric 
1230b60736ecSDimitry Andric     Builder.markChild(buildCallArguments(S->arguments()),
1231b60736ecSDimitry Andric                       syntax::NodeRole::Arguments);
1232b60736ecSDimitry Andric 
1233b60736ecSDimitry Andric     Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
1234b60736ecSDimitry Andric 
1235b60736ecSDimitry Andric     Builder.foldNode(Builder.getRange(S->getSourceRange()),
1236b60736ecSDimitry Andric                      new (allocator()) syntax::CallExpression, S);
1237b60736ecSDimitry Andric     return true;
1238b60736ecSDimitry Andric   }
1239b60736ecSDimitry Andric 
WalkUpFromCXXConstructExpr(CXXConstructExpr * S)1240b60736ecSDimitry Andric   bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S) {
1241b60736ecSDimitry Andric     // Ignore the implicit calls to default constructors.
1242b60736ecSDimitry Andric     if ((S->getNumArgs() == 0 || isa<CXXDefaultArgExpr>(S->getArg(0))) &&
1243b60736ecSDimitry Andric         S->getParenOrBraceRange().isInvalid())
1244b60736ecSDimitry Andric       return true;
1245b60736ecSDimitry Andric     return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1246b60736ecSDimitry Andric   }
1247b60736ecSDimitry Andric 
TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * S)1248cfca06d7SDimitry Andric   bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
1249b60736ecSDimitry Andric     // To construct a syntax tree of the same shape for calls to built-in and
1250b60736ecSDimitry Andric     // user-defined operators, ignore the `DeclRefExpr` that refers to the
1251b60736ecSDimitry Andric     // operator and treat it as a simple token. Do that by traversing
1252b60736ecSDimitry Andric     // arguments instead of children.
1253b60736ecSDimitry Andric     for (auto *child : S->arguments()) {
1254cfca06d7SDimitry Andric       // A postfix unary operator is declared as taking two operands. The
1255cfca06d7SDimitry Andric       // second operand is used to distinguish from its prefix counterpart. In
1256cfca06d7SDimitry Andric       // the semantic AST this "phantom" operand is represented as a
1257cfca06d7SDimitry Andric       // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
1258cfca06d7SDimitry Andric       // operand because it does not correspond to anything written in source
1259b60736ecSDimitry Andric       // code.
1260b60736ecSDimitry Andric       if (child->getSourceRange().isInvalid()) {
1261b60736ecSDimitry Andric         assert(getOperatorNodeKind(*S) ==
1262b60736ecSDimitry Andric                syntax::NodeKind::PostfixUnaryOperatorExpression);
1263cfca06d7SDimitry Andric         continue;
1264b60736ecSDimitry Andric       }
1265cfca06d7SDimitry Andric       if (!TraverseStmt(child))
1266cfca06d7SDimitry Andric         return false;
1267cfca06d7SDimitry Andric     }
1268cfca06d7SDimitry Andric     return WalkUpFromCXXOperatorCallExpr(S);
1269cfca06d7SDimitry Andric   }
1270cfca06d7SDimitry Andric 
WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr * S)1271cfca06d7SDimitry Andric   bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
1272cfca06d7SDimitry Andric     switch (getOperatorNodeKind(*S)) {
1273cfca06d7SDimitry Andric     case syntax::NodeKind::BinaryOperatorExpression:
1274b60736ecSDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::LeftHandSide);
1275b60736ecSDimitry Andric       Builder.markChildToken(S->getOperatorLoc(),
1276b60736ecSDimitry Andric                              syntax::NodeRole::OperatorToken);
1277b60736ecSDimitry Andric       Builder.markExprChild(S->getArg(1), syntax::NodeRole::RightHandSide);
1278cfca06d7SDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1279cfca06d7SDimitry Andric                        new (allocator()) syntax::BinaryOperatorExpression, S);
1280cfca06d7SDimitry Andric       return true;
1281cfca06d7SDimitry Andric     case syntax::NodeKind::PrefixUnaryOperatorExpression:
1282b60736ecSDimitry Andric       Builder.markChildToken(S->getOperatorLoc(),
1283b60736ecSDimitry Andric                              syntax::NodeRole::OperatorToken);
1284b60736ecSDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand);
1285cfca06d7SDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1286cfca06d7SDimitry Andric                        new (allocator()) syntax::PrefixUnaryOperatorExpression,
1287cfca06d7SDimitry Andric                        S);
1288cfca06d7SDimitry Andric       return true;
1289cfca06d7SDimitry Andric     case syntax::NodeKind::PostfixUnaryOperatorExpression:
1290b60736ecSDimitry Andric       Builder.markChildToken(S->getOperatorLoc(),
1291b60736ecSDimitry Andric                              syntax::NodeRole::OperatorToken);
1292b60736ecSDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand);
1293cfca06d7SDimitry Andric       Builder.foldNode(Builder.getExprRange(S),
1294cfca06d7SDimitry Andric                        new (allocator()) syntax::PostfixUnaryOperatorExpression,
1295cfca06d7SDimitry Andric                        S);
1296cfca06d7SDimitry Andric       return true;
1297b60736ecSDimitry Andric     case syntax::NodeKind::CallExpression: {
1298b60736ecSDimitry Andric       Builder.markExprChild(S->getArg(0), syntax::NodeRole::Callee);
1299b60736ecSDimitry Andric 
1300b60736ecSDimitry Andric       const auto *LParenToken =
1301b60736ecSDimitry Andric           std::next(Builder.findToken(S->getArg(0)->getEndLoc()));
1302b60736ecSDimitry Andric       // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have
1303b60736ecSDimitry Andric       // fixed the test on decltype desctructors.
1304b60736ecSDimitry Andric       if (LParenToken->kind() == clang::tok::l_paren)
1305b60736ecSDimitry Andric         Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
1306b60736ecSDimitry Andric 
1307b60736ecSDimitry Andric       Builder.markChild(buildCallArguments(CallExpr::arg_range(
1308b60736ecSDimitry Andric                             S->arg_begin() + 1, S->arg_end())),
1309b60736ecSDimitry Andric                         syntax::NodeRole::Arguments);
1310b60736ecSDimitry Andric 
1311b60736ecSDimitry Andric       Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
1312b60736ecSDimitry Andric 
1313b60736ecSDimitry Andric       Builder.foldNode(Builder.getRange(S->getSourceRange()),
1314b60736ecSDimitry Andric                        new (allocator()) syntax::CallExpression, S);
1315b60736ecSDimitry Andric       return true;
1316b60736ecSDimitry Andric     }
1317cfca06d7SDimitry Andric     case syntax::NodeKind::UnknownExpression:
1318b60736ecSDimitry Andric       return WalkUpFromExpr(S);
1319cfca06d7SDimitry Andric     default:
1320cfca06d7SDimitry Andric       llvm_unreachable("getOperatorNodeKind() does not return this value");
1321cfca06d7SDimitry Andric     }
1322cfca06d7SDimitry Andric   }
1323cfca06d7SDimitry Andric 
WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr * S)1324b60736ecSDimitry Andric   bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S) { return true; }
1325b60736ecSDimitry Andric 
WalkUpFromNamespaceDecl(NamespaceDecl * S)1326706b4fc4SDimitry Andric   bool WalkUpFromNamespaceDecl(NamespaceDecl *S) {
1327cfca06d7SDimitry Andric     auto Tokens = Builder.getDeclarationRange(S);
1328706b4fc4SDimitry Andric     if (Tokens.front().kind() == tok::coloncolon) {
1329706b4fc4SDimitry Andric       // Handle nested namespace definitions. Those start at '::' token, e.g.
1330706b4fc4SDimitry Andric       // namespace a^::b {}
1331706b4fc4SDimitry Andric       // FIXME: build corresponding nodes for the name of this namespace.
1332706b4fc4SDimitry Andric       return true;
1333706b4fc4SDimitry Andric     }
1334cfca06d7SDimitry Andric     Builder.foldNode(Tokens, new (allocator()) syntax::NamespaceDefinition, S);
1335cfca06d7SDimitry Andric     return true;
1336cfca06d7SDimitry Andric   }
1337cfca06d7SDimitry Andric 
1338b60736ecSDimitry Andric   // FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test
1339b60736ecSDimitry Andric   // results. Find test coverage or remove it.
TraverseParenTypeLoc(ParenTypeLoc L)1340cfca06d7SDimitry Andric   bool TraverseParenTypeLoc(ParenTypeLoc L) {
1341cfca06d7SDimitry Andric     // We reverse order of traversal to get the proper syntax structure.
1342cfca06d7SDimitry Andric     if (!WalkUpFromParenTypeLoc(L))
1343cfca06d7SDimitry Andric       return false;
1344cfca06d7SDimitry Andric     return TraverseTypeLoc(L.getInnerLoc());
1345cfca06d7SDimitry Andric   }
1346cfca06d7SDimitry Andric 
WalkUpFromParenTypeLoc(ParenTypeLoc L)1347cfca06d7SDimitry Andric   bool WalkUpFromParenTypeLoc(ParenTypeLoc L) {
1348cfca06d7SDimitry Andric     Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
1349cfca06d7SDimitry Andric     Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
1350cfca06d7SDimitry Andric     Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getRParenLoc()),
1351cfca06d7SDimitry Andric                      new (allocator()) syntax::ParenDeclarator, L);
1352cfca06d7SDimitry Andric     return true;
1353cfca06d7SDimitry Andric   }
1354cfca06d7SDimitry Andric 
1355cfca06d7SDimitry Andric   // Declarator chunks, they are produced by type locs and some clang::Decls.
WalkUpFromArrayTypeLoc(ArrayTypeLoc L)1356cfca06d7SDimitry Andric   bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L) {
1357cfca06d7SDimitry Andric     Builder.markChildToken(L.getLBracketLoc(), syntax::NodeRole::OpenParen);
1358b60736ecSDimitry Andric     Builder.markExprChild(L.getSizeExpr(), syntax::NodeRole::Size);
1359cfca06d7SDimitry Andric     Builder.markChildToken(L.getRBracketLoc(), syntax::NodeRole::CloseParen);
1360cfca06d7SDimitry Andric     Builder.foldNode(Builder.getRange(L.getLBracketLoc(), L.getRBracketLoc()),
1361cfca06d7SDimitry Andric                      new (allocator()) syntax::ArraySubscript, L);
1362cfca06d7SDimitry Andric     return true;
1363cfca06d7SDimitry Andric   }
1364cfca06d7SDimitry Andric 
1365b60736ecSDimitry Andric   syntax::ParameterDeclarationList *
buildParameterDeclarationList(ArrayRef<ParmVarDecl * > Params)1366b60736ecSDimitry Andric   buildParameterDeclarationList(ArrayRef<ParmVarDecl *> Params) {
1367b60736ecSDimitry Andric     for (auto *P : Params) {
1368b60736ecSDimitry Andric       Builder.markChild(P, syntax::NodeRole::ListElement);
1369b60736ecSDimitry Andric       const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1370b60736ecSDimitry Andric       if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1371b60736ecSDimitry Andric         Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1372b60736ecSDimitry Andric     }
1373b60736ecSDimitry Andric     auto *Parameters = new (allocator()) syntax::ParameterDeclarationList;
1374b60736ecSDimitry Andric     if (!Params.empty())
1375b60736ecSDimitry Andric       Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1376b60736ecSDimitry Andric                                         Params.back()->getEndLoc()),
1377b60736ecSDimitry Andric                        Parameters, nullptr);
1378b60736ecSDimitry Andric     return Parameters;
1379b60736ecSDimitry Andric   }
1380b60736ecSDimitry Andric 
WalkUpFromFunctionTypeLoc(FunctionTypeLoc L)1381cfca06d7SDimitry Andric   bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) {
1382cfca06d7SDimitry Andric     Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
1383b60736ecSDimitry Andric 
1384b60736ecSDimitry Andric     Builder.markChild(buildParameterDeclarationList(L.getParams()),
1385b60736ecSDimitry Andric                       syntax::NodeRole::Parameters);
1386b60736ecSDimitry Andric 
1387cfca06d7SDimitry Andric     Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
1388cfca06d7SDimitry Andric     Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()),
1389cfca06d7SDimitry Andric                      new (allocator()) syntax::ParametersAndQualifiers, L);
1390cfca06d7SDimitry Andric     return true;
1391cfca06d7SDimitry Andric   }
1392cfca06d7SDimitry Andric 
WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L)1393cfca06d7SDimitry Andric   bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L) {
1394cfca06d7SDimitry Andric     if (!L.getTypePtr()->hasTrailingReturn())
1395cfca06d7SDimitry Andric       return WalkUpFromFunctionTypeLoc(L);
1396cfca06d7SDimitry Andric 
1397b60736ecSDimitry Andric     auto *TrailingReturnTokens = buildTrailingReturn(L);
1398cfca06d7SDimitry Andric     // Finish building the node for parameters.
1399b60736ecSDimitry Andric     Builder.markChild(TrailingReturnTokens, syntax::NodeRole::TrailingReturn);
1400cfca06d7SDimitry Andric     return WalkUpFromFunctionTypeLoc(L);
1401cfca06d7SDimitry Andric   }
1402cfca06d7SDimitry Andric 
TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L)1403b60736ecSDimitry Andric   bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) {
1404b60736ecSDimitry Andric     // In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds
1405b60736ecSDimitry Andric     // to "Y::*" but it points to a `ParenTypeLoc` that corresponds to
1406b60736ecSDimitry Andric     // "(Y::*mp)" We thus reverse the order of traversal to get the proper
1407b60736ecSDimitry Andric     // syntax structure.
1408b60736ecSDimitry Andric     if (!WalkUpFromMemberPointerTypeLoc(L))
1409b60736ecSDimitry Andric       return false;
1410b60736ecSDimitry Andric     return TraverseTypeLoc(L.getPointeeLoc());
1411b60736ecSDimitry Andric   }
1412b60736ecSDimitry Andric 
WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L)1413cfca06d7SDimitry Andric   bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) {
1414cfca06d7SDimitry Andric     auto SR = L.getLocalSourceRange();
1415cfca06d7SDimitry Andric     Builder.foldNode(Builder.getRange(SR),
1416cfca06d7SDimitry Andric                      new (allocator()) syntax::MemberPointer, L);
1417706b4fc4SDimitry Andric     return true;
1418706b4fc4SDimitry Andric   }
1419706b4fc4SDimitry Andric 
1420706b4fc4SDimitry Andric   // The code below is very regular, it could even be generated with some
1421706b4fc4SDimitry Andric   // preprocessor magic. We merely assign roles to the corresponding children
1422706b4fc4SDimitry Andric   // and fold resulting nodes.
WalkUpFromDeclStmt(DeclStmt * S)1423706b4fc4SDimitry Andric   bool WalkUpFromDeclStmt(DeclStmt *S) {
1424706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1425cfca06d7SDimitry Andric                      new (allocator()) syntax::DeclarationStatement, S);
1426706b4fc4SDimitry Andric     return true;
1427706b4fc4SDimitry Andric   }
1428706b4fc4SDimitry Andric 
WalkUpFromNullStmt(NullStmt * S)1429706b4fc4SDimitry Andric   bool WalkUpFromNullStmt(NullStmt *S) {
1430706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1431cfca06d7SDimitry Andric                      new (allocator()) syntax::EmptyStatement, S);
1432706b4fc4SDimitry Andric     return true;
1433706b4fc4SDimitry Andric   }
1434706b4fc4SDimitry Andric 
WalkUpFromSwitchStmt(SwitchStmt * S)1435706b4fc4SDimitry Andric   bool WalkUpFromSwitchStmt(SwitchStmt *S) {
1436706b4fc4SDimitry Andric     Builder.markChildToken(S->getSwitchLoc(),
1437706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1438706b4fc4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1439706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1440cfca06d7SDimitry Andric                      new (allocator()) syntax::SwitchStatement, S);
1441706b4fc4SDimitry Andric     return true;
1442706b4fc4SDimitry Andric   }
1443706b4fc4SDimitry Andric 
WalkUpFromCaseStmt(CaseStmt * S)1444706b4fc4SDimitry Andric   bool WalkUpFromCaseStmt(CaseStmt *S) {
1445706b4fc4SDimitry Andric     Builder.markChildToken(S->getKeywordLoc(),
1446706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1447b60736ecSDimitry Andric     Builder.markExprChild(S->getLHS(), syntax::NodeRole::CaseValue);
1448706b4fc4SDimitry Andric     Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement);
1449706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1450cfca06d7SDimitry Andric                      new (allocator()) syntax::CaseStatement, S);
1451706b4fc4SDimitry Andric     return true;
1452706b4fc4SDimitry Andric   }
1453706b4fc4SDimitry Andric 
WalkUpFromDefaultStmt(DefaultStmt * S)1454706b4fc4SDimitry Andric   bool WalkUpFromDefaultStmt(DefaultStmt *S) {
1455706b4fc4SDimitry Andric     Builder.markChildToken(S->getKeywordLoc(),
1456706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1457706b4fc4SDimitry Andric     Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement);
1458706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1459cfca06d7SDimitry Andric                      new (allocator()) syntax::DefaultStatement, S);
1460706b4fc4SDimitry Andric     return true;
1461706b4fc4SDimitry Andric   }
1462706b4fc4SDimitry Andric 
WalkUpFromIfStmt(IfStmt * S)1463706b4fc4SDimitry Andric   bool WalkUpFromIfStmt(IfStmt *S) {
1464706b4fc4SDimitry Andric     Builder.markChildToken(S->getIfLoc(), syntax::NodeRole::IntroducerKeyword);
1465344a3780SDimitry Andric     Stmt *ConditionStatement = S->getCond();
1466344a3780SDimitry Andric     if (S->hasVarStorage())
1467344a3780SDimitry Andric       ConditionStatement = S->getConditionVariableDeclStmt();
1468344a3780SDimitry Andric     Builder.markStmtChild(ConditionStatement, syntax::NodeRole::Condition);
1469b60736ecSDimitry Andric     Builder.markStmtChild(S->getThen(), syntax::NodeRole::ThenStatement);
1470b60736ecSDimitry Andric     Builder.markChildToken(S->getElseLoc(), syntax::NodeRole::ElseKeyword);
1471b60736ecSDimitry Andric     Builder.markStmtChild(S->getElse(), syntax::NodeRole::ElseStatement);
1472706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1473cfca06d7SDimitry Andric                      new (allocator()) syntax::IfStatement, S);
1474706b4fc4SDimitry Andric     return true;
1475706b4fc4SDimitry Andric   }
1476706b4fc4SDimitry Andric 
WalkUpFromForStmt(ForStmt * S)1477706b4fc4SDimitry Andric   bool WalkUpFromForStmt(ForStmt *S) {
1478706b4fc4SDimitry Andric     Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword);
1479706b4fc4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1480706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1481cfca06d7SDimitry Andric                      new (allocator()) syntax::ForStatement, S);
1482706b4fc4SDimitry Andric     return true;
1483706b4fc4SDimitry Andric   }
1484706b4fc4SDimitry Andric 
WalkUpFromWhileStmt(WhileStmt * S)1485706b4fc4SDimitry Andric   bool WalkUpFromWhileStmt(WhileStmt *S) {
1486706b4fc4SDimitry Andric     Builder.markChildToken(S->getWhileLoc(),
1487706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1488706b4fc4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1489706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1490cfca06d7SDimitry Andric                      new (allocator()) syntax::WhileStatement, S);
1491706b4fc4SDimitry Andric     return true;
1492706b4fc4SDimitry Andric   }
1493706b4fc4SDimitry Andric 
WalkUpFromContinueStmt(ContinueStmt * S)1494706b4fc4SDimitry Andric   bool WalkUpFromContinueStmt(ContinueStmt *S) {
1495706b4fc4SDimitry Andric     Builder.markChildToken(S->getContinueLoc(),
1496706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1497706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1498cfca06d7SDimitry Andric                      new (allocator()) syntax::ContinueStatement, S);
1499706b4fc4SDimitry Andric     return true;
1500706b4fc4SDimitry Andric   }
1501706b4fc4SDimitry Andric 
WalkUpFromBreakStmt(BreakStmt * S)1502706b4fc4SDimitry Andric   bool WalkUpFromBreakStmt(BreakStmt *S) {
1503706b4fc4SDimitry Andric     Builder.markChildToken(S->getBreakLoc(),
1504706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1505706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1506cfca06d7SDimitry Andric                      new (allocator()) syntax::BreakStatement, S);
1507706b4fc4SDimitry Andric     return true;
1508706b4fc4SDimitry Andric   }
1509706b4fc4SDimitry Andric 
WalkUpFromReturnStmt(ReturnStmt * S)1510706b4fc4SDimitry Andric   bool WalkUpFromReturnStmt(ReturnStmt *S) {
1511706b4fc4SDimitry Andric     Builder.markChildToken(S->getReturnLoc(),
1512706b4fc4SDimitry Andric                            syntax::NodeRole::IntroducerKeyword);
1513b60736ecSDimitry Andric     Builder.markExprChild(S->getRetValue(), syntax::NodeRole::ReturnValue);
1514706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1515cfca06d7SDimitry Andric                      new (allocator()) syntax::ReturnStatement, S);
1516706b4fc4SDimitry Andric     return true;
1517706b4fc4SDimitry Andric   }
1518706b4fc4SDimitry Andric 
WalkUpFromCXXForRangeStmt(CXXForRangeStmt * S)1519706b4fc4SDimitry Andric   bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S) {
1520706b4fc4SDimitry Andric     Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword);
1521706b4fc4SDimitry Andric     Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1522706b4fc4SDimitry Andric     Builder.foldNode(Builder.getStmtRange(S),
1523cfca06d7SDimitry Andric                      new (allocator()) syntax::RangeBasedForStatement, S);
1524706b4fc4SDimitry Andric     return true;
1525706b4fc4SDimitry Andric   }
1526706b4fc4SDimitry Andric 
WalkUpFromEmptyDecl(EmptyDecl * S)1527706b4fc4SDimitry Andric   bool WalkUpFromEmptyDecl(EmptyDecl *S) {
1528cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1529cfca06d7SDimitry Andric                      new (allocator()) syntax::EmptyDeclaration, S);
1530706b4fc4SDimitry Andric     return true;
1531706b4fc4SDimitry Andric   }
1532706b4fc4SDimitry Andric 
WalkUpFromStaticAssertDecl(StaticAssertDecl * S)1533706b4fc4SDimitry Andric   bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S) {
1534b60736ecSDimitry Andric     Builder.markExprChild(S->getAssertExpr(), syntax::NodeRole::Condition);
1535b60736ecSDimitry Andric     Builder.markExprChild(S->getMessage(), syntax::NodeRole::Message);
1536cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1537cfca06d7SDimitry Andric                      new (allocator()) syntax::StaticAssertDeclaration, S);
1538706b4fc4SDimitry Andric     return true;
1539706b4fc4SDimitry Andric   }
1540706b4fc4SDimitry Andric 
WalkUpFromLinkageSpecDecl(LinkageSpecDecl * S)1541706b4fc4SDimitry Andric   bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) {
1542cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1543cfca06d7SDimitry Andric                      new (allocator()) syntax::LinkageSpecificationDeclaration,
1544cfca06d7SDimitry Andric                      S);
1545706b4fc4SDimitry Andric     return true;
1546706b4fc4SDimitry Andric   }
1547706b4fc4SDimitry Andric 
WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl * S)1548706b4fc4SDimitry Andric   bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) {
1549cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1550cfca06d7SDimitry Andric                      new (allocator()) syntax::NamespaceAliasDefinition, S);
1551706b4fc4SDimitry Andric     return true;
1552706b4fc4SDimitry Andric   }
1553706b4fc4SDimitry Andric 
WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl * S)1554706b4fc4SDimitry Andric   bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) {
1555cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1556cfca06d7SDimitry Andric                      new (allocator()) syntax::UsingNamespaceDirective, S);
1557706b4fc4SDimitry Andric     return true;
1558706b4fc4SDimitry Andric   }
1559706b4fc4SDimitry Andric 
WalkUpFromUsingDecl(UsingDecl * S)1560706b4fc4SDimitry Andric   bool WalkUpFromUsingDecl(UsingDecl *S) {
1561cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1562cfca06d7SDimitry Andric                      new (allocator()) syntax::UsingDeclaration, S);
1563706b4fc4SDimitry Andric     return true;
1564706b4fc4SDimitry Andric   }
1565706b4fc4SDimitry Andric 
WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * S)1566706b4fc4SDimitry Andric   bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) {
1567cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1568cfca06d7SDimitry Andric                      new (allocator()) syntax::UsingDeclaration, S);
1569706b4fc4SDimitry Andric     return true;
1570706b4fc4SDimitry Andric   }
1571706b4fc4SDimitry Andric 
WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * S)1572706b4fc4SDimitry Andric   bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) {
1573cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1574cfca06d7SDimitry Andric                      new (allocator()) syntax::UsingDeclaration, S);
1575706b4fc4SDimitry Andric     return true;
1576706b4fc4SDimitry Andric   }
1577706b4fc4SDimitry Andric 
WalkUpFromTypeAliasDecl(TypeAliasDecl * S)1578706b4fc4SDimitry Andric   bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) {
1579cfca06d7SDimitry Andric     Builder.foldNode(Builder.getDeclarationRange(S),
1580cfca06d7SDimitry Andric                      new (allocator()) syntax::TypeAliasDeclaration, S);
1581706b4fc4SDimitry Andric     return true;
1582706b4fc4SDimitry Andric   }
1583706b4fc4SDimitry Andric 
158422989816SDimitry Andric private:
1585cfca06d7SDimitry Andric   /// Folds SimpleDeclarator node (if present) and in case this is the last
1586cfca06d7SDimitry Andric   /// declarator in the chain it also folds SimpleDeclaration node.
processDeclaratorAndDeclaration(T * D)1587cfca06d7SDimitry Andric   template <class T> bool processDeclaratorAndDeclaration(T *D) {
1588b60736ecSDimitry Andric     auto Range = getDeclaratorRange(
1589b60736ecSDimitry Andric         Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1590b60736ecSDimitry Andric         getQualifiedNameStart(D), getInitializerRange(D));
1591cfca06d7SDimitry Andric 
1592cfca06d7SDimitry Andric     // There doesn't have to be a declarator (e.g. `void foo(int)` only has
1593cfca06d7SDimitry Andric     // declaration, but no declarator).
1594b60736ecSDimitry Andric     if (!Range.getBegin().isValid()) {
1595b60736ecSDimitry Andric       Builder.markChild(new (allocator()) syntax::DeclaratorList,
1596b60736ecSDimitry Andric                         syntax::NodeRole::Declarators);
1597b60736ecSDimitry Andric       Builder.foldNode(Builder.getDeclarationRange(D),
1598b60736ecSDimitry Andric                        new (allocator()) syntax::SimpleDeclaration, D);
1599b60736ecSDimitry Andric       return true;
1600cfca06d7SDimitry Andric     }
1601cfca06d7SDimitry Andric 
1602b60736ecSDimitry Andric     auto *N = new (allocator()) syntax::SimpleDeclarator;
1603b60736ecSDimitry Andric     Builder.foldNode(Builder.getRange(Range), N, nullptr);
1604b60736ecSDimitry Andric     Builder.markChild(N, syntax::NodeRole::ListElement);
1605b60736ecSDimitry Andric 
1606b60736ecSDimitry Andric     if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1607b60736ecSDimitry Andric       // If this is not the last declarator in the declaration we expect a
1608b60736ecSDimitry Andric       // delimiter after it.
1609b60736ecSDimitry Andric       const auto *DelimiterToken = std::next(Builder.findToken(Range.getEnd()));
1610b60736ecSDimitry Andric       if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1611b60736ecSDimitry Andric         Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1612b60736ecSDimitry Andric     } else {
1613b60736ecSDimitry Andric       auto *DL = new (allocator()) syntax::DeclaratorList;
1614b60736ecSDimitry Andric       auto DeclarationRange = Builder.getDeclarationRange(D);
1615b60736ecSDimitry Andric       Builder.foldList(DeclarationRange, DL, nullptr);
1616b60736ecSDimitry Andric 
1617b60736ecSDimitry Andric       Builder.markChild(DL, syntax::NodeRole::Declarators);
1618b60736ecSDimitry Andric       Builder.foldNode(DeclarationRange,
1619cfca06d7SDimitry Andric                        new (allocator()) syntax::SimpleDeclaration, D);
1620cfca06d7SDimitry Andric     }
1621cfca06d7SDimitry Andric     return true;
1622cfca06d7SDimitry Andric   }
1623cfca06d7SDimitry Andric 
1624cfca06d7SDimitry Andric   /// Returns the range of the built node.
buildTrailingReturn(FunctionProtoTypeLoc L)1625b60736ecSDimitry Andric   syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1626cfca06d7SDimitry Andric     assert(L.getTypePtr()->hasTrailingReturn());
1627cfca06d7SDimitry Andric 
1628cfca06d7SDimitry Andric     auto ReturnedType = L.getReturnLoc();
1629cfca06d7SDimitry Andric     // Build node for the declarator, if any.
1630b60736ecSDimitry Andric     auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1631b60736ecSDimitry Andric                                              ReturnedType.getEndLoc());
1632cfca06d7SDimitry Andric     syntax::SimpleDeclarator *ReturnDeclarator = nullptr;
1633cfca06d7SDimitry Andric     if (ReturnDeclaratorRange.isValid()) {
1634cfca06d7SDimitry Andric       ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator;
1635cfca06d7SDimitry Andric       Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1636cfca06d7SDimitry Andric                        ReturnDeclarator, nullptr);
1637cfca06d7SDimitry Andric     }
1638cfca06d7SDimitry Andric 
1639cfca06d7SDimitry Andric     // Build node for trailing return type.
1640cfca06d7SDimitry Andric     auto Return = Builder.getRange(ReturnedType.getSourceRange());
1641cfca06d7SDimitry Andric     const auto *Arrow = Return.begin() - 1;
1642cfca06d7SDimitry Andric     assert(Arrow->kind() == tok::arrow);
1643e3b55780SDimitry Andric     auto Tokens = llvm::ArrayRef(Arrow, Return.end());
1644cfca06d7SDimitry Andric     Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1645cfca06d7SDimitry Andric     if (ReturnDeclarator)
1646b60736ecSDimitry Andric       Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1647cfca06d7SDimitry Andric     auto *R = new (allocator()) syntax::TrailingReturnType;
1648cfca06d7SDimitry Andric     Builder.foldNode(Tokens, R, L);
1649cfca06d7SDimitry Andric     return R;
1650cfca06d7SDimitry Andric   }
1651cfca06d7SDimitry Andric 
foldExplicitTemplateInstantiation(ArrayRef<syntax::Token> Range,const syntax::Token * ExternKW,const syntax::Token * TemplateKW,syntax::SimpleDeclaration * InnerDeclaration,Decl * From)1652cfca06d7SDimitry Andric   void foldExplicitTemplateInstantiation(
1653cfca06d7SDimitry Andric       ArrayRef<syntax::Token> Range, const syntax::Token *ExternKW,
1654cfca06d7SDimitry Andric       const syntax::Token *TemplateKW,
1655cfca06d7SDimitry Andric       syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1656cfca06d7SDimitry Andric     assert(!ExternKW || ExternKW->kind() == tok::kw_extern);
1657cfca06d7SDimitry Andric     assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
1658cfca06d7SDimitry Andric     Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1659cfca06d7SDimitry Andric     Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1660b60736ecSDimitry Andric     Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1661cfca06d7SDimitry Andric     Builder.foldNode(
1662cfca06d7SDimitry Andric         Range, new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1663cfca06d7SDimitry Andric   }
1664cfca06d7SDimitry Andric 
foldTemplateDeclaration(ArrayRef<syntax::Token> Range,const syntax::Token * TemplateKW,ArrayRef<syntax::Token> TemplatedDeclaration,Decl * From)1665cfca06d7SDimitry Andric   syntax::TemplateDeclaration *foldTemplateDeclaration(
1666cfca06d7SDimitry Andric       ArrayRef<syntax::Token> Range, const syntax::Token *TemplateKW,
1667cfca06d7SDimitry Andric       ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1668cfca06d7SDimitry Andric     assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
1669cfca06d7SDimitry Andric     Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1670cfca06d7SDimitry Andric 
1671cfca06d7SDimitry Andric     auto *N = new (allocator()) syntax::TemplateDeclaration;
1672cfca06d7SDimitry Andric     Builder.foldNode(Range, N, From);
1673b60736ecSDimitry Andric     Builder.markChild(N, syntax::NodeRole::Declaration);
1674cfca06d7SDimitry Andric     return N;
1675cfca06d7SDimitry Andric   }
1676cfca06d7SDimitry Andric 
167722989816SDimitry Andric   /// A small helper to save some typing.
allocator()167822989816SDimitry Andric   llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); }
167922989816SDimitry Andric 
168022989816SDimitry Andric   syntax::TreeBuilder &Builder;
1681cfca06d7SDimitry Andric   const ASTContext &Context;
168222989816SDimitry Andric };
168322989816SDimitry Andric } // namespace
168422989816SDimitry Andric 
noticeDeclWithoutSemicolon(Decl * D)1685cfca06d7SDimitry Andric void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) {
1686706b4fc4SDimitry Andric   DeclsWithoutSemicolons.insert(D);
1687706b4fc4SDimitry Andric }
1688706b4fc4SDimitry Andric 
markChildToken(SourceLocation Loc,NodeRole Role)1689706b4fc4SDimitry Andric void syntax::TreeBuilder::markChildToken(SourceLocation Loc, NodeRole Role) {
169022989816SDimitry Andric   if (Loc.isInvalid())
169122989816SDimitry Andric     return;
169222989816SDimitry Andric   Pending.assignRole(*findToken(Loc), Role);
169322989816SDimitry Andric }
169422989816SDimitry Andric 
markChildToken(const syntax::Token * T,NodeRole R)1695cfca06d7SDimitry Andric void syntax::TreeBuilder::markChildToken(const syntax::Token *T, NodeRole R) {
1696cfca06d7SDimitry Andric   if (!T)
1697cfca06d7SDimitry Andric     return;
1698cfca06d7SDimitry Andric   Pending.assignRole(*T, R);
1699cfca06d7SDimitry Andric }
1700cfca06d7SDimitry Andric 
markChild(syntax::Node * N,NodeRole R)1701cfca06d7SDimitry Andric void syntax::TreeBuilder::markChild(syntax::Node *N, NodeRole R) {
1702cfca06d7SDimitry Andric   assert(N);
1703cfca06d7SDimitry Andric   setRole(N, R);
1704cfca06d7SDimitry Andric }
1705cfca06d7SDimitry Andric 
markChild(ASTPtr N,NodeRole R)1706cfca06d7SDimitry Andric void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1707cfca06d7SDimitry Andric   auto *SN = Mapping.find(N);
1708cfca06d7SDimitry Andric   assert(SN != nullptr);
1709cfca06d7SDimitry Andric   setRole(SN, R);
1710cfca06d7SDimitry Andric }
markChild(NestedNameSpecifierLoc NNSLoc,NodeRole R)1711b60736ecSDimitry Andric void syntax::TreeBuilder::markChild(NestedNameSpecifierLoc NNSLoc, NodeRole R) {
1712b60736ecSDimitry Andric   auto *SN = Mapping.find(NNSLoc);
1713b60736ecSDimitry Andric   assert(SN != nullptr);
1714b60736ecSDimitry Andric   setRole(SN, R);
1715b60736ecSDimitry Andric }
1716cfca06d7SDimitry Andric 
markStmtChild(Stmt * Child,NodeRole Role)1717706b4fc4SDimitry Andric void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) {
1718706b4fc4SDimitry Andric   if (!Child)
1719706b4fc4SDimitry Andric     return;
1720706b4fc4SDimitry Andric 
1721cfca06d7SDimitry Andric   syntax::Tree *ChildNode;
1722cfca06d7SDimitry Andric   if (Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1723706b4fc4SDimitry Andric     // This is an expression in a statement position, consume the trailing
1724706b4fc4SDimitry Andric     // semicolon and form an 'ExpressionStatement' node.
1725b60736ecSDimitry Andric     markExprChild(ChildExpr, NodeRole::Expression);
1726cfca06d7SDimitry Andric     ChildNode = new (allocator()) syntax::ExpressionStatement;
1727cfca06d7SDimitry Andric     // (!) 'getStmtRange()' ensures this covers a trailing semicolon.
17284b4fe385SDimitry Andric     Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);
1729cfca06d7SDimitry Andric   } else {
1730cfca06d7SDimitry Andric     ChildNode = Mapping.find(Child);
1731706b4fc4SDimitry Andric   }
1732cfca06d7SDimitry Andric   assert(ChildNode != nullptr);
1733cfca06d7SDimitry Andric   setRole(ChildNode, Role);
1734706b4fc4SDimitry Andric }
1735706b4fc4SDimitry Andric 
markExprChild(Expr * Child,NodeRole Role)1736706b4fc4SDimitry Andric void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) {
1737706b4fc4SDimitry Andric   if (!Child)
1738706b4fc4SDimitry Andric     return;
1739b60736ecSDimitry Andric   Child = IgnoreImplicit(Child);
1740706b4fc4SDimitry Andric 
1741cfca06d7SDimitry Andric   syntax::Tree *ChildNode = Mapping.find(Child);
1742cfca06d7SDimitry Andric   assert(ChildNode != nullptr);
1743cfca06d7SDimitry Andric   setRole(ChildNode, Role);
1744706b4fc4SDimitry Andric }
1745706b4fc4SDimitry Andric 
findToken(SourceLocation L) const174622989816SDimitry Andric const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const {
1747cfca06d7SDimitry Andric   if (L.isInvalid())
1748cfca06d7SDimitry Andric     return nullptr;
1749b60736ecSDimitry Andric   auto It = LocationToToken.find(L);
1750706b4fc4SDimitry Andric   assert(It != LocationToToken.end());
1751706b4fc4SDimitry Andric   return It->second;
175222989816SDimitry Andric }
175322989816SDimitry Andric 
buildSyntaxTree(Arena & A,TokenBufferTokenManager & TBTM,ASTContext & Context)1754b60736ecSDimitry Andric syntax::TranslationUnit *syntax::buildSyntaxTree(Arena &A,
17554b4fe385SDimitry Andric                                                  TokenBufferTokenManager& TBTM,
1756b60736ecSDimitry Andric                                                  ASTContext &Context) {
17574b4fe385SDimitry Andric   TreeBuilder Builder(A, TBTM);
1758b60736ecSDimitry Andric   BuildTreeVisitor(Context, Builder).TraverseAST(Context);
175922989816SDimitry Andric   return std::move(Builder).finalize();
176022989816SDimitry Andric }
1761