17330f729Sjoerg //===- BuildTree.cpp ------------------------------------------*- C++ -*-=====//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg #include "clang/Tooling/Syntax/BuildTree.h"
9*e038c9c4Sjoerg #include "clang/AST/ASTFwd.h"
10*e038c9c4Sjoerg #include "clang/AST/Decl.h"
11*e038c9c4Sjoerg #include "clang/AST/DeclBase.h"
12*e038c9c4Sjoerg #include "clang/AST/DeclCXX.h"
13*e038c9c4Sjoerg #include "clang/AST/DeclarationName.h"
14*e038c9c4Sjoerg #include "clang/AST/Expr.h"
15*e038c9c4Sjoerg #include "clang/AST/ExprCXX.h"
16*e038c9c4Sjoerg #include "clang/AST/IgnoreExpr.h"
17*e038c9c4Sjoerg #include "clang/AST/OperationKinds.h"
187330f729Sjoerg #include "clang/AST/RecursiveASTVisitor.h"
197330f729Sjoerg #include "clang/AST/Stmt.h"
20*e038c9c4Sjoerg #include "clang/AST/TypeLoc.h"
21*e038c9c4Sjoerg #include "clang/AST/TypeLocVisitor.h"
227330f729Sjoerg #include "clang/Basic/LLVM.h"
237330f729Sjoerg #include "clang/Basic/SourceLocation.h"
247330f729Sjoerg #include "clang/Basic/SourceManager.h"
25*e038c9c4Sjoerg #include "clang/Basic/Specifiers.h"
267330f729Sjoerg #include "clang/Basic/TokenKinds.h"
277330f729Sjoerg #include "clang/Lex/Lexer.h"
28*e038c9c4Sjoerg #include "clang/Lex/LiteralSupport.h"
297330f729Sjoerg #include "clang/Tooling/Syntax/Nodes.h"
307330f729Sjoerg #include "clang/Tooling/Syntax/Tokens.h"
317330f729Sjoerg #include "clang/Tooling/Syntax/Tree.h"
327330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
33*e038c9c4Sjoerg #include "llvm/ADT/DenseMap.h"
34*e038c9c4Sjoerg #include "llvm/ADT/PointerUnion.h"
357330f729Sjoerg #include "llvm/ADT/STLExtras.h"
36*e038c9c4Sjoerg #include "llvm/ADT/ScopeExit.h"
377330f729Sjoerg #include "llvm/ADT/SmallVector.h"
387330f729Sjoerg #include "llvm/Support/Allocator.h"
397330f729Sjoerg #include "llvm/Support/Casting.h"
40*e038c9c4Sjoerg #include "llvm/Support/Compiler.h"
417330f729Sjoerg #include "llvm/Support/FormatVariadic.h"
42*e038c9c4Sjoerg #include "llvm/Support/MemoryBuffer.h"
437330f729Sjoerg #include "llvm/Support/raw_ostream.h"
44*e038c9c4Sjoerg #include <cstddef>
457330f729Sjoerg #include <map>
467330f729Sjoerg
477330f729Sjoerg using namespace clang;
487330f729Sjoerg
49*e038c9c4Sjoerg // Ignores the implicit `CXXConstructExpr` for copy/move constructor calls
50*e038c9c4Sjoerg // generated by the compiler, as well as in implicit conversions like the one
51*e038c9c4Sjoerg // wrapping `1` in `X x = 1;`.
IgnoreImplicitConstructorSingleStep(Expr * E)52*e038c9c4Sjoerg static Expr *IgnoreImplicitConstructorSingleStep(Expr *E) {
53*e038c9c4Sjoerg if (auto *C = dyn_cast<CXXConstructExpr>(E)) {
54*e038c9c4Sjoerg auto NumArgs = C->getNumArgs();
55*e038c9c4Sjoerg if (NumArgs == 1 || (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) {
56*e038c9c4Sjoerg Expr *A = C->getArg(0);
57*e038c9c4Sjoerg if (C->getParenOrBraceRange().isInvalid())
58*e038c9c4Sjoerg return A;
59*e038c9c4Sjoerg }
60*e038c9c4Sjoerg }
61*e038c9c4Sjoerg return E;
62*e038c9c4Sjoerg }
63*e038c9c4Sjoerg
64*e038c9c4Sjoerg // In:
65*e038c9c4Sjoerg // struct X {
66*e038c9c4Sjoerg // X(int)
67*e038c9c4Sjoerg // };
68*e038c9c4Sjoerg // X x = X(1);
69*e038c9c4Sjoerg // Ignores the implicit `CXXFunctionalCastExpr` that wraps
70*e038c9c4Sjoerg // `CXXConstructExpr X(1)`.
IgnoreCXXFunctionalCastExprWrappingConstructor(Expr * E)71*e038c9c4Sjoerg static Expr *IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E) {
72*e038c9c4Sjoerg if (auto *F = dyn_cast<CXXFunctionalCastExpr>(E)) {
73*e038c9c4Sjoerg if (F->getCastKind() == CK_ConstructorConversion)
74*e038c9c4Sjoerg return F->getSubExpr();
75*e038c9c4Sjoerg }
76*e038c9c4Sjoerg return E;
77*e038c9c4Sjoerg }
78*e038c9c4Sjoerg
IgnoreImplicit(Expr * E)79*e038c9c4Sjoerg static Expr *IgnoreImplicit(Expr *E) {
80*e038c9c4Sjoerg return IgnoreExprNodes(E, IgnoreImplicitSingleStep,
81*e038c9c4Sjoerg IgnoreImplicitConstructorSingleStep,
82*e038c9c4Sjoerg IgnoreCXXFunctionalCastExprWrappingConstructor);
83*e038c9c4Sjoerg }
84*e038c9c4Sjoerg
85*e038c9c4Sjoerg LLVM_ATTRIBUTE_UNUSED
isImplicitExpr(Expr * E)86*e038c9c4Sjoerg static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; }
87*e038c9c4Sjoerg
88*e038c9c4Sjoerg namespace {
89*e038c9c4Sjoerg /// Get start location of the Declarator from the TypeLoc.
90*e038c9c4Sjoerg /// E.g.:
91*e038c9c4Sjoerg /// loc of `(` in `int (a)`
92*e038c9c4Sjoerg /// loc of `*` in `int *(a)`
93*e038c9c4Sjoerg /// loc of the first `(` in `int (*a)(int)`
94*e038c9c4Sjoerg /// loc of the `*` in `int *(a)(int)`
95*e038c9c4Sjoerg /// loc of the first `*` in `const int *const *volatile a;`
96*e038c9c4Sjoerg ///
97*e038c9c4Sjoerg /// It is non-trivial to get the start location because TypeLocs are stored
98*e038c9c4Sjoerg /// inside out. In the example above `*volatile` is the TypeLoc returned
99*e038c9c4Sjoerg /// by `Decl.getTypeSourceInfo()`, and `*const` is what `.getPointeeLoc()`
100*e038c9c4Sjoerg /// returns.
101*e038c9c4Sjoerg struct GetStartLoc : TypeLocVisitor<GetStartLoc, SourceLocation> {
VisitParenTypeLoc__anonb546bc060111::GetStartLoc102*e038c9c4Sjoerg SourceLocation VisitParenTypeLoc(ParenTypeLoc T) {
103*e038c9c4Sjoerg auto L = Visit(T.getInnerLoc());
104*e038c9c4Sjoerg if (L.isValid())
105*e038c9c4Sjoerg return L;
106*e038c9c4Sjoerg return T.getLParenLoc();
107*e038c9c4Sjoerg }
108*e038c9c4Sjoerg
109*e038c9c4Sjoerg // Types spelled in the prefix part of the declarator.
VisitPointerTypeLoc__anonb546bc060111::GetStartLoc110*e038c9c4Sjoerg SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) {
111*e038c9c4Sjoerg return HandlePointer(T);
112*e038c9c4Sjoerg }
113*e038c9c4Sjoerg
VisitMemberPointerTypeLoc__anonb546bc060111::GetStartLoc114*e038c9c4Sjoerg SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
115*e038c9c4Sjoerg return HandlePointer(T);
116*e038c9c4Sjoerg }
117*e038c9c4Sjoerg
VisitBlockPointerTypeLoc__anonb546bc060111::GetStartLoc118*e038c9c4Sjoerg SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
119*e038c9c4Sjoerg return HandlePointer(T);
120*e038c9c4Sjoerg }
121*e038c9c4Sjoerg
VisitReferenceTypeLoc__anonb546bc060111::GetStartLoc122*e038c9c4Sjoerg SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) {
123*e038c9c4Sjoerg return HandlePointer(T);
124*e038c9c4Sjoerg }
125*e038c9c4Sjoerg
VisitObjCObjectPointerTypeLoc__anonb546bc060111::GetStartLoc126*e038c9c4Sjoerg SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) {
127*e038c9c4Sjoerg return HandlePointer(T);
128*e038c9c4Sjoerg }
129*e038c9c4Sjoerg
130*e038c9c4Sjoerg // All other cases are not important, as they are either part of declaration
131*e038c9c4Sjoerg // specifiers (e.g. inheritors of TypeSpecTypeLoc) or introduce modifiers on
132*e038c9c4Sjoerg // existing declarators (e.g. QualifiedTypeLoc). They cannot start the
133*e038c9c4Sjoerg // declarator themselves, but their underlying type can.
VisitTypeLoc__anonb546bc060111::GetStartLoc134*e038c9c4Sjoerg SourceLocation VisitTypeLoc(TypeLoc T) {
135*e038c9c4Sjoerg auto N = T.getNextTypeLoc();
136*e038c9c4Sjoerg if (!N)
137*e038c9c4Sjoerg return SourceLocation();
138*e038c9c4Sjoerg return Visit(N);
139*e038c9c4Sjoerg }
140*e038c9c4Sjoerg
VisitFunctionProtoTypeLoc__anonb546bc060111::GetStartLoc141*e038c9c4Sjoerg SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) {
142*e038c9c4Sjoerg if (T.getTypePtr()->hasTrailingReturn())
143*e038c9c4Sjoerg return SourceLocation(); // avoid recursing into the suffix of declarator.
144*e038c9c4Sjoerg return VisitTypeLoc(T);
145*e038c9c4Sjoerg }
146*e038c9c4Sjoerg
147*e038c9c4Sjoerg private:
HandlePointer__anonb546bc060111::GetStartLoc148*e038c9c4Sjoerg template <class PtrLoc> SourceLocation HandlePointer(PtrLoc T) {
149*e038c9c4Sjoerg auto L = Visit(T.getPointeeLoc());
150*e038c9c4Sjoerg if (L.isValid())
151*e038c9c4Sjoerg return L;
152*e038c9c4Sjoerg return T.getLocalSourceRange().getBegin();
153*e038c9c4Sjoerg }
154*e038c9c4Sjoerg };
155*e038c9c4Sjoerg } // namespace
156*e038c9c4Sjoerg
dropDefaultArgs(CallExpr::arg_range Args)157*e038c9c4Sjoerg static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args) {
158*e038c9c4Sjoerg auto FirstDefaultArg = std::find_if(Args.begin(), Args.end(), [](auto It) {
159*e038c9c4Sjoerg return isa<CXXDefaultArgExpr>(It);
160*e038c9c4Sjoerg });
161*e038c9c4Sjoerg return llvm::make_range(Args.begin(), FirstDefaultArg);
162*e038c9c4Sjoerg }
163*e038c9c4Sjoerg
getOperatorNodeKind(const CXXOperatorCallExpr & E)164*e038c9c4Sjoerg static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) {
165*e038c9c4Sjoerg switch (E.getOperator()) {
166*e038c9c4Sjoerg // Comparison
167*e038c9c4Sjoerg case OO_EqualEqual:
168*e038c9c4Sjoerg case OO_ExclaimEqual:
169*e038c9c4Sjoerg case OO_Greater:
170*e038c9c4Sjoerg case OO_GreaterEqual:
171*e038c9c4Sjoerg case OO_Less:
172*e038c9c4Sjoerg case OO_LessEqual:
173*e038c9c4Sjoerg case OO_Spaceship:
174*e038c9c4Sjoerg // Assignment
175*e038c9c4Sjoerg case OO_Equal:
176*e038c9c4Sjoerg case OO_SlashEqual:
177*e038c9c4Sjoerg case OO_PercentEqual:
178*e038c9c4Sjoerg case OO_CaretEqual:
179*e038c9c4Sjoerg case OO_PipeEqual:
180*e038c9c4Sjoerg case OO_LessLessEqual:
181*e038c9c4Sjoerg case OO_GreaterGreaterEqual:
182*e038c9c4Sjoerg case OO_PlusEqual:
183*e038c9c4Sjoerg case OO_MinusEqual:
184*e038c9c4Sjoerg case OO_StarEqual:
185*e038c9c4Sjoerg case OO_AmpEqual:
186*e038c9c4Sjoerg // Binary computation
187*e038c9c4Sjoerg case OO_Slash:
188*e038c9c4Sjoerg case OO_Percent:
189*e038c9c4Sjoerg case OO_Caret:
190*e038c9c4Sjoerg case OO_Pipe:
191*e038c9c4Sjoerg case OO_LessLess:
192*e038c9c4Sjoerg case OO_GreaterGreater:
193*e038c9c4Sjoerg case OO_AmpAmp:
194*e038c9c4Sjoerg case OO_PipePipe:
195*e038c9c4Sjoerg case OO_ArrowStar:
196*e038c9c4Sjoerg case OO_Comma:
197*e038c9c4Sjoerg return syntax::NodeKind::BinaryOperatorExpression;
198*e038c9c4Sjoerg case OO_Tilde:
199*e038c9c4Sjoerg case OO_Exclaim:
200*e038c9c4Sjoerg return syntax::NodeKind::PrefixUnaryOperatorExpression;
201*e038c9c4Sjoerg // Prefix/Postfix increment/decrement
202*e038c9c4Sjoerg case OO_PlusPlus:
203*e038c9c4Sjoerg case OO_MinusMinus:
204*e038c9c4Sjoerg switch (E.getNumArgs()) {
205*e038c9c4Sjoerg case 1:
206*e038c9c4Sjoerg return syntax::NodeKind::PrefixUnaryOperatorExpression;
207*e038c9c4Sjoerg case 2:
208*e038c9c4Sjoerg return syntax::NodeKind::PostfixUnaryOperatorExpression;
209*e038c9c4Sjoerg default:
210*e038c9c4Sjoerg llvm_unreachable("Invalid number of arguments for operator");
211*e038c9c4Sjoerg }
212*e038c9c4Sjoerg // Operators that can be unary or binary
213*e038c9c4Sjoerg case OO_Plus:
214*e038c9c4Sjoerg case OO_Minus:
215*e038c9c4Sjoerg case OO_Star:
216*e038c9c4Sjoerg case OO_Amp:
217*e038c9c4Sjoerg switch (E.getNumArgs()) {
218*e038c9c4Sjoerg case 1:
219*e038c9c4Sjoerg return syntax::NodeKind::PrefixUnaryOperatorExpression;
220*e038c9c4Sjoerg case 2:
221*e038c9c4Sjoerg return syntax::NodeKind::BinaryOperatorExpression;
222*e038c9c4Sjoerg default:
223*e038c9c4Sjoerg llvm_unreachable("Invalid number of arguments for operator");
224*e038c9c4Sjoerg }
225*e038c9c4Sjoerg return syntax::NodeKind::BinaryOperatorExpression;
226*e038c9c4Sjoerg // Not yet supported by SyntaxTree
227*e038c9c4Sjoerg case OO_New:
228*e038c9c4Sjoerg case OO_Delete:
229*e038c9c4Sjoerg case OO_Array_New:
230*e038c9c4Sjoerg case OO_Array_Delete:
231*e038c9c4Sjoerg case OO_Coawait:
232*e038c9c4Sjoerg case OO_Subscript:
233*e038c9c4Sjoerg case OO_Arrow:
234*e038c9c4Sjoerg return syntax::NodeKind::UnknownExpression;
235*e038c9c4Sjoerg case OO_Call:
236*e038c9c4Sjoerg return syntax::NodeKind::CallExpression;
237*e038c9c4Sjoerg case OO_Conditional: // not overloadable
238*e038c9c4Sjoerg case NUM_OVERLOADED_OPERATORS:
239*e038c9c4Sjoerg case OO_None:
240*e038c9c4Sjoerg llvm_unreachable("Not an overloadable operator");
241*e038c9c4Sjoerg }
242*e038c9c4Sjoerg llvm_unreachable("Unknown OverloadedOperatorKind enum");
243*e038c9c4Sjoerg }
244*e038c9c4Sjoerg
245*e038c9c4Sjoerg /// Get the start of the qualified name. In the examples below it gives the
246*e038c9c4Sjoerg /// location of the `^`:
247*e038c9c4Sjoerg /// `int ^a;`
248*e038c9c4Sjoerg /// `int *^a;`
249*e038c9c4Sjoerg /// `int ^a::S::f(){}`
getQualifiedNameStart(NamedDecl * D)250*e038c9c4Sjoerg static SourceLocation getQualifiedNameStart(NamedDecl *D) {
251*e038c9c4Sjoerg assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) &&
252*e038c9c4Sjoerg "only DeclaratorDecl and TypedefNameDecl are supported.");
253*e038c9c4Sjoerg
254*e038c9c4Sjoerg auto DN = D->getDeclName();
255*e038c9c4Sjoerg bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo();
256*e038c9c4Sjoerg if (IsAnonymous)
257*e038c9c4Sjoerg return SourceLocation();
258*e038c9c4Sjoerg
259*e038c9c4Sjoerg if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
260*e038c9c4Sjoerg if (DD->getQualifierLoc()) {
261*e038c9c4Sjoerg return DD->getQualifierLoc().getBeginLoc();
262*e038c9c4Sjoerg }
263*e038c9c4Sjoerg }
264*e038c9c4Sjoerg
265*e038c9c4Sjoerg return D->getLocation();
266*e038c9c4Sjoerg }
267*e038c9c4Sjoerg
268*e038c9c4Sjoerg /// Gets the range of the initializer inside an init-declarator C++ [dcl.decl].
269*e038c9c4Sjoerg /// `int a;` -> range of ``,
270*e038c9c4Sjoerg /// `int *a = nullptr` -> range of `= nullptr`.
271*e038c9c4Sjoerg /// `int a{}` -> range of `{}`.
272*e038c9c4Sjoerg /// `int a()` -> range of `()`.
getInitializerRange(Decl * D)273*e038c9c4Sjoerg static SourceRange getInitializerRange(Decl *D) {
274*e038c9c4Sjoerg if (auto *V = dyn_cast<VarDecl>(D)) {
275*e038c9c4Sjoerg auto *I = V->getInit();
276*e038c9c4Sjoerg // Initializers in range-based-for are not part of the declarator
277*e038c9c4Sjoerg if (I && !V->isCXXForRangeDecl())
278*e038c9c4Sjoerg return I->getSourceRange();
279*e038c9c4Sjoerg }
280*e038c9c4Sjoerg
281*e038c9c4Sjoerg return SourceRange();
282*e038c9c4Sjoerg }
283*e038c9c4Sjoerg
284*e038c9c4Sjoerg /// Gets the range of declarator as defined by the C++ grammar. E.g.
285*e038c9c4Sjoerg /// `int a;` -> range of `a`,
286*e038c9c4Sjoerg /// `int *a;` -> range of `*a`,
287*e038c9c4Sjoerg /// `int a[10];` -> range of `a[10]`,
288*e038c9c4Sjoerg /// `int a[1][2][3];` -> range of `a[1][2][3]`,
289*e038c9c4Sjoerg /// `int *a = nullptr` -> range of `*a = nullptr`.
290*e038c9c4Sjoerg /// `int S::f(){}` -> range of `S::f()`.
291*e038c9c4Sjoerg /// FIXME: \p Name must be a source range.
getDeclaratorRange(const SourceManager & SM,TypeLoc T,SourceLocation Name,SourceRange Initializer)292*e038c9c4Sjoerg static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T,
293*e038c9c4Sjoerg SourceLocation Name,
294*e038c9c4Sjoerg SourceRange Initializer) {
295*e038c9c4Sjoerg SourceLocation Start = GetStartLoc().Visit(T);
296*e038c9c4Sjoerg SourceLocation End = T.getEndLoc();
297*e038c9c4Sjoerg if (Name.isValid()) {
298*e038c9c4Sjoerg if (Start.isInvalid())
299*e038c9c4Sjoerg Start = Name;
300*e038c9c4Sjoerg // End of TypeLoc could be invalid if the type is invalid, fallback to the
301*e038c9c4Sjoerg // NameLoc.
302*e038c9c4Sjoerg if (End.isInvalid() || SM.isBeforeInTranslationUnit(End, Name))
303*e038c9c4Sjoerg End = Name;
304*e038c9c4Sjoerg }
305*e038c9c4Sjoerg if (Initializer.isValid()) {
306*e038c9c4Sjoerg auto InitializerEnd = Initializer.getEnd();
307*e038c9c4Sjoerg assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) ||
308*e038c9c4Sjoerg End == InitializerEnd);
309*e038c9c4Sjoerg End = InitializerEnd;
310*e038c9c4Sjoerg }
311*e038c9c4Sjoerg return SourceRange(Start, End);
312*e038c9c4Sjoerg }
313*e038c9c4Sjoerg
314*e038c9c4Sjoerg namespace {
315*e038c9c4Sjoerg /// All AST hierarchy roots that can be represented as pointers.
316*e038c9c4Sjoerg using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>;
317*e038c9c4Sjoerg /// Maintains a mapping from AST to syntax tree nodes. This class will get more
318*e038c9c4Sjoerg /// complicated as we support more kinds of AST nodes, e.g. TypeLocs.
319*e038c9c4Sjoerg /// FIXME: expose this as public API.
320*e038c9c4Sjoerg class ASTToSyntaxMapping {
321*e038c9c4Sjoerg public:
add(ASTPtr From,syntax::Tree * To)322*e038c9c4Sjoerg void add(ASTPtr From, syntax::Tree *To) {
323*e038c9c4Sjoerg assert(To != nullptr);
324*e038c9c4Sjoerg assert(!From.isNull());
325*e038c9c4Sjoerg
326*e038c9c4Sjoerg bool Added = Nodes.insert({From, To}).second;
327*e038c9c4Sjoerg (void)Added;
328*e038c9c4Sjoerg assert(Added && "mapping added twice");
329*e038c9c4Sjoerg }
330*e038c9c4Sjoerg
add(NestedNameSpecifierLoc From,syntax::Tree * To)331*e038c9c4Sjoerg void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
332*e038c9c4Sjoerg assert(To != nullptr);
333*e038c9c4Sjoerg assert(From.hasQualifier());
334*e038c9c4Sjoerg
335*e038c9c4Sjoerg bool Added = NNSNodes.insert({From, To}).second;
336*e038c9c4Sjoerg (void)Added;
337*e038c9c4Sjoerg assert(Added && "mapping added twice");
338*e038c9c4Sjoerg }
339*e038c9c4Sjoerg
find(ASTPtr P) const340*e038c9c4Sjoerg syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }
341*e038c9c4Sjoerg
find(NestedNameSpecifierLoc P) const342*e038c9c4Sjoerg syntax::Tree *find(NestedNameSpecifierLoc P) const {
343*e038c9c4Sjoerg return NNSNodes.lookup(P);
344*e038c9c4Sjoerg }
345*e038c9c4Sjoerg
346*e038c9c4Sjoerg private:
347*e038c9c4Sjoerg llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes;
348*e038c9c4Sjoerg llvm::DenseMap<NestedNameSpecifierLoc, syntax::Tree *> NNSNodes;
349*e038c9c4Sjoerg };
350*e038c9c4Sjoerg } // namespace
351*e038c9c4Sjoerg
3527330f729Sjoerg /// A helper class for constructing the syntax tree while traversing a clang
3537330f729Sjoerg /// AST.
3547330f729Sjoerg ///
3557330f729Sjoerg /// At each point of the traversal we maintain a list of pending nodes.
3567330f729Sjoerg /// Initially all tokens are added as pending nodes. When processing a clang AST
3577330f729Sjoerg /// node, the clients need to:
3587330f729Sjoerg /// - create a corresponding syntax node,
3597330f729Sjoerg /// - assign roles to all pending child nodes with 'markChild' and
3607330f729Sjoerg /// 'markChildToken',
3617330f729Sjoerg /// - replace the child nodes with the new syntax node in the pending list
3627330f729Sjoerg /// with 'foldNode'.
3637330f729Sjoerg ///
3647330f729Sjoerg /// Note that all children are expected to be processed when building a node.
3657330f729Sjoerg ///
3667330f729Sjoerg /// Call finalize() to finish building the tree and consume the root node.
3677330f729Sjoerg class syntax::TreeBuilder {
3687330f729Sjoerg public:
TreeBuilder(syntax::Arena & Arena)369*e038c9c4Sjoerg TreeBuilder(syntax::Arena &Arena) : Arena(Arena), Pending(Arena) {
370*e038c9c4Sjoerg for (const auto &T : Arena.getTokenBuffer().expandedTokens())
371*e038c9c4Sjoerg LocationToToken.insert({T.location(), &T});
372*e038c9c4Sjoerg }
3737330f729Sjoerg
allocator()374*e038c9c4Sjoerg llvm::BumpPtrAllocator &allocator() { return Arena.getAllocator(); }
sourceManager() const375*e038c9c4Sjoerg const SourceManager &sourceManager() const {
376*e038c9c4Sjoerg return Arena.getSourceManager();
377*e038c9c4Sjoerg }
3787330f729Sjoerg
3797330f729Sjoerg /// Populate children for \p New node, assuming it covers tokens from \p
3807330f729Sjoerg /// Range.
foldNode(ArrayRef<syntax::Token> Range,syntax::Tree * New,ASTPtr From)381*e038c9c4Sjoerg void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, ASTPtr From) {
382*e038c9c4Sjoerg assert(New);
383*e038c9c4Sjoerg Pending.foldChildren(Arena, Range, New);
384*e038c9c4Sjoerg if (From)
385*e038c9c4Sjoerg Mapping.add(From, New);
386*e038c9c4Sjoerg }
3877330f729Sjoerg
foldNode(ArrayRef<syntax::Token> Range,syntax::Tree * New,TypeLoc L)388*e038c9c4Sjoerg void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New, TypeLoc L) {
389*e038c9c4Sjoerg // FIXME: add mapping for TypeLocs
390*e038c9c4Sjoerg foldNode(Range, New, nullptr);
391*e038c9c4Sjoerg }
392*e038c9c4Sjoerg
foldNode(llvm::ArrayRef<syntax::Token> Range,syntax::Tree * New,NestedNameSpecifierLoc From)393*e038c9c4Sjoerg void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New,
394*e038c9c4Sjoerg NestedNameSpecifierLoc From) {
395*e038c9c4Sjoerg assert(New);
396*e038c9c4Sjoerg Pending.foldChildren(Arena, Range, New);
397*e038c9c4Sjoerg if (From)
398*e038c9c4Sjoerg Mapping.add(From, New);
399*e038c9c4Sjoerg }
400*e038c9c4Sjoerg
401*e038c9c4Sjoerg /// Populate children for \p New list, assuming it covers tokens from a
402*e038c9c4Sjoerg /// subrange of \p SuperRange.
foldList(ArrayRef<syntax::Token> SuperRange,syntax::List * New,ASTPtr From)403*e038c9c4Sjoerg void foldList(ArrayRef<syntax::Token> SuperRange, syntax::List *New,
404*e038c9c4Sjoerg ASTPtr From) {
405*e038c9c4Sjoerg assert(New);
406*e038c9c4Sjoerg auto ListRange = Pending.shrinkToFitList(SuperRange);
407*e038c9c4Sjoerg Pending.foldChildren(Arena, ListRange, New);
408*e038c9c4Sjoerg if (From)
409*e038c9c4Sjoerg Mapping.add(From, New);
410*e038c9c4Sjoerg }
411*e038c9c4Sjoerg
412*e038c9c4Sjoerg /// Notifies that we should not consume trailing semicolon when computing
413*e038c9c4Sjoerg /// token range of \p D.
414*e038c9c4Sjoerg void noticeDeclWithoutSemicolon(Decl *D);
415*e038c9c4Sjoerg
416*e038c9c4Sjoerg /// Mark the \p Child node with a corresponding \p Role. All marked children
417*e038c9c4Sjoerg /// should be consumed by foldNode.
418*e038c9c4Sjoerg /// When called on expressions (clang::Expr is derived from clang::Stmt),
419*e038c9c4Sjoerg /// wraps expressions into expression statement.
420*e038c9c4Sjoerg void markStmtChild(Stmt *Child, NodeRole Role);
421*e038c9c4Sjoerg /// Should be called for expressions in non-statement position to avoid
422*e038c9c4Sjoerg /// wrapping into expression statement.
423*e038c9c4Sjoerg void markExprChild(Expr *Child, NodeRole Role);
4247330f729Sjoerg /// Set role for a token starting at \p Loc.
425*e038c9c4Sjoerg void markChildToken(SourceLocation Loc, NodeRole R);
426*e038c9c4Sjoerg /// Set role for \p T.
427*e038c9c4Sjoerg void markChildToken(const syntax::Token *T, NodeRole R);
428*e038c9c4Sjoerg
429*e038c9c4Sjoerg /// Set role for \p N.
430*e038c9c4Sjoerg void markChild(syntax::Node *N, NodeRole R);
431*e038c9c4Sjoerg /// Set role for the syntax node matching \p N.
432*e038c9c4Sjoerg void markChild(ASTPtr N, NodeRole R);
433*e038c9c4Sjoerg /// Set role for the syntax node matching \p N.
434*e038c9c4Sjoerg void markChild(NestedNameSpecifierLoc N, NodeRole R);
4357330f729Sjoerg
4367330f729Sjoerg /// Finish building the tree and consume the root node.
finalize()4377330f729Sjoerg syntax::TranslationUnit *finalize() && {
438*e038c9c4Sjoerg auto Tokens = Arena.getTokenBuffer().expandedTokens();
4397330f729Sjoerg assert(!Tokens.empty());
4407330f729Sjoerg assert(Tokens.back().kind() == tok::eof);
4417330f729Sjoerg
4427330f729Sjoerg // Build the root of the tree, consuming all the children.
443*e038c9c4Sjoerg Pending.foldChildren(Arena, Tokens.drop_back(),
444*e038c9c4Sjoerg new (Arena.getAllocator()) syntax::TranslationUnit);
4457330f729Sjoerg
446*e038c9c4Sjoerg auto *TU = cast<syntax::TranslationUnit>(std::move(Pending).finalize());
447*e038c9c4Sjoerg TU->assertInvariantsRecursive();
448*e038c9c4Sjoerg return TU;
4497330f729Sjoerg }
4507330f729Sjoerg
451*e038c9c4Sjoerg /// Finds a token starting at \p L. The token must exist if \p L is valid.
452*e038c9c4Sjoerg const syntax::Token *findToken(SourceLocation L) const;
453*e038c9c4Sjoerg
454*e038c9c4Sjoerg /// Finds the syntax tokens corresponding to the \p SourceRange.
getRange(SourceRange Range) const455*e038c9c4Sjoerg ArrayRef<syntax::Token> getRange(SourceRange Range) const {
456*e038c9c4Sjoerg assert(Range.isValid());
457*e038c9c4Sjoerg return getRange(Range.getBegin(), Range.getEnd());
458*e038c9c4Sjoerg }
459*e038c9c4Sjoerg
460*e038c9c4Sjoerg /// Finds the syntax tokens corresponding to the passed source locations.
4617330f729Sjoerg /// \p First is the start position of the first token and \p Last is the start
4627330f729Sjoerg /// position of the last token.
getRange(SourceLocation First,SourceLocation Last) const463*e038c9c4Sjoerg ArrayRef<syntax::Token> getRange(SourceLocation First,
4647330f729Sjoerg SourceLocation Last) const {
4657330f729Sjoerg assert(First.isValid());
4667330f729Sjoerg assert(Last.isValid());
4677330f729Sjoerg assert(First == Last ||
468*e038c9c4Sjoerg Arena.getSourceManager().isBeforeInTranslationUnit(First, Last));
4697330f729Sjoerg return llvm::makeArrayRef(findToken(First), std::next(findToken(Last)));
4707330f729Sjoerg }
471*e038c9c4Sjoerg
472*e038c9c4Sjoerg ArrayRef<syntax::Token>
getTemplateRange(const ClassTemplateSpecializationDecl * D) const473*e038c9c4Sjoerg getTemplateRange(const ClassTemplateSpecializationDecl *D) const {
474*e038c9c4Sjoerg auto Tokens = getRange(D->getSourceRange());
475*e038c9c4Sjoerg return maybeAppendSemicolon(Tokens, D);
4767330f729Sjoerg }
477*e038c9c4Sjoerg
478*e038c9c4Sjoerg /// Returns true if \p D is the last declarator in a chain and is thus
479*e038c9c4Sjoerg /// reponsible for creating SimpleDeclaration for the whole chain.
isResponsibleForCreatingDeclaration(const Decl * D) const480*e038c9c4Sjoerg bool isResponsibleForCreatingDeclaration(const Decl *D) const {
481*e038c9c4Sjoerg assert((isa<DeclaratorDecl, TypedefNameDecl>(D)) &&
482*e038c9c4Sjoerg "only DeclaratorDecl and TypedefNameDecl are supported.");
483*e038c9c4Sjoerg
484*e038c9c4Sjoerg const Decl *Next = D->getNextDeclInContext();
485*e038c9c4Sjoerg
486*e038c9c4Sjoerg // There's no next sibling, this one is responsible.
487*e038c9c4Sjoerg if (Next == nullptr) {
488*e038c9c4Sjoerg return true;
489*e038c9c4Sjoerg }
490*e038c9c4Sjoerg
491*e038c9c4Sjoerg // Next sibling is not the same type, this one is responsible.
492*e038c9c4Sjoerg if (D->getKind() != Next->getKind()) {
493*e038c9c4Sjoerg return true;
494*e038c9c4Sjoerg }
495*e038c9c4Sjoerg // Next sibling doesn't begin at the same loc, it must be a different
496*e038c9c4Sjoerg // declaration, so this declarator is responsible.
497*e038c9c4Sjoerg if (Next->getBeginLoc() != D->getBeginLoc()) {
498*e038c9c4Sjoerg return true;
499*e038c9c4Sjoerg }
500*e038c9c4Sjoerg
501*e038c9c4Sjoerg // NextT is a member of the same declaration, and we need the last member to
502*e038c9c4Sjoerg // create declaration. This one is not responsible.
503*e038c9c4Sjoerg return false;
504*e038c9c4Sjoerg }
505*e038c9c4Sjoerg
getDeclarationRange(Decl * D)506*e038c9c4Sjoerg ArrayRef<syntax::Token> getDeclarationRange(Decl *D) {
507*e038c9c4Sjoerg ArrayRef<syntax::Token> Tokens;
508*e038c9c4Sjoerg // We want to drop the template parameters for specializations.
509*e038c9c4Sjoerg if (const auto *S = dyn_cast<TagDecl>(D))
510*e038c9c4Sjoerg Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());
511*e038c9c4Sjoerg else
512*e038c9c4Sjoerg Tokens = getRange(D->getSourceRange());
513*e038c9c4Sjoerg return maybeAppendSemicolon(Tokens, D);
514*e038c9c4Sjoerg }
515*e038c9c4Sjoerg
getExprRange(const Expr * E) const516*e038c9c4Sjoerg ArrayRef<syntax::Token> getExprRange(const Expr *E) const {
517*e038c9c4Sjoerg return getRange(E->getSourceRange());
518*e038c9c4Sjoerg }
519*e038c9c4Sjoerg
520*e038c9c4Sjoerg /// Find the adjusted range for the statement, consuming the trailing
521*e038c9c4Sjoerg /// semicolon when needed.
getStmtRange(const Stmt * S) const522*e038c9c4Sjoerg ArrayRef<syntax::Token> getStmtRange(const Stmt *S) const {
523*e038c9c4Sjoerg auto Tokens = getRange(S->getSourceRange());
524*e038c9c4Sjoerg if (isa<CompoundStmt>(S))
525*e038c9c4Sjoerg return Tokens;
526*e038c9c4Sjoerg
527*e038c9c4Sjoerg // Some statements miss a trailing semicolon, e.g. 'return', 'continue' and
528*e038c9c4Sjoerg // all statements that end with those. Consume this semicolon here.
529*e038c9c4Sjoerg if (Tokens.back().kind() == tok::semi)
530*e038c9c4Sjoerg return Tokens;
531*e038c9c4Sjoerg return withTrailingSemicolon(Tokens);
5327330f729Sjoerg }
5337330f729Sjoerg
5347330f729Sjoerg private:
maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,const Decl * D) const535*e038c9c4Sjoerg ArrayRef<syntax::Token> maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,
536*e038c9c4Sjoerg const Decl *D) const {
537*e038c9c4Sjoerg if (isa<NamespaceDecl>(D))
538*e038c9c4Sjoerg return Tokens;
539*e038c9c4Sjoerg if (DeclsWithoutSemicolons.count(D))
540*e038c9c4Sjoerg return Tokens;
541*e038c9c4Sjoerg // FIXME: do not consume trailing semicolon on function definitions.
542*e038c9c4Sjoerg // Most declarations own a semicolon in syntax trees, but not in clang AST.
543*e038c9c4Sjoerg return withTrailingSemicolon(Tokens);
544*e038c9c4Sjoerg }
545*e038c9c4Sjoerg
546*e038c9c4Sjoerg ArrayRef<syntax::Token>
withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const547*e038c9c4Sjoerg withTrailingSemicolon(ArrayRef<syntax::Token> Tokens) const {
548*e038c9c4Sjoerg assert(!Tokens.empty());
549*e038c9c4Sjoerg assert(Tokens.back().kind() != tok::eof);
550*e038c9c4Sjoerg // We never consume 'eof', so looking at the next token is ok.
551*e038c9c4Sjoerg if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi)
552*e038c9c4Sjoerg return llvm::makeArrayRef(Tokens.begin(), Tokens.end() + 1);
553*e038c9c4Sjoerg return Tokens;
554*e038c9c4Sjoerg }
555*e038c9c4Sjoerg
setRole(syntax::Node * N,NodeRole R)556*e038c9c4Sjoerg void setRole(syntax::Node *N, NodeRole R) {
557*e038c9c4Sjoerg assert(N->getRole() == NodeRole::Detached);
558*e038c9c4Sjoerg N->setRole(R);
559*e038c9c4Sjoerg }
5607330f729Sjoerg
5617330f729Sjoerg /// A collection of trees covering the input tokens.
5627330f729Sjoerg /// When created, each tree corresponds to a single token in the file.
5637330f729Sjoerg /// Clients call 'foldChildren' to attach one or more subtrees to a parent
5647330f729Sjoerg /// node and update the list of trees accordingly.
5657330f729Sjoerg ///
5667330f729Sjoerg /// Ensures that added nodes properly nest and cover the whole token stream.
5677330f729Sjoerg struct Forest {
Forestsyntax::TreeBuilder::Forest5687330f729Sjoerg Forest(syntax::Arena &A) {
569*e038c9c4Sjoerg assert(!A.getTokenBuffer().expandedTokens().empty());
570*e038c9c4Sjoerg assert(A.getTokenBuffer().expandedTokens().back().kind() == tok::eof);
5717330f729Sjoerg // Create all leaf nodes.
5727330f729Sjoerg // Note that we do not have 'eof' in the tree.
573*e038c9c4Sjoerg for (const auto &T : A.getTokenBuffer().expandedTokens().drop_back()) {
574*e038c9c4Sjoerg auto *L = new (A.getAllocator()) syntax::Leaf(&T);
575*e038c9c4Sjoerg L->Original = true;
576*e038c9c4Sjoerg L->CanModify = A.getTokenBuffer().spelledForExpanded(T).hasValue();
577*e038c9c4Sjoerg Trees.insert(Trees.end(), {&T, L});
578*e038c9c4Sjoerg }
5797330f729Sjoerg }
5807330f729Sjoerg
assignRolesyntax::TreeBuilder::Forest581*e038c9c4Sjoerg void assignRole(ArrayRef<syntax::Token> Range, syntax::NodeRole Role) {
5827330f729Sjoerg assert(!Range.empty());
5837330f729Sjoerg auto It = Trees.lower_bound(Range.begin());
5847330f729Sjoerg assert(It != Trees.end() && "no node found");
5857330f729Sjoerg assert(It->first == Range.begin() && "no child with the specified range");
5867330f729Sjoerg assert((std::next(It) == Trees.end() ||
5877330f729Sjoerg std::next(It)->first == Range.end()) &&
5887330f729Sjoerg "no child with the specified range");
589*e038c9c4Sjoerg assert(It->second->getRole() == NodeRole::Detached &&
590*e038c9c4Sjoerg "re-assigning role for a child");
591*e038c9c4Sjoerg It->second->setRole(Role);
5927330f729Sjoerg }
5937330f729Sjoerg
594*e038c9c4Sjoerg /// Shrink \p Range to a subrange that only contains tokens of a list.
595*e038c9c4Sjoerg /// List elements and delimiters should already have correct roles.
shrinkToFitListsyntax::TreeBuilder::Forest596*e038c9c4Sjoerg ArrayRef<syntax::Token> shrinkToFitList(ArrayRef<syntax::Token> Range) {
597*e038c9c4Sjoerg auto BeginChildren = Trees.lower_bound(Range.begin());
598*e038c9c4Sjoerg assert((BeginChildren == Trees.end() ||
599*e038c9c4Sjoerg BeginChildren->first == Range.begin()) &&
600*e038c9c4Sjoerg "Range crosses boundaries of existing subtrees");
601*e038c9c4Sjoerg
602*e038c9c4Sjoerg auto EndChildren = Trees.lower_bound(Range.end());
603*e038c9c4Sjoerg assert(
604*e038c9c4Sjoerg (EndChildren == Trees.end() || EndChildren->first == Range.end()) &&
605*e038c9c4Sjoerg "Range crosses boundaries of existing subtrees");
606*e038c9c4Sjoerg
607*e038c9c4Sjoerg auto BelongsToList = [](decltype(Trees)::value_type KV) {
608*e038c9c4Sjoerg auto Role = KV.second->getRole();
609*e038c9c4Sjoerg return Role == syntax::NodeRole::ListElement ||
610*e038c9c4Sjoerg Role == syntax::NodeRole::ListDelimiter;
611*e038c9c4Sjoerg };
612*e038c9c4Sjoerg
613*e038c9c4Sjoerg auto BeginListChildren =
614*e038c9c4Sjoerg std::find_if(BeginChildren, EndChildren, BelongsToList);
615*e038c9c4Sjoerg
616*e038c9c4Sjoerg auto EndListChildren =
617*e038c9c4Sjoerg std::find_if_not(BeginListChildren, EndChildren, BelongsToList);
618*e038c9c4Sjoerg
619*e038c9c4Sjoerg return ArrayRef<syntax::Token>(BeginListChildren->first,
620*e038c9c4Sjoerg EndListChildren->first);
621*e038c9c4Sjoerg }
622*e038c9c4Sjoerg
623*e038c9c4Sjoerg /// Add \p Node to the forest and attach child nodes based on \p Tokens.
foldChildrensyntax::TreeBuilder::Forest624*e038c9c4Sjoerg void foldChildren(const syntax::Arena &A, ArrayRef<syntax::Token> Tokens,
6257330f729Sjoerg syntax::Tree *Node) {
626*e038c9c4Sjoerg // Attach children to `Node`.
627*e038c9c4Sjoerg assert(Node->getFirstChild() == nullptr && "node already has children");
6287330f729Sjoerg
629*e038c9c4Sjoerg auto *FirstToken = Tokens.begin();
6307330f729Sjoerg auto BeginChildren = Trees.lower_bound(FirstToken);
631*e038c9c4Sjoerg
632*e038c9c4Sjoerg assert((BeginChildren == Trees.end() ||
633*e038c9c4Sjoerg BeginChildren->first == FirstToken) &&
6347330f729Sjoerg "fold crosses boundaries of existing subtrees");
635*e038c9c4Sjoerg auto EndChildren = Trees.lower_bound(Tokens.end());
636*e038c9c4Sjoerg assert(
637*e038c9c4Sjoerg (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&
6387330f729Sjoerg "fold crosses boundaries of existing subtrees");
6397330f729Sjoerg
640*e038c9c4Sjoerg for (auto It = BeginChildren; It != EndChildren; ++It) {
641*e038c9c4Sjoerg auto *C = It->second;
642*e038c9c4Sjoerg if (C->getRole() == NodeRole::Detached)
643*e038c9c4Sjoerg C->setRole(NodeRole::Unknown);
644*e038c9c4Sjoerg Node->appendChildLowLevel(C);
645*e038c9c4Sjoerg }
646*e038c9c4Sjoerg
647*e038c9c4Sjoerg // Mark that this node came from the AST and is backed by the source code.
648*e038c9c4Sjoerg Node->Original = true;
649*e038c9c4Sjoerg Node->CanModify =
650*e038c9c4Sjoerg A.getTokenBuffer().spelledForExpanded(Tokens).hasValue();
6517330f729Sjoerg
6527330f729Sjoerg Trees.erase(BeginChildren, EndChildren);
653*e038c9c4Sjoerg Trees.insert({FirstToken, Node});
6547330f729Sjoerg }
6557330f729Sjoerg
6567330f729Sjoerg // EXPECTS: all tokens were consumed and are owned by a single root node.
finalizesyntax::TreeBuilder::Forest6577330f729Sjoerg syntax::Node *finalize() && {
6587330f729Sjoerg assert(Trees.size() == 1);
659*e038c9c4Sjoerg auto *Root = Trees.begin()->second;
6607330f729Sjoerg Trees = {};
6617330f729Sjoerg return Root;
6627330f729Sjoerg }
6637330f729Sjoerg
strsyntax::TreeBuilder::Forest6647330f729Sjoerg std::string str(const syntax::Arena &A) const {
6657330f729Sjoerg std::string R;
6667330f729Sjoerg for (auto It = Trees.begin(); It != Trees.end(); ++It) {
6677330f729Sjoerg unsigned CoveredTokens =
6687330f729Sjoerg It != Trees.end()
6697330f729Sjoerg ? (std::next(It)->first - It->first)
670*e038c9c4Sjoerg : A.getTokenBuffer().expandedTokens().end() - It->first;
6717330f729Sjoerg
672*e038c9c4Sjoerg R += std::string(
673*e038c9c4Sjoerg formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(),
674*e038c9c4Sjoerg It->first->text(A.getSourceManager()), CoveredTokens));
675*e038c9c4Sjoerg R += It->second->dump(A.getSourceManager());
6767330f729Sjoerg }
6777330f729Sjoerg return R;
6787330f729Sjoerg }
6797330f729Sjoerg
6807330f729Sjoerg private:
6817330f729Sjoerg /// Maps from the start token to a subtree starting at that token.
682*e038c9c4Sjoerg /// Keys in the map are pointers into the array of expanded tokens, so
683*e038c9c4Sjoerg /// pointer order corresponds to the order of preprocessor tokens.
684*e038c9c4Sjoerg std::map<const syntax::Token *, syntax::Node *> Trees;
6857330f729Sjoerg };
6867330f729Sjoerg
6877330f729Sjoerg /// For debugging purposes.
str()6887330f729Sjoerg std::string str() { return Pending.str(Arena); }
6897330f729Sjoerg
6907330f729Sjoerg syntax::Arena &Arena;
691*e038c9c4Sjoerg /// To quickly find tokens by their start location.
692*e038c9c4Sjoerg llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken;
6937330f729Sjoerg Forest Pending;
694*e038c9c4Sjoerg llvm::DenseSet<Decl *> DeclsWithoutSemicolons;
695*e038c9c4Sjoerg ASTToSyntaxMapping Mapping;
6967330f729Sjoerg };
6977330f729Sjoerg
6987330f729Sjoerg namespace {
6997330f729Sjoerg class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
7007330f729Sjoerg public:
BuildTreeVisitor(ASTContext & Context,syntax::TreeBuilder & Builder)701*e038c9c4Sjoerg explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
702*e038c9c4Sjoerg : Builder(Builder), Context(Context) {}
7037330f729Sjoerg
shouldTraversePostOrder() const7047330f729Sjoerg bool shouldTraversePostOrder() const { return true; }
7057330f729Sjoerg
WalkUpFromDeclaratorDecl(DeclaratorDecl * DD)706*e038c9c4Sjoerg bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {
707*e038c9c4Sjoerg return processDeclaratorAndDeclaration(DD);
708*e038c9c4Sjoerg }
709*e038c9c4Sjoerg
WalkUpFromTypedefNameDecl(TypedefNameDecl * TD)710*e038c9c4Sjoerg bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) {
711*e038c9c4Sjoerg return processDeclaratorAndDeclaration(TD);
7127330f729Sjoerg }
7137330f729Sjoerg
VisitDecl(Decl * D)7147330f729Sjoerg bool VisitDecl(Decl *D) {
7157330f729Sjoerg assert(!D->isImplicit());
716*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(D),
717*e038c9c4Sjoerg new (allocator()) syntax::UnknownDeclaration(), D);
7187330f729Sjoerg return true;
7197330f729Sjoerg }
7207330f729Sjoerg
721*e038c9c4Sjoerg // RAV does not call WalkUpFrom* on explicit instantiations, so we have to
722*e038c9c4Sjoerg // override Traverse.
723*e038c9c4Sjoerg // FIXME: make RAV call WalkUpFrom* instead.
724*e038c9c4Sjoerg bool
TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * C)725*e038c9c4Sjoerg TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {
726*e038c9c4Sjoerg if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C))
727*e038c9c4Sjoerg return false;
728*e038c9c4Sjoerg if (C->isExplicitSpecialization())
729*e038c9c4Sjoerg return true; // we are only interested in explicit instantiations.
730*e038c9c4Sjoerg auto *Declaration =
731*e038c9c4Sjoerg cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C));
732*e038c9c4Sjoerg foldExplicitTemplateInstantiation(
733*e038c9c4Sjoerg Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()),
734*e038c9c4Sjoerg Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C);
735*e038c9c4Sjoerg return true;
736*e038c9c4Sjoerg }
737*e038c9c4Sjoerg
WalkUpFromTemplateDecl(TemplateDecl * S)738*e038c9c4Sjoerg bool WalkUpFromTemplateDecl(TemplateDecl *S) {
739*e038c9c4Sjoerg foldTemplateDeclaration(
740*e038c9c4Sjoerg Builder.getDeclarationRange(S),
741*e038c9c4Sjoerg Builder.findToken(S->getTemplateParameters()->getTemplateLoc()),
742*e038c9c4Sjoerg Builder.getDeclarationRange(S->getTemplatedDecl()), S);
743*e038c9c4Sjoerg return true;
744*e038c9c4Sjoerg }
745*e038c9c4Sjoerg
WalkUpFromTagDecl(TagDecl * C)746*e038c9c4Sjoerg bool WalkUpFromTagDecl(TagDecl *C) {
747*e038c9c4Sjoerg // FIXME: build the ClassSpecifier node.
748*e038c9c4Sjoerg if (!C->isFreeStanding()) {
749*e038c9c4Sjoerg assert(C->getNumTemplateParameterLists() == 0);
750*e038c9c4Sjoerg return true;
751*e038c9c4Sjoerg }
752*e038c9c4Sjoerg handleFreeStandingTagDecl(C);
753*e038c9c4Sjoerg return true;
754*e038c9c4Sjoerg }
755*e038c9c4Sjoerg
handleFreeStandingTagDecl(TagDecl * C)756*e038c9c4Sjoerg syntax::Declaration *handleFreeStandingTagDecl(TagDecl *C) {
757*e038c9c4Sjoerg assert(C->isFreeStanding());
758*e038c9c4Sjoerg // Class is a declaration specifier and needs a spanning declaration node.
759*e038c9c4Sjoerg auto DeclarationRange = Builder.getDeclarationRange(C);
760*e038c9c4Sjoerg syntax::Declaration *Result = new (allocator()) syntax::SimpleDeclaration;
761*e038c9c4Sjoerg Builder.foldNode(DeclarationRange, Result, nullptr);
762*e038c9c4Sjoerg
763*e038c9c4Sjoerg // Build TemplateDeclaration nodes if we had template parameters.
764*e038c9c4Sjoerg auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) {
765*e038c9c4Sjoerg const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
766*e038c9c4Sjoerg auto R = llvm::makeArrayRef(TemplateKW, DeclarationRange.end());
767*e038c9c4Sjoerg Result =
768*e038c9c4Sjoerg foldTemplateDeclaration(R, TemplateKW, DeclarationRange, nullptr);
769*e038c9c4Sjoerg DeclarationRange = R;
770*e038c9c4Sjoerg };
771*e038c9c4Sjoerg if (auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(C))
772*e038c9c4Sjoerg ConsumeTemplateParameters(*S->getTemplateParameters());
773*e038c9c4Sjoerg for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I)
774*e038c9c4Sjoerg ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1));
775*e038c9c4Sjoerg return Result;
776*e038c9c4Sjoerg }
777*e038c9c4Sjoerg
WalkUpFromTranslationUnitDecl(TranslationUnitDecl * TU)7787330f729Sjoerg bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
779*e038c9c4Sjoerg // We do not want to call VisitDecl(), the declaration for translation
7807330f729Sjoerg // unit is built by finalize().
7817330f729Sjoerg return true;
7827330f729Sjoerg }
7837330f729Sjoerg
WalkUpFromCompoundStmt(CompoundStmt * S)7847330f729Sjoerg bool WalkUpFromCompoundStmt(CompoundStmt *S) {
7857330f729Sjoerg using NodeRole = syntax::NodeRole;
7867330f729Sjoerg
787*e038c9c4Sjoerg Builder.markChildToken(S->getLBracLoc(), NodeRole::OpenParen);
788*e038c9c4Sjoerg for (auto *Child : S->body())
789*e038c9c4Sjoerg Builder.markStmtChild(Child, NodeRole::Statement);
790*e038c9c4Sjoerg Builder.markChildToken(S->getRBracLoc(), NodeRole::CloseParen);
7917330f729Sjoerg
792*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
793*e038c9c4Sjoerg new (allocator()) syntax::CompoundStatement, S);
794*e038c9c4Sjoerg return true;
795*e038c9c4Sjoerg }
796*e038c9c4Sjoerg
797*e038c9c4Sjoerg // Some statements are not yet handled by syntax trees.
WalkUpFromStmt(Stmt * S)798*e038c9c4Sjoerg bool WalkUpFromStmt(Stmt *S) {
799*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
800*e038c9c4Sjoerg new (allocator()) syntax::UnknownStatement, S);
801*e038c9c4Sjoerg return true;
802*e038c9c4Sjoerg }
803*e038c9c4Sjoerg
TraverseIfStmt(IfStmt * S)804*e038c9c4Sjoerg bool TraverseIfStmt(IfStmt *S) {
805*e038c9c4Sjoerg bool Result = [&, this]() {
806*e038c9c4Sjoerg if (S->getInit() && !TraverseStmt(S->getInit())) {
807*e038c9c4Sjoerg return false;
808*e038c9c4Sjoerg }
809*e038c9c4Sjoerg // In cases where the condition is an initialized declaration in a
810*e038c9c4Sjoerg // statement, we want to preserve the declaration and ignore the
811*e038c9c4Sjoerg // implicit condition expression in the syntax tree.
812*e038c9c4Sjoerg if (S->hasVarStorage()) {
813*e038c9c4Sjoerg if (!TraverseStmt(S->getConditionVariableDeclStmt()))
814*e038c9c4Sjoerg return false;
815*e038c9c4Sjoerg } else if (S->getCond() && !TraverseStmt(S->getCond()))
816*e038c9c4Sjoerg return false;
817*e038c9c4Sjoerg
818*e038c9c4Sjoerg if (S->getThen() && !TraverseStmt(S->getThen()))
819*e038c9c4Sjoerg return false;
820*e038c9c4Sjoerg if (S->getElse() && !TraverseStmt(S->getElse()))
821*e038c9c4Sjoerg return false;
822*e038c9c4Sjoerg return true;
823*e038c9c4Sjoerg }();
824*e038c9c4Sjoerg WalkUpFromIfStmt(S);
825*e038c9c4Sjoerg return Result;
826*e038c9c4Sjoerg }
827*e038c9c4Sjoerg
TraverseCXXForRangeStmt(CXXForRangeStmt * S)828*e038c9c4Sjoerg bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
829*e038c9c4Sjoerg // We override to traverse range initializer as VarDecl.
830*e038c9c4Sjoerg // RAV traverses it as a statement, we produce invalid node kinds in that
831*e038c9c4Sjoerg // case.
832*e038c9c4Sjoerg // FIXME: should do this in RAV instead?
833*e038c9c4Sjoerg bool Result = [&, this]() {
834*e038c9c4Sjoerg if (S->getInit() && !TraverseStmt(S->getInit()))
835*e038c9c4Sjoerg return false;
836*e038c9c4Sjoerg if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable()))
837*e038c9c4Sjoerg return false;
838*e038c9c4Sjoerg if (S->getRangeInit() && !TraverseStmt(S->getRangeInit()))
839*e038c9c4Sjoerg return false;
840*e038c9c4Sjoerg if (S->getBody() && !TraverseStmt(S->getBody()))
841*e038c9c4Sjoerg return false;
842*e038c9c4Sjoerg return true;
843*e038c9c4Sjoerg }();
844*e038c9c4Sjoerg WalkUpFromCXXForRangeStmt(S);
845*e038c9c4Sjoerg return Result;
846*e038c9c4Sjoerg }
847*e038c9c4Sjoerg
TraverseStmt(Stmt * S)848*e038c9c4Sjoerg bool TraverseStmt(Stmt *S) {
849*e038c9c4Sjoerg if (auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
850*e038c9c4Sjoerg // We want to consume the semicolon, make sure SimpleDeclaration does not.
851*e038c9c4Sjoerg for (auto *D : DS->decls())
852*e038c9c4Sjoerg Builder.noticeDeclWithoutSemicolon(D);
853*e038c9c4Sjoerg } else if (auto *E = dyn_cast_or_null<Expr>(S)) {
854*e038c9c4Sjoerg return RecursiveASTVisitor::TraverseStmt(IgnoreImplicit(E));
855*e038c9c4Sjoerg }
856*e038c9c4Sjoerg return RecursiveASTVisitor::TraverseStmt(S);
857*e038c9c4Sjoerg }
858*e038c9c4Sjoerg
TraverseOpaqueValueExpr(OpaqueValueExpr * VE)859*e038c9c4Sjoerg bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
860*e038c9c4Sjoerg // OpaqueValue doesn't correspond to concrete syntax, ignore it.
861*e038c9c4Sjoerg return true;
862*e038c9c4Sjoerg }
863*e038c9c4Sjoerg
864*e038c9c4Sjoerg // Some expressions are not yet handled by syntax trees.
WalkUpFromExpr(Expr * E)865*e038c9c4Sjoerg bool WalkUpFromExpr(Expr *E) {
866*e038c9c4Sjoerg assert(!isImplicitExpr(E) && "should be handled by TraverseStmt");
867*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(E),
868*e038c9c4Sjoerg new (allocator()) syntax::UnknownExpression, E);
869*e038c9c4Sjoerg return true;
870*e038c9c4Sjoerg }
871*e038c9c4Sjoerg
TraverseUserDefinedLiteral(UserDefinedLiteral * S)872*e038c9c4Sjoerg bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
873*e038c9c4Sjoerg // The semantic AST node `UserDefinedLiteral` (UDL) may have one child node
874*e038c9c4Sjoerg // referencing the location of the UDL suffix (`_w` in `1.2_w`). The
875*e038c9c4Sjoerg // UDL suffix location does not point to the beginning of a token, so we
876*e038c9c4Sjoerg // can't represent the UDL suffix as a separate syntax tree node.
877*e038c9c4Sjoerg
878*e038c9c4Sjoerg return WalkUpFromUserDefinedLiteral(S);
879*e038c9c4Sjoerg }
880*e038c9c4Sjoerg
881*e038c9c4Sjoerg syntax::UserDefinedLiteralExpression *
buildUserDefinedLiteral(UserDefinedLiteral * S)882*e038c9c4Sjoerg buildUserDefinedLiteral(UserDefinedLiteral *S) {
883*e038c9c4Sjoerg switch (S->getLiteralOperatorKind()) {
884*e038c9c4Sjoerg case UserDefinedLiteral::LOK_Integer:
885*e038c9c4Sjoerg return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
886*e038c9c4Sjoerg case UserDefinedLiteral::LOK_Floating:
887*e038c9c4Sjoerg return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
888*e038c9c4Sjoerg case UserDefinedLiteral::LOK_Character:
889*e038c9c4Sjoerg return new (allocator()) syntax::CharUserDefinedLiteralExpression;
890*e038c9c4Sjoerg case UserDefinedLiteral::LOK_String:
891*e038c9c4Sjoerg return new (allocator()) syntax::StringUserDefinedLiteralExpression;
892*e038c9c4Sjoerg case UserDefinedLiteral::LOK_Raw:
893*e038c9c4Sjoerg case UserDefinedLiteral::LOK_Template:
894*e038c9c4Sjoerg // For raw literal operator and numeric literal operator template we
895*e038c9c4Sjoerg // cannot get the type of the operand in the semantic AST. We get this
896*e038c9c4Sjoerg // information from the token. As integer and floating point have the same
897*e038c9c4Sjoerg // token kind, we run `NumericLiteralParser` again to distinguish them.
898*e038c9c4Sjoerg auto TokLoc = S->getBeginLoc();
899*e038c9c4Sjoerg auto TokSpelling =
900*e038c9c4Sjoerg Builder.findToken(TokLoc)->text(Context.getSourceManager());
901*e038c9c4Sjoerg auto Literal =
902*e038c9c4Sjoerg NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(),
903*e038c9c4Sjoerg Context.getLangOpts(), Context.getTargetInfo(),
904*e038c9c4Sjoerg Context.getDiagnostics());
905*e038c9c4Sjoerg if (Literal.isIntegerLiteral())
906*e038c9c4Sjoerg return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
907*e038c9c4Sjoerg else {
908*e038c9c4Sjoerg assert(Literal.isFloatingLiteral());
909*e038c9c4Sjoerg return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
910*e038c9c4Sjoerg }
911*e038c9c4Sjoerg }
912*e038c9c4Sjoerg llvm_unreachable("Unknown literal operator kind.");
913*e038c9c4Sjoerg }
914*e038c9c4Sjoerg
WalkUpFromUserDefinedLiteral(UserDefinedLiteral * S)915*e038c9c4Sjoerg bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
916*e038c9c4Sjoerg Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
917*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
918*e038c9c4Sjoerg return true;
919*e038c9c4Sjoerg }
920*e038c9c4Sjoerg
921*e038c9c4Sjoerg // FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the
922*e038c9c4Sjoerg // `DependentTemplateSpecializationType` case.
923*e038c9c4Sjoerg /// Given a nested-name-specifier return the range for the last name
924*e038c9c4Sjoerg /// specifier.
925*e038c9c4Sjoerg ///
926*e038c9c4Sjoerg /// e.g. `std::T::template X<U>::` => `template X<U>::`
getLocalSourceRange(const NestedNameSpecifierLoc & NNSLoc)927*e038c9c4Sjoerg SourceRange getLocalSourceRange(const NestedNameSpecifierLoc &NNSLoc) {
928*e038c9c4Sjoerg auto SR = NNSLoc.getLocalSourceRange();
929*e038c9c4Sjoerg
930*e038c9c4Sjoerg // The method `NestedNameSpecifierLoc::getLocalSourceRange` *should*
931*e038c9c4Sjoerg // return the desired `SourceRange`, but there is a corner case. For a
932*e038c9c4Sjoerg // `DependentTemplateSpecializationType` this method returns its
933*e038c9c4Sjoerg // qualifiers as well, in other words in the example above this method
934*e038c9c4Sjoerg // returns `T::template X<U>::` instead of only `template X<U>::`
935*e038c9c4Sjoerg if (auto TL = NNSLoc.getTypeLoc()) {
936*e038c9c4Sjoerg if (auto DependentTL =
937*e038c9c4Sjoerg TL.getAs<DependentTemplateSpecializationTypeLoc>()) {
938*e038c9c4Sjoerg // The 'template' keyword is always present in dependent template
939*e038c9c4Sjoerg // specializations. Except in the case of incorrect code
940*e038c9c4Sjoerg // TODO: Treat the case of incorrect code.
941*e038c9c4Sjoerg SR.setBegin(DependentTL.getTemplateKeywordLoc());
942*e038c9c4Sjoerg }
943*e038c9c4Sjoerg }
944*e038c9c4Sjoerg
945*e038c9c4Sjoerg return SR;
946*e038c9c4Sjoerg }
947*e038c9c4Sjoerg
getNameSpecifierKind(const NestedNameSpecifier & NNS)948*e038c9c4Sjoerg syntax::NodeKind getNameSpecifierKind(const NestedNameSpecifier &NNS) {
949*e038c9c4Sjoerg switch (NNS.getKind()) {
950*e038c9c4Sjoerg case NestedNameSpecifier::Global:
951*e038c9c4Sjoerg return syntax::NodeKind::GlobalNameSpecifier;
952*e038c9c4Sjoerg case NestedNameSpecifier::Namespace:
953*e038c9c4Sjoerg case NestedNameSpecifier::NamespaceAlias:
954*e038c9c4Sjoerg case NestedNameSpecifier::Identifier:
955*e038c9c4Sjoerg return syntax::NodeKind::IdentifierNameSpecifier;
956*e038c9c4Sjoerg case NestedNameSpecifier::TypeSpecWithTemplate:
957*e038c9c4Sjoerg return syntax::NodeKind::SimpleTemplateNameSpecifier;
958*e038c9c4Sjoerg case NestedNameSpecifier::TypeSpec: {
959*e038c9c4Sjoerg const auto *NNSType = NNS.getAsType();
960*e038c9c4Sjoerg assert(NNSType);
961*e038c9c4Sjoerg if (isa<DecltypeType>(NNSType))
962*e038c9c4Sjoerg return syntax::NodeKind::DecltypeNameSpecifier;
963*e038c9c4Sjoerg if (isa<TemplateSpecializationType, DependentTemplateSpecializationType>(
964*e038c9c4Sjoerg NNSType))
965*e038c9c4Sjoerg return syntax::NodeKind::SimpleTemplateNameSpecifier;
966*e038c9c4Sjoerg return syntax::NodeKind::IdentifierNameSpecifier;
967*e038c9c4Sjoerg }
968*e038c9c4Sjoerg default:
969*e038c9c4Sjoerg // FIXME: Support Microsoft's __super
970*e038c9c4Sjoerg llvm::report_fatal_error("We don't yet support the __super specifier",
971*e038c9c4Sjoerg true);
972*e038c9c4Sjoerg }
973*e038c9c4Sjoerg }
974*e038c9c4Sjoerg
975*e038c9c4Sjoerg syntax::NameSpecifier *
buildNameSpecifier(const NestedNameSpecifierLoc & NNSLoc)976*e038c9c4Sjoerg buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {
977*e038c9c4Sjoerg assert(NNSLoc.hasQualifier());
978*e038c9c4Sjoerg auto NameSpecifierTokens =
979*e038c9c4Sjoerg Builder.getRange(getLocalSourceRange(NNSLoc)).drop_back();
980*e038c9c4Sjoerg switch (getNameSpecifierKind(*NNSLoc.getNestedNameSpecifier())) {
981*e038c9c4Sjoerg case syntax::NodeKind::GlobalNameSpecifier:
982*e038c9c4Sjoerg return new (allocator()) syntax::GlobalNameSpecifier;
983*e038c9c4Sjoerg case syntax::NodeKind::IdentifierNameSpecifier: {
984*e038c9c4Sjoerg assert(NameSpecifierTokens.size() == 1);
985*e038c9c4Sjoerg Builder.markChildToken(NameSpecifierTokens.begin(),
986*e038c9c4Sjoerg syntax::NodeRole::Unknown);
987*e038c9c4Sjoerg auto *NS = new (allocator()) syntax::IdentifierNameSpecifier;
988*e038c9c4Sjoerg Builder.foldNode(NameSpecifierTokens, NS, nullptr);
989*e038c9c4Sjoerg return NS;
990*e038c9c4Sjoerg }
991*e038c9c4Sjoerg case syntax::NodeKind::SimpleTemplateNameSpecifier: {
992*e038c9c4Sjoerg // TODO: Build `SimpleTemplateNameSpecifier` children and implement
993*e038c9c4Sjoerg // accessors to them.
994*e038c9c4Sjoerg // Be aware, we cannot do that simply by calling `TraverseTypeLoc`,
995*e038c9c4Sjoerg // some `TypeLoc`s have inside them the previous name specifier and
996*e038c9c4Sjoerg // we want to treat them independently.
997*e038c9c4Sjoerg auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier;
998*e038c9c4Sjoerg Builder.foldNode(NameSpecifierTokens, NS, nullptr);
999*e038c9c4Sjoerg return NS;
1000*e038c9c4Sjoerg }
1001*e038c9c4Sjoerg case syntax::NodeKind::DecltypeNameSpecifier: {
1002*e038c9c4Sjoerg const auto TL = NNSLoc.getTypeLoc().castAs<DecltypeTypeLoc>();
1003*e038c9c4Sjoerg if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL))
1004*e038c9c4Sjoerg return nullptr;
1005*e038c9c4Sjoerg auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;
1006*e038c9c4Sjoerg // TODO: Implement accessor to `DecltypeNameSpecifier` inner
1007*e038c9c4Sjoerg // `DecltypeTypeLoc`.
1008*e038c9c4Sjoerg // For that add mapping from `TypeLoc` to `syntax::Node*` then:
1009*e038c9c4Sjoerg // Builder.markChild(TypeLoc, syntax::NodeRole);
1010*e038c9c4Sjoerg Builder.foldNode(NameSpecifierTokens, NS, nullptr);
1011*e038c9c4Sjoerg return NS;
1012*e038c9c4Sjoerg }
1013*e038c9c4Sjoerg default:
1014*e038c9c4Sjoerg llvm_unreachable("getChildKind() does not return this value");
1015*e038c9c4Sjoerg }
1016*e038c9c4Sjoerg }
1017*e038c9c4Sjoerg
1018*e038c9c4Sjoerg // To build syntax tree nodes for NestedNameSpecifierLoc we override
1019*e038c9c4Sjoerg // Traverse instead of WalkUpFrom because we want to traverse the children
1020*e038c9c4Sjoerg // ourselves and build a list instead of a nested tree of name specifier
1021*e038c9c4Sjoerg // prefixes.
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)1022*e038c9c4Sjoerg bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1023*e038c9c4Sjoerg if (!QualifierLoc)
1024*e038c9c4Sjoerg return true;
1025*e038c9c4Sjoerg for (auto It = QualifierLoc; It; It = It.getPrefix()) {
1026*e038c9c4Sjoerg auto *NS = buildNameSpecifier(It);
1027*e038c9c4Sjoerg if (!NS)
1028*e038c9c4Sjoerg return false;
1029*e038c9c4Sjoerg Builder.markChild(NS, syntax::NodeRole::ListElement);
1030*e038c9c4Sjoerg Builder.markChildToken(It.getEndLoc(), syntax::NodeRole::ListDelimiter);
1031*e038c9c4Sjoerg }
1032*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),
1033*e038c9c4Sjoerg new (allocator()) syntax::NestedNameSpecifier,
1034*e038c9c4Sjoerg QualifierLoc);
1035*e038c9c4Sjoerg return true;
1036*e038c9c4Sjoerg }
1037*e038c9c4Sjoerg
buildIdExpression(NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKeywordLoc,SourceRange UnqualifiedIdLoc,ASTPtr From)1038*e038c9c4Sjoerg syntax::IdExpression *buildIdExpression(NestedNameSpecifierLoc QualifierLoc,
1039*e038c9c4Sjoerg SourceLocation TemplateKeywordLoc,
1040*e038c9c4Sjoerg SourceRange UnqualifiedIdLoc,
1041*e038c9c4Sjoerg ASTPtr From) {
1042*e038c9c4Sjoerg if (QualifierLoc) {
1043*e038c9c4Sjoerg Builder.markChild(QualifierLoc, syntax::NodeRole::Qualifier);
1044*e038c9c4Sjoerg if (TemplateKeywordLoc.isValid())
1045*e038c9c4Sjoerg Builder.markChildToken(TemplateKeywordLoc,
1046*e038c9c4Sjoerg syntax::NodeRole::TemplateKeyword);
1047*e038c9c4Sjoerg }
1048*e038c9c4Sjoerg
1049*e038c9c4Sjoerg auto *TheUnqualifiedId = new (allocator()) syntax::UnqualifiedId;
1050*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1051*e038c9c4Sjoerg nullptr);
1052*e038c9c4Sjoerg Builder.markChild(TheUnqualifiedId, syntax::NodeRole::UnqualifiedId);
1053*e038c9c4Sjoerg
1054*e038c9c4Sjoerg auto IdExpressionBeginLoc =
1055*e038c9c4Sjoerg QualifierLoc ? QualifierLoc.getBeginLoc() : UnqualifiedIdLoc.getBegin();
1056*e038c9c4Sjoerg
1057*e038c9c4Sjoerg auto *TheIdExpression = new (allocator()) syntax::IdExpression;
1058*e038c9c4Sjoerg Builder.foldNode(
1059*e038c9c4Sjoerg Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.getEnd()),
1060*e038c9c4Sjoerg TheIdExpression, From);
1061*e038c9c4Sjoerg
1062*e038c9c4Sjoerg return TheIdExpression;
1063*e038c9c4Sjoerg }
1064*e038c9c4Sjoerg
WalkUpFromMemberExpr(MemberExpr * S)1065*e038c9c4Sjoerg bool WalkUpFromMemberExpr(MemberExpr *S) {
1066*e038c9c4Sjoerg // For `MemberExpr` with implicit `this->` we generate a simple
1067*e038c9c4Sjoerg // `id-expression` syntax node, beacuse an implicit `member-expression` is
1068*e038c9c4Sjoerg // syntactically undistinguishable from an `id-expression`
1069*e038c9c4Sjoerg if (S->isImplicitAccess()) {
1070*e038c9c4Sjoerg buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1071*e038c9c4Sjoerg SourceRange(S->getMemberLoc(), S->getEndLoc()), S);
1072*e038c9c4Sjoerg return true;
1073*e038c9c4Sjoerg }
1074*e038c9c4Sjoerg
1075*e038c9c4Sjoerg auto *TheIdExpression = buildIdExpression(
1076*e038c9c4Sjoerg S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1077*e038c9c4Sjoerg SourceRange(S->getMemberLoc(), S->getEndLoc()), nullptr);
1078*e038c9c4Sjoerg
1079*e038c9c4Sjoerg Builder.markChild(TheIdExpression, syntax::NodeRole::Member);
1080*e038c9c4Sjoerg
1081*e038c9c4Sjoerg Builder.markExprChild(S->getBase(), syntax::NodeRole::Object);
1082*e038c9c4Sjoerg Builder.markChildToken(S->getOperatorLoc(), syntax::NodeRole::AccessToken);
1083*e038c9c4Sjoerg
1084*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1085*e038c9c4Sjoerg new (allocator()) syntax::MemberExpression, S);
1086*e038c9c4Sjoerg return true;
1087*e038c9c4Sjoerg }
1088*e038c9c4Sjoerg
WalkUpFromDeclRefExpr(DeclRefExpr * S)1089*e038c9c4Sjoerg bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
1090*e038c9c4Sjoerg buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1091*e038c9c4Sjoerg SourceRange(S->getLocation(), S->getEndLoc()), S);
1092*e038c9c4Sjoerg
1093*e038c9c4Sjoerg return true;
1094*e038c9c4Sjoerg }
1095*e038c9c4Sjoerg
1096*e038c9c4Sjoerg // Same logic as DeclRefExpr.
WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr * S)1097*e038c9c4Sjoerg bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
1098*e038c9c4Sjoerg buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
1099*e038c9c4Sjoerg SourceRange(S->getLocation(), S->getEndLoc()), S);
1100*e038c9c4Sjoerg
1101*e038c9c4Sjoerg return true;
1102*e038c9c4Sjoerg }
1103*e038c9c4Sjoerg
WalkUpFromCXXThisExpr(CXXThisExpr * S)1104*e038c9c4Sjoerg bool WalkUpFromCXXThisExpr(CXXThisExpr *S) {
1105*e038c9c4Sjoerg if (!S->isImplicit()) {
1106*e038c9c4Sjoerg Builder.markChildToken(S->getLocation(),
1107*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1108*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1109*e038c9c4Sjoerg new (allocator()) syntax::ThisExpression, S);
1110*e038c9c4Sjoerg }
1111*e038c9c4Sjoerg return true;
1112*e038c9c4Sjoerg }
1113*e038c9c4Sjoerg
WalkUpFromParenExpr(ParenExpr * S)1114*e038c9c4Sjoerg bool WalkUpFromParenExpr(ParenExpr *S) {
1115*e038c9c4Sjoerg Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
1116*e038c9c4Sjoerg Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::SubExpression);
1117*e038c9c4Sjoerg Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen);
1118*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1119*e038c9c4Sjoerg new (allocator()) syntax::ParenExpression, S);
1120*e038c9c4Sjoerg return true;
1121*e038c9c4Sjoerg }
1122*e038c9c4Sjoerg
WalkUpFromIntegerLiteral(IntegerLiteral * S)1123*e038c9c4Sjoerg bool WalkUpFromIntegerLiteral(IntegerLiteral *S) {
1124*e038c9c4Sjoerg Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1125*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1126*e038c9c4Sjoerg new (allocator()) syntax::IntegerLiteralExpression, S);
1127*e038c9c4Sjoerg return true;
1128*e038c9c4Sjoerg }
1129*e038c9c4Sjoerg
WalkUpFromCharacterLiteral(CharacterLiteral * S)1130*e038c9c4Sjoerg bool WalkUpFromCharacterLiteral(CharacterLiteral *S) {
1131*e038c9c4Sjoerg Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1132*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1133*e038c9c4Sjoerg new (allocator()) syntax::CharacterLiteralExpression, S);
1134*e038c9c4Sjoerg return true;
1135*e038c9c4Sjoerg }
1136*e038c9c4Sjoerg
WalkUpFromFloatingLiteral(FloatingLiteral * S)1137*e038c9c4Sjoerg bool WalkUpFromFloatingLiteral(FloatingLiteral *S) {
1138*e038c9c4Sjoerg Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1139*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1140*e038c9c4Sjoerg new (allocator()) syntax::FloatingLiteralExpression, S);
1141*e038c9c4Sjoerg return true;
1142*e038c9c4Sjoerg }
1143*e038c9c4Sjoerg
WalkUpFromStringLiteral(StringLiteral * S)1144*e038c9c4Sjoerg bool WalkUpFromStringLiteral(StringLiteral *S) {
1145*e038c9c4Sjoerg Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
1146*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1147*e038c9c4Sjoerg new (allocator()) syntax::StringLiteralExpression, S);
1148*e038c9c4Sjoerg return true;
1149*e038c9c4Sjoerg }
1150*e038c9c4Sjoerg
WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr * S)1151*e038c9c4Sjoerg bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
1152*e038c9c4Sjoerg Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1153*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1154*e038c9c4Sjoerg new (allocator()) syntax::BoolLiteralExpression, S);
1155*e038c9c4Sjoerg return true;
1156*e038c9c4Sjoerg }
1157*e038c9c4Sjoerg
WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr * S)1158*e038c9c4Sjoerg bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
1159*e038c9c4Sjoerg Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
1160*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1161*e038c9c4Sjoerg new (allocator()) syntax::CxxNullPtrExpression, S);
1162*e038c9c4Sjoerg return true;
1163*e038c9c4Sjoerg }
1164*e038c9c4Sjoerg
WalkUpFromUnaryOperator(UnaryOperator * S)1165*e038c9c4Sjoerg bool WalkUpFromUnaryOperator(UnaryOperator *S) {
1166*e038c9c4Sjoerg Builder.markChildToken(S->getOperatorLoc(),
1167*e038c9c4Sjoerg syntax::NodeRole::OperatorToken);
1168*e038c9c4Sjoerg Builder.markExprChild(S->getSubExpr(), syntax::NodeRole::Operand);
1169*e038c9c4Sjoerg
1170*e038c9c4Sjoerg if (S->isPostfix())
1171*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1172*e038c9c4Sjoerg new (allocator()) syntax::PostfixUnaryOperatorExpression,
1173*e038c9c4Sjoerg S);
1174*e038c9c4Sjoerg else
1175*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1176*e038c9c4Sjoerg new (allocator()) syntax::PrefixUnaryOperatorExpression,
1177*e038c9c4Sjoerg S);
1178*e038c9c4Sjoerg
1179*e038c9c4Sjoerg return true;
1180*e038c9c4Sjoerg }
1181*e038c9c4Sjoerg
WalkUpFromBinaryOperator(BinaryOperator * S)1182*e038c9c4Sjoerg bool WalkUpFromBinaryOperator(BinaryOperator *S) {
1183*e038c9c4Sjoerg Builder.markExprChild(S->getLHS(), syntax::NodeRole::LeftHandSide);
1184*e038c9c4Sjoerg Builder.markChildToken(S->getOperatorLoc(),
1185*e038c9c4Sjoerg syntax::NodeRole::OperatorToken);
1186*e038c9c4Sjoerg Builder.markExprChild(S->getRHS(), syntax::NodeRole::RightHandSide);
1187*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1188*e038c9c4Sjoerg new (allocator()) syntax::BinaryOperatorExpression, S);
1189*e038c9c4Sjoerg return true;
1190*e038c9c4Sjoerg }
1191*e038c9c4Sjoerg
1192*e038c9c4Sjoerg /// Builds `CallArguments` syntax node from arguments that appear in source
1193*e038c9c4Sjoerg /// code, i.e. not default arguments.
1194*e038c9c4Sjoerg syntax::CallArguments *
buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs)1195*e038c9c4Sjoerg buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs) {
1196*e038c9c4Sjoerg auto Args = dropDefaultArgs(ArgsAndDefaultArgs);
1197*e038c9c4Sjoerg for (auto *Arg : Args) {
1198*e038c9c4Sjoerg Builder.markExprChild(Arg, syntax::NodeRole::ListElement);
1199*e038c9c4Sjoerg const auto *DelimiterToken =
1200*e038c9c4Sjoerg std::next(Builder.findToken(Arg->getEndLoc()));
1201*e038c9c4Sjoerg if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1202*e038c9c4Sjoerg Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1203*e038c9c4Sjoerg }
1204*e038c9c4Sjoerg
1205*e038c9c4Sjoerg auto *Arguments = new (allocator()) syntax::CallArguments;
1206*e038c9c4Sjoerg if (!Args.empty())
1207*e038c9c4Sjoerg Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1208*e038c9c4Sjoerg (*(Args.end() - 1))->getEndLoc()),
1209*e038c9c4Sjoerg Arguments, nullptr);
1210*e038c9c4Sjoerg
1211*e038c9c4Sjoerg return Arguments;
1212*e038c9c4Sjoerg }
1213*e038c9c4Sjoerg
WalkUpFromCallExpr(CallExpr * S)1214*e038c9c4Sjoerg bool WalkUpFromCallExpr(CallExpr *S) {
1215*e038c9c4Sjoerg Builder.markExprChild(S->getCallee(), syntax::NodeRole::Callee);
1216*e038c9c4Sjoerg
1217*e038c9c4Sjoerg const auto *LParenToken =
1218*e038c9c4Sjoerg std::next(Builder.findToken(S->getCallee()->getEndLoc()));
1219*e038c9c4Sjoerg // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have fixed
1220*e038c9c4Sjoerg // the test on decltype desctructors.
1221*e038c9c4Sjoerg if (LParenToken->kind() == clang::tok::l_paren)
1222*e038c9c4Sjoerg Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
1223*e038c9c4Sjoerg
1224*e038c9c4Sjoerg Builder.markChild(buildCallArguments(S->arguments()),
1225*e038c9c4Sjoerg syntax::NodeRole::Arguments);
1226*e038c9c4Sjoerg
1227*e038c9c4Sjoerg Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
1228*e038c9c4Sjoerg
1229*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(S->getSourceRange()),
1230*e038c9c4Sjoerg new (allocator()) syntax::CallExpression, S);
1231*e038c9c4Sjoerg return true;
1232*e038c9c4Sjoerg }
1233*e038c9c4Sjoerg
WalkUpFromCXXConstructExpr(CXXConstructExpr * S)1234*e038c9c4Sjoerg bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S) {
1235*e038c9c4Sjoerg // Ignore the implicit calls to default constructors.
1236*e038c9c4Sjoerg if ((S->getNumArgs() == 0 || isa<CXXDefaultArgExpr>(S->getArg(0))) &&
1237*e038c9c4Sjoerg S->getParenOrBraceRange().isInvalid())
1238*e038c9c4Sjoerg return true;
1239*e038c9c4Sjoerg return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1240*e038c9c4Sjoerg }
1241*e038c9c4Sjoerg
TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * S)1242*e038c9c4Sjoerg bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
1243*e038c9c4Sjoerg // To construct a syntax tree of the same shape for calls to built-in and
1244*e038c9c4Sjoerg // user-defined operators, ignore the `DeclRefExpr` that refers to the
1245*e038c9c4Sjoerg // operator and treat it as a simple token. Do that by traversing
1246*e038c9c4Sjoerg // arguments instead of children.
1247*e038c9c4Sjoerg for (auto *child : S->arguments()) {
1248*e038c9c4Sjoerg // A postfix unary operator is declared as taking two operands. The
1249*e038c9c4Sjoerg // second operand is used to distinguish from its prefix counterpart. In
1250*e038c9c4Sjoerg // the semantic AST this "phantom" operand is represented as a
1251*e038c9c4Sjoerg // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
1252*e038c9c4Sjoerg // operand because it does not correspond to anything written in source
1253*e038c9c4Sjoerg // code.
1254*e038c9c4Sjoerg if (child->getSourceRange().isInvalid()) {
1255*e038c9c4Sjoerg assert(getOperatorNodeKind(*S) ==
1256*e038c9c4Sjoerg syntax::NodeKind::PostfixUnaryOperatorExpression);
1257*e038c9c4Sjoerg continue;
1258*e038c9c4Sjoerg }
1259*e038c9c4Sjoerg if (!TraverseStmt(child))
1260*e038c9c4Sjoerg return false;
1261*e038c9c4Sjoerg }
1262*e038c9c4Sjoerg return WalkUpFromCXXOperatorCallExpr(S);
1263*e038c9c4Sjoerg }
1264*e038c9c4Sjoerg
WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr * S)1265*e038c9c4Sjoerg bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
1266*e038c9c4Sjoerg switch (getOperatorNodeKind(*S)) {
1267*e038c9c4Sjoerg case syntax::NodeKind::BinaryOperatorExpression:
1268*e038c9c4Sjoerg Builder.markExprChild(S->getArg(0), syntax::NodeRole::LeftHandSide);
1269*e038c9c4Sjoerg Builder.markChildToken(S->getOperatorLoc(),
1270*e038c9c4Sjoerg syntax::NodeRole::OperatorToken);
1271*e038c9c4Sjoerg Builder.markExprChild(S->getArg(1), syntax::NodeRole::RightHandSide);
1272*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1273*e038c9c4Sjoerg new (allocator()) syntax::BinaryOperatorExpression, S);
1274*e038c9c4Sjoerg return true;
1275*e038c9c4Sjoerg case syntax::NodeKind::PrefixUnaryOperatorExpression:
1276*e038c9c4Sjoerg Builder.markChildToken(S->getOperatorLoc(),
1277*e038c9c4Sjoerg syntax::NodeRole::OperatorToken);
1278*e038c9c4Sjoerg Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand);
1279*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1280*e038c9c4Sjoerg new (allocator()) syntax::PrefixUnaryOperatorExpression,
1281*e038c9c4Sjoerg S);
1282*e038c9c4Sjoerg return true;
1283*e038c9c4Sjoerg case syntax::NodeKind::PostfixUnaryOperatorExpression:
1284*e038c9c4Sjoerg Builder.markChildToken(S->getOperatorLoc(),
1285*e038c9c4Sjoerg syntax::NodeRole::OperatorToken);
1286*e038c9c4Sjoerg Builder.markExprChild(S->getArg(0), syntax::NodeRole::Operand);
1287*e038c9c4Sjoerg Builder.foldNode(Builder.getExprRange(S),
1288*e038c9c4Sjoerg new (allocator()) syntax::PostfixUnaryOperatorExpression,
1289*e038c9c4Sjoerg S);
1290*e038c9c4Sjoerg return true;
1291*e038c9c4Sjoerg case syntax::NodeKind::CallExpression: {
1292*e038c9c4Sjoerg Builder.markExprChild(S->getArg(0), syntax::NodeRole::Callee);
1293*e038c9c4Sjoerg
1294*e038c9c4Sjoerg const auto *LParenToken =
1295*e038c9c4Sjoerg std::next(Builder.findToken(S->getArg(0)->getEndLoc()));
1296*e038c9c4Sjoerg // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have
1297*e038c9c4Sjoerg // fixed the test on decltype desctructors.
1298*e038c9c4Sjoerg if (LParenToken->kind() == clang::tok::l_paren)
1299*e038c9c4Sjoerg Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
1300*e038c9c4Sjoerg
1301*e038c9c4Sjoerg Builder.markChild(buildCallArguments(CallExpr::arg_range(
1302*e038c9c4Sjoerg S->arg_begin() + 1, S->arg_end())),
1303*e038c9c4Sjoerg syntax::NodeRole::Arguments);
1304*e038c9c4Sjoerg
1305*e038c9c4Sjoerg Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
1306*e038c9c4Sjoerg
1307*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(S->getSourceRange()),
1308*e038c9c4Sjoerg new (allocator()) syntax::CallExpression, S);
1309*e038c9c4Sjoerg return true;
1310*e038c9c4Sjoerg }
1311*e038c9c4Sjoerg case syntax::NodeKind::UnknownExpression:
1312*e038c9c4Sjoerg return WalkUpFromExpr(S);
1313*e038c9c4Sjoerg default:
1314*e038c9c4Sjoerg llvm_unreachable("getOperatorNodeKind() does not return this value");
1315*e038c9c4Sjoerg }
1316*e038c9c4Sjoerg }
1317*e038c9c4Sjoerg
WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr * S)1318*e038c9c4Sjoerg bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S) { return true; }
1319*e038c9c4Sjoerg
WalkUpFromNamespaceDecl(NamespaceDecl * S)1320*e038c9c4Sjoerg bool WalkUpFromNamespaceDecl(NamespaceDecl *S) {
1321*e038c9c4Sjoerg auto Tokens = Builder.getDeclarationRange(S);
1322*e038c9c4Sjoerg if (Tokens.front().kind() == tok::coloncolon) {
1323*e038c9c4Sjoerg // Handle nested namespace definitions. Those start at '::' token, e.g.
1324*e038c9c4Sjoerg // namespace a^::b {}
1325*e038c9c4Sjoerg // FIXME: build corresponding nodes for the name of this namespace.
1326*e038c9c4Sjoerg return true;
1327*e038c9c4Sjoerg }
1328*e038c9c4Sjoerg Builder.foldNode(Tokens, new (allocator()) syntax::NamespaceDefinition, S);
1329*e038c9c4Sjoerg return true;
1330*e038c9c4Sjoerg }
1331*e038c9c4Sjoerg
1332*e038c9c4Sjoerg // FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test
1333*e038c9c4Sjoerg // results. Find test coverage or remove it.
TraverseParenTypeLoc(ParenTypeLoc L)1334*e038c9c4Sjoerg bool TraverseParenTypeLoc(ParenTypeLoc L) {
1335*e038c9c4Sjoerg // We reverse order of traversal to get the proper syntax structure.
1336*e038c9c4Sjoerg if (!WalkUpFromParenTypeLoc(L))
1337*e038c9c4Sjoerg return false;
1338*e038c9c4Sjoerg return TraverseTypeLoc(L.getInnerLoc());
1339*e038c9c4Sjoerg }
1340*e038c9c4Sjoerg
WalkUpFromParenTypeLoc(ParenTypeLoc L)1341*e038c9c4Sjoerg bool WalkUpFromParenTypeLoc(ParenTypeLoc L) {
1342*e038c9c4Sjoerg Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
1343*e038c9c4Sjoerg Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
1344*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getRParenLoc()),
1345*e038c9c4Sjoerg new (allocator()) syntax::ParenDeclarator, L);
1346*e038c9c4Sjoerg return true;
1347*e038c9c4Sjoerg }
1348*e038c9c4Sjoerg
1349*e038c9c4Sjoerg // Declarator chunks, they are produced by type locs and some clang::Decls.
WalkUpFromArrayTypeLoc(ArrayTypeLoc L)1350*e038c9c4Sjoerg bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L) {
1351*e038c9c4Sjoerg Builder.markChildToken(L.getLBracketLoc(), syntax::NodeRole::OpenParen);
1352*e038c9c4Sjoerg Builder.markExprChild(L.getSizeExpr(), syntax::NodeRole::Size);
1353*e038c9c4Sjoerg Builder.markChildToken(L.getRBracketLoc(), syntax::NodeRole::CloseParen);
1354*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(L.getLBracketLoc(), L.getRBracketLoc()),
1355*e038c9c4Sjoerg new (allocator()) syntax::ArraySubscript, L);
1356*e038c9c4Sjoerg return true;
1357*e038c9c4Sjoerg }
1358*e038c9c4Sjoerg
1359*e038c9c4Sjoerg syntax::ParameterDeclarationList *
buildParameterDeclarationList(ArrayRef<ParmVarDecl * > Params)1360*e038c9c4Sjoerg buildParameterDeclarationList(ArrayRef<ParmVarDecl *> Params) {
1361*e038c9c4Sjoerg for (auto *P : Params) {
1362*e038c9c4Sjoerg Builder.markChild(P, syntax::NodeRole::ListElement);
1363*e038c9c4Sjoerg const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1364*e038c9c4Sjoerg if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1365*e038c9c4Sjoerg Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1366*e038c9c4Sjoerg }
1367*e038c9c4Sjoerg auto *Parameters = new (allocator()) syntax::ParameterDeclarationList;
1368*e038c9c4Sjoerg if (!Params.empty())
1369*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1370*e038c9c4Sjoerg Params.back()->getEndLoc()),
1371*e038c9c4Sjoerg Parameters, nullptr);
1372*e038c9c4Sjoerg return Parameters;
1373*e038c9c4Sjoerg }
1374*e038c9c4Sjoerg
WalkUpFromFunctionTypeLoc(FunctionTypeLoc L)1375*e038c9c4Sjoerg bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) {
1376*e038c9c4Sjoerg Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
1377*e038c9c4Sjoerg
1378*e038c9c4Sjoerg Builder.markChild(buildParameterDeclarationList(L.getParams()),
1379*e038c9c4Sjoerg syntax::NodeRole::Parameters);
1380*e038c9c4Sjoerg
1381*e038c9c4Sjoerg Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
1382*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()),
1383*e038c9c4Sjoerg new (allocator()) syntax::ParametersAndQualifiers, L);
1384*e038c9c4Sjoerg return true;
1385*e038c9c4Sjoerg }
1386*e038c9c4Sjoerg
WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L)1387*e038c9c4Sjoerg bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L) {
1388*e038c9c4Sjoerg if (!L.getTypePtr()->hasTrailingReturn())
1389*e038c9c4Sjoerg return WalkUpFromFunctionTypeLoc(L);
1390*e038c9c4Sjoerg
1391*e038c9c4Sjoerg auto *TrailingReturnTokens = buildTrailingReturn(L);
1392*e038c9c4Sjoerg // Finish building the node for parameters.
1393*e038c9c4Sjoerg Builder.markChild(TrailingReturnTokens, syntax::NodeRole::TrailingReturn);
1394*e038c9c4Sjoerg return WalkUpFromFunctionTypeLoc(L);
1395*e038c9c4Sjoerg }
1396*e038c9c4Sjoerg
TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L)1397*e038c9c4Sjoerg bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) {
1398*e038c9c4Sjoerg // In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds
1399*e038c9c4Sjoerg // to "Y::*" but it points to a `ParenTypeLoc` that corresponds to
1400*e038c9c4Sjoerg // "(Y::*mp)" We thus reverse the order of traversal to get the proper
1401*e038c9c4Sjoerg // syntax structure.
1402*e038c9c4Sjoerg if (!WalkUpFromMemberPointerTypeLoc(L))
1403*e038c9c4Sjoerg return false;
1404*e038c9c4Sjoerg return TraverseTypeLoc(L.getPointeeLoc());
1405*e038c9c4Sjoerg }
1406*e038c9c4Sjoerg
WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L)1407*e038c9c4Sjoerg bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) {
1408*e038c9c4Sjoerg auto SR = L.getLocalSourceRange();
1409*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(SR),
1410*e038c9c4Sjoerg new (allocator()) syntax::MemberPointer, L);
1411*e038c9c4Sjoerg return true;
1412*e038c9c4Sjoerg }
1413*e038c9c4Sjoerg
1414*e038c9c4Sjoerg // The code below is very regular, it could even be generated with some
1415*e038c9c4Sjoerg // preprocessor magic. We merely assign roles to the corresponding children
1416*e038c9c4Sjoerg // and fold resulting nodes.
WalkUpFromDeclStmt(DeclStmt * S)1417*e038c9c4Sjoerg bool WalkUpFromDeclStmt(DeclStmt *S) {
1418*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1419*e038c9c4Sjoerg new (allocator()) syntax::DeclarationStatement, S);
1420*e038c9c4Sjoerg return true;
1421*e038c9c4Sjoerg }
1422*e038c9c4Sjoerg
WalkUpFromNullStmt(NullStmt * S)1423*e038c9c4Sjoerg bool WalkUpFromNullStmt(NullStmt *S) {
1424*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1425*e038c9c4Sjoerg new (allocator()) syntax::EmptyStatement, S);
1426*e038c9c4Sjoerg return true;
1427*e038c9c4Sjoerg }
1428*e038c9c4Sjoerg
WalkUpFromSwitchStmt(SwitchStmt * S)1429*e038c9c4Sjoerg bool WalkUpFromSwitchStmt(SwitchStmt *S) {
1430*e038c9c4Sjoerg Builder.markChildToken(S->getSwitchLoc(),
1431*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1432*e038c9c4Sjoerg Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1433*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1434*e038c9c4Sjoerg new (allocator()) syntax::SwitchStatement, S);
1435*e038c9c4Sjoerg return true;
1436*e038c9c4Sjoerg }
1437*e038c9c4Sjoerg
WalkUpFromCaseStmt(CaseStmt * S)1438*e038c9c4Sjoerg bool WalkUpFromCaseStmt(CaseStmt *S) {
1439*e038c9c4Sjoerg Builder.markChildToken(S->getKeywordLoc(),
1440*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1441*e038c9c4Sjoerg Builder.markExprChild(S->getLHS(), syntax::NodeRole::CaseValue);
1442*e038c9c4Sjoerg Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement);
1443*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1444*e038c9c4Sjoerg new (allocator()) syntax::CaseStatement, S);
1445*e038c9c4Sjoerg return true;
1446*e038c9c4Sjoerg }
1447*e038c9c4Sjoerg
WalkUpFromDefaultStmt(DefaultStmt * S)1448*e038c9c4Sjoerg bool WalkUpFromDefaultStmt(DefaultStmt *S) {
1449*e038c9c4Sjoerg Builder.markChildToken(S->getKeywordLoc(),
1450*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1451*e038c9c4Sjoerg Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement);
1452*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1453*e038c9c4Sjoerg new (allocator()) syntax::DefaultStatement, S);
1454*e038c9c4Sjoerg return true;
1455*e038c9c4Sjoerg }
1456*e038c9c4Sjoerg
WalkUpFromIfStmt(IfStmt * S)1457*e038c9c4Sjoerg bool WalkUpFromIfStmt(IfStmt *S) {
1458*e038c9c4Sjoerg Builder.markChildToken(S->getIfLoc(), syntax::NodeRole::IntroducerKeyword);
1459*e038c9c4Sjoerg Stmt *ConditionStatement = S->getCond();
1460*e038c9c4Sjoerg if (S->hasVarStorage())
1461*e038c9c4Sjoerg ConditionStatement = S->getConditionVariableDeclStmt();
1462*e038c9c4Sjoerg Builder.markStmtChild(ConditionStatement, syntax::NodeRole::Condition);
1463*e038c9c4Sjoerg Builder.markStmtChild(S->getThen(), syntax::NodeRole::ThenStatement);
1464*e038c9c4Sjoerg Builder.markChildToken(S->getElseLoc(), syntax::NodeRole::ElseKeyword);
1465*e038c9c4Sjoerg Builder.markStmtChild(S->getElse(), syntax::NodeRole::ElseStatement);
1466*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1467*e038c9c4Sjoerg new (allocator()) syntax::IfStatement, S);
1468*e038c9c4Sjoerg return true;
1469*e038c9c4Sjoerg }
1470*e038c9c4Sjoerg
WalkUpFromForStmt(ForStmt * S)1471*e038c9c4Sjoerg bool WalkUpFromForStmt(ForStmt *S) {
1472*e038c9c4Sjoerg Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword);
1473*e038c9c4Sjoerg Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1474*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1475*e038c9c4Sjoerg new (allocator()) syntax::ForStatement, S);
1476*e038c9c4Sjoerg return true;
1477*e038c9c4Sjoerg }
1478*e038c9c4Sjoerg
WalkUpFromWhileStmt(WhileStmt * S)1479*e038c9c4Sjoerg bool WalkUpFromWhileStmt(WhileStmt *S) {
1480*e038c9c4Sjoerg Builder.markChildToken(S->getWhileLoc(),
1481*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1482*e038c9c4Sjoerg Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1483*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1484*e038c9c4Sjoerg new (allocator()) syntax::WhileStatement, S);
1485*e038c9c4Sjoerg return true;
1486*e038c9c4Sjoerg }
1487*e038c9c4Sjoerg
WalkUpFromContinueStmt(ContinueStmt * S)1488*e038c9c4Sjoerg bool WalkUpFromContinueStmt(ContinueStmt *S) {
1489*e038c9c4Sjoerg Builder.markChildToken(S->getContinueLoc(),
1490*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1491*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1492*e038c9c4Sjoerg new (allocator()) syntax::ContinueStatement, S);
1493*e038c9c4Sjoerg return true;
1494*e038c9c4Sjoerg }
1495*e038c9c4Sjoerg
WalkUpFromBreakStmt(BreakStmt * S)1496*e038c9c4Sjoerg bool WalkUpFromBreakStmt(BreakStmt *S) {
1497*e038c9c4Sjoerg Builder.markChildToken(S->getBreakLoc(),
1498*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1499*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1500*e038c9c4Sjoerg new (allocator()) syntax::BreakStatement, S);
1501*e038c9c4Sjoerg return true;
1502*e038c9c4Sjoerg }
1503*e038c9c4Sjoerg
WalkUpFromReturnStmt(ReturnStmt * S)1504*e038c9c4Sjoerg bool WalkUpFromReturnStmt(ReturnStmt *S) {
1505*e038c9c4Sjoerg Builder.markChildToken(S->getReturnLoc(),
1506*e038c9c4Sjoerg syntax::NodeRole::IntroducerKeyword);
1507*e038c9c4Sjoerg Builder.markExprChild(S->getRetValue(), syntax::NodeRole::ReturnValue);
1508*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1509*e038c9c4Sjoerg new (allocator()) syntax::ReturnStatement, S);
1510*e038c9c4Sjoerg return true;
1511*e038c9c4Sjoerg }
1512*e038c9c4Sjoerg
WalkUpFromCXXForRangeStmt(CXXForRangeStmt * S)1513*e038c9c4Sjoerg bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S) {
1514*e038c9c4Sjoerg Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword);
1515*e038c9c4Sjoerg Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement);
1516*e038c9c4Sjoerg Builder.foldNode(Builder.getStmtRange(S),
1517*e038c9c4Sjoerg new (allocator()) syntax::RangeBasedForStatement, S);
1518*e038c9c4Sjoerg return true;
1519*e038c9c4Sjoerg }
1520*e038c9c4Sjoerg
WalkUpFromEmptyDecl(EmptyDecl * S)1521*e038c9c4Sjoerg bool WalkUpFromEmptyDecl(EmptyDecl *S) {
1522*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1523*e038c9c4Sjoerg new (allocator()) syntax::EmptyDeclaration, S);
1524*e038c9c4Sjoerg return true;
1525*e038c9c4Sjoerg }
1526*e038c9c4Sjoerg
WalkUpFromStaticAssertDecl(StaticAssertDecl * S)1527*e038c9c4Sjoerg bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S) {
1528*e038c9c4Sjoerg Builder.markExprChild(S->getAssertExpr(), syntax::NodeRole::Condition);
1529*e038c9c4Sjoerg Builder.markExprChild(S->getMessage(), syntax::NodeRole::Message);
1530*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1531*e038c9c4Sjoerg new (allocator()) syntax::StaticAssertDeclaration, S);
1532*e038c9c4Sjoerg return true;
1533*e038c9c4Sjoerg }
1534*e038c9c4Sjoerg
WalkUpFromLinkageSpecDecl(LinkageSpecDecl * S)1535*e038c9c4Sjoerg bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) {
1536*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1537*e038c9c4Sjoerg new (allocator()) syntax::LinkageSpecificationDeclaration,
1538*e038c9c4Sjoerg S);
1539*e038c9c4Sjoerg return true;
1540*e038c9c4Sjoerg }
1541*e038c9c4Sjoerg
WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl * S)1542*e038c9c4Sjoerg bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) {
1543*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1544*e038c9c4Sjoerg new (allocator()) syntax::NamespaceAliasDefinition, S);
1545*e038c9c4Sjoerg return true;
1546*e038c9c4Sjoerg }
1547*e038c9c4Sjoerg
WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl * S)1548*e038c9c4Sjoerg bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) {
1549*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1550*e038c9c4Sjoerg new (allocator()) syntax::UsingNamespaceDirective, S);
1551*e038c9c4Sjoerg return true;
1552*e038c9c4Sjoerg }
1553*e038c9c4Sjoerg
WalkUpFromUsingDecl(UsingDecl * S)1554*e038c9c4Sjoerg bool WalkUpFromUsingDecl(UsingDecl *S) {
1555*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1556*e038c9c4Sjoerg new (allocator()) syntax::UsingDeclaration, S);
1557*e038c9c4Sjoerg return true;
1558*e038c9c4Sjoerg }
1559*e038c9c4Sjoerg
WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * S)1560*e038c9c4Sjoerg bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) {
1561*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1562*e038c9c4Sjoerg new (allocator()) syntax::UsingDeclaration, S);
1563*e038c9c4Sjoerg return true;
1564*e038c9c4Sjoerg }
1565*e038c9c4Sjoerg
WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * S)1566*e038c9c4Sjoerg bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) {
1567*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1568*e038c9c4Sjoerg new (allocator()) syntax::UsingDeclaration, S);
1569*e038c9c4Sjoerg return true;
1570*e038c9c4Sjoerg }
1571*e038c9c4Sjoerg
WalkUpFromTypeAliasDecl(TypeAliasDecl * S)1572*e038c9c4Sjoerg bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) {
1573*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(S),
1574*e038c9c4Sjoerg new (allocator()) syntax::TypeAliasDeclaration, S);
15757330f729Sjoerg return true;
15767330f729Sjoerg }
15777330f729Sjoerg
15787330f729Sjoerg private:
1579*e038c9c4Sjoerg /// Folds SimpleDeclarator node (if present) and in case this is the last
1580*e038c9c4Sjoerg /// declarator in the chain it also folds SimpleDeclaration node.
processDeclaratorAndDeclaration(T * D)1581*e038c9c4Sjoerg template <class T> bool processDeclaratorAndDeclaration(T *D) {
1582*e038c9c4Sjoerg auto Range = getDeclaratorRange(
1583*e038c9c4Sjoerg Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1584*e038c9c4Sjoerg getQualifiedNameStart(D), getInitializerRange(D));
1585*e038c9c4Sjoerg
1586*e038c9c4Sjoerg // There doesn't have to be a declarator (e.g. `void foo(int)` only has
1587*e038c9c4Sjoerg // declaration, but no declarator).
1588*e038c9c4Sjoerg if (!Range.getBegin().isValid()) {
1589*e038c9c4Sjoerg Builder.markChild(new (allocator()) syntax::DeclaratorList,
1590*e038c9c4Sjoerg syntax::NodeRole::Declarators);
1591*e038c9c4Sjoerg Builder.foldNode(Builder.getDeclarationRange(D),
1592*e038c9c4Sjoerg new (allocator()) syntax::SimpleDeclaration, D);
1593*e038c9c4Sjoerg return true;
1594*e038c9c4Sjoerg }
1595*e038c9c4Sjoerg
1596*e038c9c4Sjoerg auto *N = new (allocator()) syntax::SimpleDeclarator;
1597*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(Range), N, nullptr);
1598*e038c9c4Sjoerg Builder.markChild(N, syntax::NodeRole::ListElement);
1599*e038c9c4Sjoerg
1600*e038c9c4Sjoerg if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1601*e038c9c4Sjoerg // If this is not the last declarator in the declaration we expect a
1602*e038c9c4Sjoerg // delimiter after it.
1603*e038c9c4Sjoerg const auto *DelimiterToken = std::next(Builder.findToken(Range.getEnd()));
1604*e038c9c4Sjoerg if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1605*e038c9c4Sjoerg Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1606*e038c9c4Sjoerg } else {
1607*e038c9c4Sjoerg auto *DL = new (allocator()) syntax::DeclaratorList;
1608*e038c9c4Sjoerg auto DeclarationRange = Builder.getDeclarationRange(D);
1609*e038c9c4Sjoerg Builder.foldList(DeclarationRange, DL, nullptr);
1610*e038c9c4Sjoerg
1611*e038c9c4Sjoerg Builder.markChild(DL, syntax::NodeRole::Declarators);
1612*e038c9c4Sjoerg Builder.foldNode(DeclarationRange,
1613*e038c9c4Sjoerg new (allocator()) syntax::SimpleDeclaration, D);
1614*e038c9c4Sjoerg }
1615*e038c9c4Sjoerg return true;
1616*e038c9c4Sjoerg }
1617*e038c9c4Sjoerg
1618*e038c9c4Sjoerg /// Returns the range of the built node.
buildTrailingReturn(FunctionProtoTypeLoc L)1619*e038c9c4Sjoerg syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1620*e038c9c4Sjoerg assert(L.getTypePtr()->hasTrailingReturn());
1621*e038c9c4Sjoerg
1622*e038c9c4Sjoerg auto ReturnedType = L.getReturnLoc();
1623*e038c9c4Sjoerg // Build node for the declarator, if any.
1624*e038c9c4Sjoerg auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1625*e038c9c4Sjoerg ReturnedType.getEndLoc());
1626*e038c9c4Sjoerg syntax::SimpleDeclarator *ReturnDeclarator = nullptr;
1627*e038c9c4Sjoerg if (ReturnDeclaratorRange.isValid()) {
1628*e038c9c4Sjoerg ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator;
1629*e038c9c4Sjoerg Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1630*e038c9c4Sjoerg ReturnDeclarator, nullptr);
1631*e038c9c4Sjoerg }
1632*e038c9c4Sjoerg
1633*e038c9c4Sjoerg // Build node for trailing return type.
1634*e038c9c4Sjoerg auto Return = Builder.getRange(ReturnedType.getSourceRange());
1635*e038c9c4Sjoerg const auto *Arrow = Return.begin() - 1;
1636*e038c9c4Sjoerg assert(Arrow->kind() == tok::arrow);
1637*e038c9c4Sjoerg auto Tokens = llvm::makeArrayRef(Arrow, Return.end());
1638*e038c9c4Sjoerg Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1639*e038c9c4Sjoerg if (ReturnDeclarator)
1640*e038c9c4Sjoerg Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1641*e038c9c4Sjoerg auto *R = new (allocator()) syntax::TrailingReturnType;
1642*e038c9c4Sjoerg Builder.foldNode(Tokens, R, L);
1643*e038c9c4Sjoerg return R;
1644*e038c9c4Sjoerg }
1645*e038c9c4Sjoerg
foldExplicitTemplateInstantiation(ArrayRef<syntax::Token> Range,const syntax::Token * ExternKW,const syntax::Token * TemplateKW,syntax::SimpleDeclaration * InnerDeclaration,Decl * From)1646*e038c9c4Sjoerg void foldExplicitTemplateInstantiation(
1647*e038c9c4Sjoerg ArrayRef<syntax::Token> Range, const syntax::Token *ExternKW,
1648*e038c9c4Sjoerg const syntax::Token *TemplateKW,
1649*e038c9c4Sjoerg syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1650*e038c9c4Sjoerg assert(!ExternKW || ExternKW->kind() == tok::kw_extern);
1651*e038c9c4Sjoerg assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
1652*e038c9c4Sjoerg Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1653*e038c9c4Sjoerg Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1654*e038c9c4Sjoerg Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1655*e038c9c4Sjoerg Builder.foldNode(
1656*e038c9c4Sjoerg Range, new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1657*e038c9c4Sjoerg }
1658*e038c9c4Sjoerg
foldTemplateDeclaration(ArrayRef<syntax::Token> Range,const syntax::Token * TemplateKW,ArrayRef<syntax::Token> TemplatedDeclaration,Decl * From)1659*e038c9c4Sjoerg syntax::TemplateDeclaration *foldTemplateDeclaration(
1660*e038c9c4Sjoerg ArrayRef<syntax::Token> Range, const syntax::Token *TemplateKW,
1661*e038c9c4Sjoerg ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1662*e038c9c4Sjoerg assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
1663*e038c9c4Sjoerg Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1664*e038c9c4Sjoerg
1665*e038c9c4Sjoerg auto *N = new (allocator()) syntax::TemplateDeclaration;
1666*e038c9c4Sjoerg Builder.foldNode(Range, N, From);
1667*e038c9c4Sjoerg Builder.markChild(N, syntax::NodeRole::Declaration);
1668*e038c9c4Sjoerg return N;
1669*e038c9c4Sjoerg }
1670*e038c9c4Sjoerg
16717330f729Sjoerg /// A small helper to save some typing.
allocator()16727330f729Sjoerg llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); }
16737330f729Sjoerg
16747330f729Sjoerg syntax::TreeBuilder &Builder;
1675*e038c9c4Sjoerg const ASTContext &Context;
16767330f729Sjoerg };
16777330f729Sjoerg } // namespace
16787330f729Sjoerg
noticeDeclWithoutSemicolon(Decl * D)1679*e038c9c4Sjoerg void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) {
1680*e038c9c4Sjoerg DeclsWithoutSemicolons.insert(D);
16817330f729Sjoerg }
16827330f729Sjoerg
markChildToken(SourceLocation Loc,NodeRole Role)1683*e038c9c4Sjoerg void syntax::TreeBuilder::markChildToken(SourceLocation Loc, NodeRole Role) {
16847330f729Sjoerg if (Loc.isInvalid())
16857330f729Sjoerg return;
16867330f729Sjoerg Pending.assignRole(*findToken(Loc), Role);
16877330f729Sjoerg }
16887330f729Sjoerg
markChildToken(const syntax::Token * T,NodeRole R)1689*e038c9c4Sjoerg void syntax::TreeBuilder::markChildToken(const syntax::Token *T, NodeRole R) {
1690*e038c9c4Sjoerg if (!T)
1691*e038c9c4Sjoerg return;
1692*e038c9c4Sjoerg Pending.assignRole(*T, R);
16937330f729Sjoerg }
16947330f729Sjoerg
markChild(syntax::Node * N,NodeRole R)1695*e038c9c4Sjoerg void syntax::TreeBuilder::markChild(syntax::Node *N, NodeRole R) {
1696*e038c9c4Sjoerg assert(N);
1697*e038c9c4Sjoerg setRole(N, R);
1698*e038c9c4Sjoerg }
1699*e038c9c4Sjoerg
markChild(ASTPtr N,NodeRole R)1700*e038c9c4Sjoerg void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1701*e038c9c4Sjoerg auto *SN = Mapping.find(N);
1702*e038c9c4Sjoerg assert(SN != nullptr);
1703*e038c9c4Sjoerg setRole(SN, R);
1704*e038c9c4Sjoerg }
markChild(NestedNameSpecifierLoc NNSLoc,NodeRole R)1705*e038c9c4Sjoerg void syntax::TreeBuilder::markChild(NestedNameSpecifierLoc NNSLoc, NodeRole R) {
1706*e038c9c4Sjoerg auto *SN = Mapping.find(NNSLoc);
1707*e038c9c4Sjoerg assert(SN != nullptr);
1708*e038c9c4Sjoerg setRole(SN, R);
1709*e038c9c4Sjoerg }
1710*e038c9c4Sjoerg
markStmtChild(Stmt * Child,NodeRole Role)1711*e038c9c4Sjoerg void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) {
1712*e038c9c4Sjoerg if (!Child)
1713*e038c9c4Sjoerg return;
1714*e038c9c4Sjoerg
1715*e038c9c4Sjoerg syntax::Tree *ChildNode;
1716*e038c9c4Sjoerg if (Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1717*e038c9c4Sjoerg // This is an expression in a statement position, consume the trailing
1718*e038c9c4Sjoerg // semicolon and form an 'ExpressionStatement' node.
1719*e038c9c4Sjoerg markExprChild(ChildExpr, NodeRole::Expression);
1720*e038c9c4Sjoerg ChildNode = new (allocator()) syntax::ExpressionStatement;
1721*e038c9c4Sjoerg // (!) 'getStmtRange()' ensures this covers a trailing semicolon.
1722*e038c9c4Sjoerg Pending.foldChildren(Arena, getStmtRange(Child), ChildNode);
1723*e038c9c4Sjoerg } else {
1724*e038c9c4Sjoerg ChildNode = Mapping.find(Child);
1725*e038c9c4Sjoerg }
1726*e038c9c4Sjoerg assert(ChildNode != nullptr);
1727*e038c9c4Sjoerg setRole(ChildNode, Role);
1728*e038c9c4Sjoerg }
1729*e038c9c4Sjoerg
markExprChild(Expr * Child,NodeRole Role)1730*e038c9c4Sjoerg void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) {
1731*e038c9c4Sjoerg if (!Child)
1732*e038c9c4Sjoerg return;
1733*e038c9c4Sjoerg Child = IgnoreImplicit(Child);
1734*e038c9c4Sjoerg
1735*e038c9c4Sjoerg syntax::Tree *ChildNode = Mapping.find(Child);
1736*e038c9c4Sjoerg assert(ChildNode != nullptr);
1737*e038c9c4Sjoerg setRole(ChildNode, Role);
1738*e038c9c4Sjoerg }
1739*e038c9c4Sjoerg
findToken(SourceLocation L) const1740*e038c9c4Sjoerg const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const {
1741*e038c9c4Sjoerg if (L.isInvalid())
1742*e038c9c4Sjoerg return nullptr;
1743*e038c9c4Sjoerg auto It = LocationToToken.find(L);
1744*e038c9c4Sjoerg assert(It != LocationToToken.end());
1745*e038c9c4Sjoerg return It->second;
1746*e038c9c4Sjoerg }
1747*e038c9c4Sjoerg
buildSyntaxTree(Arena & A,ASTContext & Context)1748*e038c9c4Sjoerg syntax::TranslationUnit *syntax::buildSyntaxTree(Arena &A,
1749*e038c9c4Sjoerg ASTContext &Context) {
17507330f729Sjoerg TreeBuilder Builder(A);
1751*e038c9c4Sjoerg BuildTreeVisitor(Context, Builder).TraverseAST(Context);
17527330f729Sjoerg return std::move(Builder).finalize();
17537330f729Sjoerg }
1754