1 //===- BuildTree.cpp ------------------------------------------*- C++ -*-=====// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #include "clang/Tooling/Syntax/BuildTree.h" 9 #include "clang/AST/ASTFwd.h" 10 #include "clang/AST/Decl.h" 11 #include "clang/AST/DeclBase.h" 12 #include "clang/AST/DeclCXX.h" 13 #include "clang/AST/DeclarationName.h" 14 #include "clang/AST/Expr.h" 15 #include "clang/AST/RecursiveASTVisitor.h" 16 #include "clang/AST/Stmt.h" 17 #include "clang/AST/TypeLoc.h" 18 #include "clang/AST/TypeLocVisitor.h" 19 #include "clang/Basic/LLVM.h" 20 #include "clang/Basic/SourceLocation.h" 21 #include "clang/Basic/SourceManager.h" 22 #include "clang/Basic/Specifiers.h" 23 #include "clang/Basic/TokenKinds.h" 24 #include "clang/Lex/Lexer.h" 25 #include "clang/Tooling/Syntax/Nodes.h" 26 #include "clang/Tooling/Syntax/Tokens.h" 27 #include "clang/Tooling/Syntax/Tree.h" 28 #include "llvm/ADT/ArrayRef.h" 29 #include "llvm/ADT/DenseMap.h" 30 #include "llvm/ADT/PointerUnion.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/ADT/ScopeExit.h" 33 #include "llvm/ADT/SmallVector.h" 34 #include "llvm/Support/Allocator.h" 35 #include "llvm/Support/Casting.h" 36 #include "llvm/Support/Compiler.h" 37 #include "llvm/Support/FormatVariadic.h" 38 #include "llvm/Support/MemoryBuffer.h" 39 #include "llvm/Support/raw_ostream.h" 40 #include <cstddef> 41 #include <map> 42 43 using namespace clang; 44 45 LLVM_ATTRIBUTE_UNUSED 46 static bool isImplicitExpr(clang::Expr *E) { return E->IgnoreImplicit() != E; } 47 48 namespace { 49 /// Get start location of the Declarator from the TypeLoc. 50 /// E.g.: 51 /// loc of `(` in `int (a)` 52 /// loc of `*` in `int *(a)` 53 /// loc of the first `(` in `int (*a)(int)` 54 /// loc of the `*` in `int *(a)(int)` 55 /// loc of the first `*` in `const int *const *volatile a;` 56 /// 57 /// It is non-trivial to get the start location because TypeLocs are stored 58 /// inside out. In the example above `*volatile` is the TypeLoc returned 59 /// by `Decl.getTypeSourceInfo()`, and `*const` is what `.getPointeeLoc()` 60 /// returns. 61 struct GetStartLoc : TypeLocVisitor<GetStartLoc, SourceLocation> { 62 SourceLocation VisitParenTypeLoc(ParenTypeLoc T) { 63 auto L = Visit(T.getInnerLoc()); 64 if (L.isValid()) 65 return L; 66 return T.getLParenLoc(); 67 } 68 69 // Types spelled in the prefix part of the declarator. 70 SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) { 71 return HandlePointer(T); 72 } 73 74 SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) { 75 return HandlePointer(T); 76 } 77 78 SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) { 79 return HandlePointer(T); 80 } 81 82 SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) { 83 return HandlePointer(T); 84 } 85 86 SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) { 87 return HandlePointer(T); 88 } 89 90 // All other cases are not important, as they are either part of declaration 91 // specifiers (e.g. inheritors of TypeSpecTypeLoc) or introduce modifiers on 92 // existing declarators (e.g. QualifiedTypeLoc). They cannot start the 93 // declarator themselves, but their underlying type can. 94 SourceLocation VisitTypeLoc(TypeLoc T) { 95 auto N = T.getNextTypeLoc(); 96 if (!N) 97 return SourceLocation(); 98 return Visit(N); 99 } 100 101 SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) { 102 if (T.getTypePtr()->hasTrailingReturn()) 103 return SourceLocation(); // avoid recursing into the suffix of declarator. 104 return VisitTypeLoc(T); 105 } 106 107 private: 108 template <class PtrLoc> SourceLocation HandlePointer(PtrLoc T) { 109 auto L = Visit(T.getPointeeLoc()); 110 if (L.isValid()) 111 return L; 112 return T.getLocalSourceRange().getBegin(); 113 } 114 }; 115 } // namespace 116 117 /// Gets the range of declarator as defined by the C++ grammar. E.g. 118 /// `int a;` -> range of `a`, 119 /// `int *a;` -> range of `*a`, 120 /// `int a[10];` -> range of `a[10]`, 121 /// `int a[1][2][3];` -> range of `a[1][2][3]`, 122 /// `int *a = nullptr` -> range of `*a = nullptr`. 123 /// FIMXE: \p Name must be a source range, e.g. for `operator+`. 124 static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T, 125 SourceLocation Name, 126 SourceRange Initializer) { 127 SourceLocation Start = GetStartLoc().Visit(T); 128 SourceLocation End = T.getSourceRange().getEnd(); 129 assert(End.isValid()); 130 if (Name.isValid()) { 131 if (Start.isInvalid()) 132 Start = Name; 133 if (SM.isBeforeInTranslationUnit(End, Name)) 134 End = Name; 135 } 136 if (Initializer.isValid()) { 137 auto InitializerEnd = Initializer.getEnd(); 138 assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) || End == InitializerEnd); 139 End = InitializerEnd; 140 } 141 return SourceRange(Start, End); 142 } 143 144 namespace { 145 /// All AST hierarchy roots that can be represented as pointers. 146 using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>; 147 /// Maintains a mapping from AST to syntax tree nodes. This class will get more 148 /// complicated as we support more kinds of AST nodes, e.g. TypeLocs. 149 /// FIXME: expose this as public API. 150 class ASTToSyntaxMapping { 151 public: 152 void add(ASTPtr From, syntax::Tree *To) { 153 assert(To != nullptr); 154 assert(!From.isNull()); 155 156 bool Added = Nodes.insert({From, To}).second; 157 (void)Added; 158 assert(Added && "mapping added twice"); 159 } 160 161 syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); } 162 163 private: 164 llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes; 165 }; 166 } // namespace 167 168 /// A helper class for constructing the syntax tree while traversing a clang 169 /// AST. 170 /// 171 /// At each point of the traversal we maintain a list of pending nodes. 172 /// Initially all tokens are added as pending nodes. When processing a clang AST 173 /// node, the clients need to: 174 /// - create a corresponding syntax node, 175 /// - assign roles to all pending child nodes with 'markChild' and 176 /// 'markChildToken', 177 /// - replace the child nodes with the new syntax node in the pending list 178 /// with 'foldNode'. 179 /// 180 /// Note that all children are expected to be processed when building a node. 181 /// 182 /// Call finalize() to finish building the tree and consume the root node. 183 class syntax::TreeBuilder { 184 public: 185 TreeBuilder(syntax::Arena &Arena) : Arena(Arena), Pending(Arena) { 186 for (const auto &T : Arena.tokenBuffer().expandedTokens()) 187 LocationToToken.insert({T.location().getRawEncoding(), &T}); 188 } 189 190 llvm::BumpPtrAllocator &allocator() { return Arena.allocator(); } 191 const SourceManager &sourceManager() const { return Arena.sourceManager(); } 192 193 /// Populate children for \p New node, assuming it covers tokens from \p 194 /// Range. 195 void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New, 196 ASTPtr From) { 197 assert(New); 198 Pending.foldChildren(Arena, Range, New); 199 if (From) 200 Mapping.add(From, New); 201 } 202 void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *New, 203 TypeLoc L) { 204 // FIXME: add mapping for TypeLocs 205 foldNode(Range, New, nullptr); 206 } 207 208 /// Notifies that we should not consume trailing semicolon when computing 209 /// token range of \p D. 210 void noticeDeclWithoutSemicolon(Decl *D); 211 212 /// Mark the \p Child node with a corresponding \p Role. All marked children 213 /// should be consumed by foldNode. 214 /// When called on expressions (clang::Expr is derived from clang::Stmt), 215 /// wraps expressions into expression statement. 216 void markStmtChild(Stmt *Child, NodeRole Role); 217 /// Should be called for expressions in non-statement position to avoid 218 /// wrapping into expression statement. 219 void markExprChild(Expr *Child, NodeRole Role); 220 /// Set role for a token starting at \p Loc. 221 void markChildToken(SourceLocation Loc, NodeRole R); 222 /// Set role for \p T. 223 void markChildToken(const syntax::Token *T, NodeRole R); 224 225 /// Set role for \p N. 226 void markChild(syntax::Node *N, NodeRole R); 227 /// Set role for the syntax node matching \p N. 228 void markChild(ASTPtr N, NodeRole R); 229 230 /// Finish building the tree and consume the root node. 231 syntax::TranslationUnit *finalize() && { 232 auto Tokens = Arena.tokenBuffer().expandedTokens(); 233 assert(!Tokens.empty()); 234 assert(Tokens.back().kind() == tok::eof); 235 236 // Build the root of the tree, consuming all the children. 237 Pending.foldChildren(Arena, Tokens.drop_back(), 238 new (Arena.allocator()) syntax::TranslationUnit); 239 240 auto *TU = cast<syntax::TranslationUnit>(std::move(Pending).finalize()); 241 TU->assertInvariantsRecursive(); 242 return TU; 243 } 244 245 /// Finds a token starting at \p L. The token must exist if \p L is valid. 246 const syntax::Token *findToken(SourceLocation L) const; 247 248 /// Finds the syntax tokens corresponding to the \p SourceRange. 249 llvm::ArrayRef<syntax::Token> getRange(SourceRange Range) const { 250 assert(Range.isValid()); 251 return getRange(Range.getBegin(), Range.getEnd()); 252 } 253 254 /// Finds the syntax tokens corresponding to the passed source locations. 255 /// \p First is the start position of the first token and \p Last is the start 256 /// position of the last token. 257 llvm::ArrayRef<syntax::Token> getRange(SourceLocation First, 258 SourceLocation Last) const { 259 assert(First.isValid()); 260 assert(Last.isValid()); 261 assert(First == Last || 262 Arena.sourceManager().isBeforeInTranslationUnit(First, Last)); 263 return llvm::makeArrayRef(findToken(First), std::next(findToken(Last))); 264 } 265 266 llvm::ArrayRef<syntax::Token> 267 getTemplateRange(const ClassTemplateSpecializationDecl *D) const { 268 auto Tokens = getRange(D->getSourceRange()); 269 return maybeAppendSemicolon(Tokens, D); 270 } 271 272 /// Returns true if \p D is the last declarator in a chain and is thus 273 /// reponsible for creating SimpleDeclaration for the whole chain. 274 template <class T> 275 bool isResponsibleForCreatingDeclaration(const T *D) const { 276 static_assert((std::is_base_of<DeclaratorDecl, T>::value || 277 std::is_base_of<TypedefNameDecl, T>::value), 278 "only DeclaratorDecl and TypedefNameDecl are supported."); 279 280 const Decl *Next = D->getNextDeclInContext(); 281 282 // There's no next sibling, this one is responsible. 283 if (Next == nullptr) { 284 return true; 285 } 286 const auto *NextT = llvm::dyn_cast<T>(Next); 287 288 // Next sibling is not the same type, this one is responsible. 289 if (NextT == nullptr) { 290 return true; 291 } 292 // Next sibling doesn't begin at the same loc, it must be a different 293 // declaration, so this declarator is responsible. 294 if (NextT->getBeginLoc() != D->getBeginLoc()) { 295 return true; 296 } 297 298 // NextT is a member of the same declaration, and we need the last member to 299 // create declaration. This one is not responsible. 300 return false; 301 } 302 303 llvm::ArrayRef<syntax::Token> getDeclarationRange(Decl *D) { 304 llvm::ArrayRef<clang::syntax::Token> Tokens; 305 // We want to drop the template parameters for specializations. 306 if (const auto *S = llvm::dyn_cast<TagDecl>(D)) 307 Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc()); 308 else 309 Tokens = getRange(D->getSourceRange()); 310 return maybeAppendSemicolon(Tokens, D); 311 } 312 313 llvm::ArrayRef<syntax::Token> getExprRange(const Expr *E) const { 314 return getRange(E->getSourceRange()); 315 } 316 317 /// Find the adjusted range for the statement, consuming the trailing 318 /// semicolon when needed. 319 llvm::ArrayRef<syntax::Token> getStmtRange(const Stmt *S) const { 320 auto Tokens = getRange(S->getSourceRange()); 321 if (isa<CompoundStmt>(S)) 322 return Tokens; 323 324 // Some statements miss a trailing semicolon, e.g. 'return', 'continue' and 325 // all statements that end with those. Consume this semicolon here. 326 if (Tokens.back().kind() == tok::semi) 327 return Tokens; 328 return withTrailingSemicolon(Tokens); 329 } 330 331 private: 332 llvm::ArrayRef<syntax::Token> 333 maybeAppendSemicolon(llvm::ArrayRef<syntax::Token> Tokens, 334 const Decl *D) const { 335 if (llvm::isa<NamespaceDecl>(D)) 336 return Tokens; 337 if (DeclsWithoutSemicolons.count(D)) 338 return Tokens; 339 // FIXME: do not consume trailing semicolon on function definitions. 340 // Most declarations own a semicolon in syntax trees, but not in clang AST. 341 return withTrailingSemicolon(Tokens); 342 } 343 344 llvm::ArrayRef<syntax::Token> 345 withTrailingSemicolon(llvm::ArrayRef<syntax::Token> Tokens) const { 346 assert(!Tokens.empty()); 347 assert(Tokens.back().kind() != tok::eof); 348 // We never consume 'eof', so looking at the next token is ok. 349 if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi) 350 return llvm::makeArrayRef(Tokens.begin(), Tokens.end() + 1); 351 return Tokens; 352 } 353 354 void setRole(syntax::Node *N, NodeRole R) { 355 assert(N->role() == NodeRole::Detached); 356 N->setRole(R); 357 } 358 359 /// A collection of trees covering the input tokens. 360 /// When created, each tree corresponds to a single token in the file. 361 /// Clients call 'foldChildren' to attach one or more subtrees to a parent 362 /// node and update the list of trees accordingly. 363 /// 364 /// Ensures that added nodes properly nest and cover the whole token stream. 365 struct Forest { 366 Forest(syntax::Arena &A) { 367 assert(!A.tokenBuffer().expandedTokens().empty()); 368 assert(A.tokenBuffer().expandedTokens().back().kind() == tok::eof); 369 // Create all leaf nodes. 370 // Note that we do not have 'eof' in the tree. 371 for (auto &T : A.tokenBuffer().expandedTokens().drop_back()) { 372 auto *L = new (A.allocator()) syntax::Leaf(&T); 373 L->Original = true; 374 L->CanModify = A.tokenBuffer().spelledForExpanded(T).hasValue(); 375 Trees.insert(Trees.end(), {&T, L}); 376 } 377 } 378 379 void assignRole(llvm::ArrayRef<syntax::Token> Range, 380 syntax::NodeRole Role) { 381 assert(!Range.empty()); 382 auto It = Trees.lower_bound(Range.begin()); 383 assert(It != Trees.end() && "no node found"); 384 assert(It->first == Range.begin() && "no child with the specified range"); 385 assert((std::next(It) == Trees.end() || 386 std::next(It)->first == Range.end()) && 387 "no child with the specified range"); 388 assert(It->second->role() == NodeRole::Detached && 389 "re-assigning role for a child"); 390 It->second->setRole(Role); 391 } 392 393 /// Add \p Node to the forest and attach child nodes based on \p Tokens. 394 void foldChildren(const syntax::Arena &A, 395 llvm::ArrayRef<syntax::Token> Tokens, 396 syntax::Tree *Node) { 397 // Attach children to `Node`. 398 assert(Node->firstChild() == nullptr && "node already has children"); 399 400 auto *FirstToken = Tokens.begin(); 401 auto BeginChildren = Trees.lower_bound(FirstToken); 402 403 assert((BeginChildren == Trees.end() || 404 BeginChildren->first == FirstToken) && 405 "fold crosses boundaries of existing subtrees"); 406 auto EndChildren = Trees.lower_bound(Tokens.end()); 407 assert( 408 (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) && 409 "fold crosses boundaries of existing subtrees"); 410 411 // We need to go in reverse order, because we can only prepend. 412 for (auto It = EndChildren; It != BeginChildren; --It) { 413 auto *C = std::prev(It)->second; 414 if (C->role() == NodeRole::Detached) 415 C->setRole(NodeRole::Unknown); 416 Node->prependChildLowLevel(C); 417 } 418 419 // Mark that this node came from the AST and is backed by the source code. 420 Node->Original = true; 421 Node->CanModify = A.tokenBuffer().spelledForExpanded(Tokens).hasValue(); 422 423 Trees.erase(BeginChildren, EndChildren); 424 Trees.insert({FirstToken, Node}); 425 } 426 427 // EXPECTS: all tokens were consumed and are owned by a single root node. 428 syntax::Node *finalize() && { 429 assert(Trees.size() == 1); 430 auto *Root = Trees.begin()->second; 431 Trees = {}; 432 return Root; 433 } 434 435 std::string str(const syntax::Arena &A) const { 436 std::string R; 437 for (auto It = Trees.begin(); It != Trees.end(); ++It) { 438 unsigned CoveredTokens = 439 It != Trees.end() 440 ? (std::next(It)->first - It->first) 441 : A.tokenBuffer().expandedTokens().end() - It->first; 442 443 R += std::string(llvm::formatv( 444 "- '{0}' covers '{1}'+{2} tokens\n", It->second->kind(), 445 It->first->text(A.sourceManager()), CoveredTokens)); 446 R += It->second->dump(A); 447 } 448 return R; 449 } 450 451 private: 452 /// Maps from the start token to a subtree starting at that token. 453 /// Keys in the map are pointers into the array of expanded tokens, so 454 /// pointer order corresponds to the order of preprocessor tokens. 455 std::map<const syntax::Token *, syntax::Node *> Trees; 456 }; 457 458 /// For debugging purposes. 459 std::string str() { return Pending.str(Arena); } 460 461 syntax::Arena &Arena; 462 /// To quickly find tokens by their start location. 463 llvm::DenseMap</*SourceLocation*/ unsigned, const syntax::Token *> 464 LocationToToken; 465 Forest Pending; 466 llvm::DenseSet<Decl *> DeclsWithoutSemicolons; 467 ASTToSyntaxMapping Mapping; 468 }; 469 470 namespace { 471 class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> { 472 public: 473 explicit BuildTreeVisitor(ASTContext &Ctx, syntax::TreeBuilder &Builder) 474 : Builder(Builder), LangOpts(Ctx.getLangOpts()) {} 475 476 bool shouldTraversePostOrder() const { return true; } 477 478 bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) { 479 return processDeclaratorAndDeclaration(DD); 480 } 481 482 bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) { 483 return processDeclaratorAndDeclaration(TD); 484 } 485 486 bool VisitDecl(Decl *D) { 487 assert(!D->isImplicit()); 488 Builder.foldNode(Builder.getDeclarationRange(D), 489 new (allocator()) syntax::UnknownDeclaration(), D); 490 return true; 491 } 492 493 // RAV does not call WalkUpFrom* on explicit instantiations, so we have to 494 // override Traverse. 495 // FIXME: make RAV call WalkUpFrom* instead. 496 bool 497 TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) { 498 if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C)) 499 return false; 500 if (C->isExplicitSpecialization()) 501 return true; // we are only interested in explicit instantiations. 502 auto *Declaration = 503 cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C)); 504 foldExplicitTemplateInstantiation( 505 Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()), 506 Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C); 507 return true; 508 } 509 510 bool WalkUpFromTemplateDecl(TemplateDecl *S) { 511 foldTemplateDeclaration( 512 Builder.getDeclarationRange(S), 513 Builder.findToken(S->getTemplateParameters()->getTemplateLoc()), 514 Builder.getDeclarationRange(S->getTemplatedDecl()), S); 515 return true; 516 } 517 518 bool WalkUpFromTagDecl(TagDecl *C) { 519 // FIXME: build the ClassSpecifier node. 520 if (!C->isFreeStanding()) { 521 assert(C->getNumTemplateParameterLists() == 0); 522 return true; 523 } 524 handleFreeStandingTagDecl(C); 525 return true; 526 } 527 528 syntax::Declaration *handleFreeStandingTagDecl(TagDecl *C) { 529 assert(C->isFreeStanding()); 530 // Class is a declaration specifier and needs a spanning declaration node. 531 auto DeclarationRange = Builder.getDeclarationRange(C); 532 syntax::Declaration *Result = new (allocator()) syntax::SimpleDeclaration; 533 Builder.foldNode(DeclarationRange, Result, nullptr); 534 535 // Build TemplateDeclaration nodes if we had template parameters. 536 auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) { 537 const auto *TemplateKW = Builder.findToken(L.getTemplateLoc()); 538 auto R = llvm::makeArrayRef(TemplateKW, DeclarationRange.end()); 539 Result = 540 foldTemplateDeclaration(R, TemplateKW, DeclarationRange, nullptr); 541 DeclarationRange = R; 542 }; 543 if (auto *S = llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(C)) 544 ConsumeTemplateParameters(*S->getTemplateParameters()); 545 for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I) 546 ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1)); 547 return Result; 548 } 549 550 bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) { 551 // We do not want to call VisitDecl(), the declaration for translation 552 // unit is built by finalize(). 553 return true; 554 } 555 556 bool WalkUpFromCompoundStmt(CompoundStmt *S) { 557 using NodeRole = syntax::NodeRole; 558 559 Builder.markChildToken(S->getLBracLoc(), NodeRole::OpenParen); 560 for (auto *Child : S->body()) 561 Builder.markStmtChild(Child, NodeRole::CompoundStatement_statement); 562 Builder.markChildToken(S->getRBracLoc(), NodeRole::CloseParen); 563 564 Builder.foldNode(Builder.getStmtRange(S), 565 new (allocator()) syntax::CompoundStatement, S); 566 return true; 567 } 568 569 // Some statements are not yet handled by syntax trees. 570 bool WalkUpFromStmt(Stmt *S) { 571 Builder.foldNode(Builder.getStmtRange(S), 572 new (allocator()) syntax::UnknownStatement, S); 573 return true; 574 } 575 576 bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) { 577 // We override to traverse range initializer as VarDecl. 578 // RAV traverses it as a statement, we produce invalid node kinds in that 579 // case. 580 // FIXME: should do this in RAV instead? 581 bool Result = [&, this]() { 582 if (S->getInit() && !TraverseStmt(S->getInit())) 583 return false; 584 if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable())) 585 return false; 586 if (S->getRangeInit() && !TraverseStmt(S->getRangeInit())) 587 return false; 588 if (S->getBody() && !TraverseStmt(S->getBody())) 589 return false; 590 return true; 591 }(); 592 WalkUpFromCXXForRangeStmt(S); 593 return Result; 594 } 595 596 bool TraverseStmt(Stmt *S) { 597 if (auto *DS = llvm::dyn_cast_or_null<DeclStmt>(S)) { 598 // We want to consume the semicolon, make sure SimpleDeclaration does not. 599 for (auto *D : DS->decls()) 600 Builder.noticeDeclWithoutSemicolon(D); 601 } else if (auto *E = llvm::dyn_cast_or_null<Expr>(S)) { 602 return RecursiveASTVisitor::TraverseStmt(E->IgnoreImplicit()); 603 } 604 return RecursiveASTVisitor::TraverseStmt(S); 605 } 606 607 // Some expressions are not yet handled by syntax trees. 608 bool WalkUpFromExpr(Expr *E) { 609 assert(!isImplicitExpr(E) && "should be handled by TraverseStmt"); 610 Builder.foldNode(Builder.getExprRange(E), 611 new (allocator()) syntax::UnknownExpression, E); 612 return true; 613 } 614 615 syntax::NestedNameSpecifier * 616 BuildNestedNameSpecifier(NestedNameSpecifierLoc QualifierLoc) { 617 if (!QualifierLoc) 618 return nullptr; 619 for (auto it = QualifierLoc; it; it = it.getPrefix()) { 620 auto *NS = new (allocator()) syntax::NameSpecifier; 621 Builder.foldNode(Builder.getRange(it.getLocalSourceRange()), NS, nullptr); 622 Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier); 623 } 624 auto *NNS = new (allocator()) syntax::NestedNameSpecifier; 625 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS, 626 nullptr); 627 return NNS; 628 } 629 630 bool WalkUpFromDeclRefExpr(DeclRefExpr *S) { 631 if (auto *NNS = BuildNestedNameSpecifier(S->getQualifierLoc())) 632 Builder.markChild(NNS, syntax::NodeRole::IdExpression_qualifier); 633 634 auto *unqualifiedId = new (allocator()) syntax::UnqualifiedId; 635 // Get `UnqualifiedId` from `DeclRefExpr`. 636 // FIXME: Extract this logic so that it can be used by `MemberExpr`, 637 // and other semantic constructs, now it is tied to `DeclRefExpr`. 638 if (!S->hasExplicitTemplateArgs()) { 639 Builder.foldNode(Builder.getRange(S->getNameInfo().getSourceRange()), 640 unqualifiedId, nullptr); 641 } else { 642 auto templateIdSourceRange = 643 SourceRange(S->getNameInfo().getBeginLoc(), S->getRAngleLoc()); 644 Builder.foldNode(Builder.getRange(templateIdSourceRange), unqualifiedId, 645 nullptr); 646 } 647 Builder.markChild(unqualifiedId, syntax::NodeRole::IdExpression_id); 648 649 Builder.foldNode(Builder.getExprRange(S), 650 new (allocator()) syntax::IdExpression, S); 651 return true; 652 } 653 654 bool WalkUpFromParenExpr(ParenExpr *S) { 655 Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen); 656 Builder.markExprChild(S->getSubExpr(), 657 syntax::NodeRole::ParenExpression_subExpression); 658 Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen); 659 Builder.foldNode(Builder.getExprRange(S), 660 new (allocator()) syntax::ParenExpression, S); 661 return true; 662 } 663 664 bool WalkUpFromIntegerLiteral(IntegerLiteral *S) { 665 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 666 Builder.foldNode(Builder.getExprRange(S), 667 new (allocator()) syntax::IntegerLiteralExpression, S); 668 return true; 669 } 670 671 bool WalkUpFromCharacterLiteral(CharacterLiteral *S) { 672 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 673 Builder.foldNode(Builder.getExprRange(S), 674 new (allocator()) syntax::CharacterLiteralExpression, S); 675 return true; 676 } 677 678 bool WalkUpFromFloatingLiteral(FloatingLiteral *S) { 679 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 680 Builder.foldNode(Builder.getExprRange(S), 681 new (allocator()) syntax::FloatingLiteralExpression, S); 682 return true; 683 } 684 685 bool WalkUpFromStringLiteral(StringLiteral *S) { 686 Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken); 687 Builder.foldNode(Builder.getExprRange(S), 688 new (allocator()) syntax::StringLiteralExpression, S); 689 return true; 690 } 691 692 bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) { 693 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 694 Builder.foldNode(Builder.getExprRange(S), 695 new (allocator()) syntax::BoolLiteralExpression, S); 696 return true; 697 } 698 699 bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) { 700 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); 701 Builder.foldNode(Builder.getExprRange(S), 702 new (allocator()) syntax::CxxNullPtrExpression, S); 703 return true; 704 } 705 706 bool WalkUpFromUnaryOperator(UnaryOperator *S) { 707 Builder.markChildToken(S->getOperatorLoc(), 708 syntax::NodeRole::OperatorExpression_operatorToken); 709 Builder.markExprChild(S->getSubExpr(), 710 syntax::NodeRole::UnaryOperatorExpression_operand); 711 712 if (S->isPostfix()) 713 Builder.foldNode(Builder.getExprRange(S), 714 new (allocator()) syntax::PostfixUnaryOperatorExpression, 715 S); 716 else 717 Builder.foldNode(Builder.getExprRange(S), 718 new (allocator()) syntax::PrefixUnaryOperatorExpression, 719 S); 720 721 return true; 722 } 723 724 bool WalkUpFromBinaryOperator(BinaryOperator *S) { 725 Builder.markExprChild( 726 S->getLHS(), syntax::NodeRole::BinaryOperatorExpression_leftHandSide); 727 Builder.markChildToken(S->getOperatorLoc(), 728 syntax::NodeRole::OperatorExpression_operatorToken); 729 Builder.markExprChild( 730 S->getRHS(), syntax::NodeRole::BinaryOperatorExpression_rightHandSide); 731 Builder.foldNode(Builder.getExprRange(S), 732 new (allocator()) syntax::BinaryOperatorExpression, S); 733 return true; 734 } 735 736 bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) { 737 if (S->isInfixBinaryOp()) { 738 Builder.markExprChild( 739 S->getArg(0), 740 syntax::NodeRole::BinaryOperatorExpression_leftHandSide); 741 Builder.markChildToken( 742 S->getOperatorLoc(), 743 syntax::NodeRole::OperatorExpression_operatorToken); 744 Builder.markExprChild( 745 S->getArg(1), 746 syntax::NodeRole::BinaryOperatorExpression_rightHandSide); 747 Builder.foldNode(Builder.getExprRange(S), 748 new (allocator()) syntax::BinaryOperatorExpression, S); 749 return true; 750 } 751 return RecursiveASTVisitor::WalkUpFromCXXOperatorCallExpr(S); 752 } 753 754 bool WalkUpFromNamespaceDecl(NamespaceDecl *S) { 755 auto Tokens = Builder.getDeclarationRange(S); 756 if (Tokens.front().kind() == tok::coloncolon) { 757 // Handle nested namespace definitions. Those start at '::' token, e.g. 758 // namespace a^::b {} 759 // FIXME: build corresponding nodes for the name of this namespace. 760 return true; 761 } 762 Builder.foldNode(Tokens, new (allocator()) syntax::NamespaceDefinition, S); 763 return true; 764 } 765 766 bool TraverseParenTypeLoc(ParenTypeLoc L) { 767 // We reverse order of traversal to get the proper syntax structure. 768 if (!WalkUpFromParenTypeLoc(L)) 769 return false; 770 return TraverseTypeLoc(L.getInnerLoc()); 771 } 772 773 bool WalkUpFromParenTypeLoc(ParenTypeLoc L) { 774 Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen); 775 Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen); 776 Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getRParenLoc()), 777 new (allocator()) syntax::ParenDeclarator, L); 778 return true; 779 } 780 781 // Declarator chunks, they are produced by type locs and some clang::Decls. 782 bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L) { 783 Builder.markChildToken(L.getLBracketLoc(), syntax::NodeRole::OpenParen); 784 Builder.markExprChild(L.getSizeExpr(), 785 syntax::NodeRole::ArraySubscript_sizeExpression); 786 Builder.markChildToken(L.getRBracketLoc(), syntax::NodeRole::CloseParen); 787 Builder.foldNode(Builder.getRange(L.getLBracketLoc(), L.getRBracketLoc()), 788 new (allocator()) syntax::ArraySubscript, L); 789 return true; 790 } 791 792 bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) { 793 Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen); 794 for (auto *P : L.getParams()) { 795 Builder.markChild(P, syntax::NodeRole::ParametersAndQualifiers_parameter); 796 } 797 Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen); 798 Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()), 799 new (allocator()) syntax::ParametersAndQualifiers, L); 800 return true; 801 } 802 803 bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L) { 804 if (!L.getTypePtr()->hasTrailingReturn()) 805 return WalkUpFromFunctionTypeLoc(L); 806 807 auto *TrailingReturnTokens = BuildTrailingReturn(L); 808 // Finish building the node for parameters. 809 Builder.markChild(TrailingReturnTokens, 810 syntax::NodeRole::ParametersAndQualifiers_trailingReturn); 811 return WalkUpFromFunctionTypeLoc(L); 812 } 813 814 bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) { 815 auto SR = L.getLocalSourceRange(); 816 Builder.foldNode(Builder.getRange(SR), 817 new (allocator()) syntax::MemberPointer, L); 818 return true; 819 } 820 821 // The code below is very regular, it could even be generated with some 822 // preprocessor magic. We merely assign roles to the corresponding children 823 // and fold resulting nodes. 824 bool WalkUpFromDeclStmt(DeclStmt *S) { 825 Builder.foldNode(Builder.getStmtRange(S), 826 new (allocator()) syntax::DeclarationStatement, S); 827 return true; 828 } 829 830 bool WalkUpFromNullStmt(NullStmt *S) { 831 Builder.foldNode(Builder.getStmtRange(S), 832 new (allocator()) syntax::EmptyStatement, S); 833 return true; 834 } 835 836 bool WalkUpFromSwitchStmt(SwitchStmt *S) { 837 Builder.markChildToken(S->getSwitchLoc(), 838 syntax::NodeRole::IntroducerKeyword); 839 Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 840 Builder.foldNode(Builder.getStmtRange(S), 841 new (allocator()) syntax::SwitchStatement, S); 842 return true; 843 } 844 845 bool WalkUpFromCaseStmt(CaseStmt *S) { 846 Builder.markChildToken(S->getKeywordLoc(), 847 syntax::NodeRole::IntroducerKeyword); 848 Builder.markExprChild(S->getLHS(), syntax::NodeRole::CaseStatement_value); 849 Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement); 850 Builder.foldNode(Builder.getStmtRange(S), 851 new (allocator()) syntax::CaseStatement, S); 852 return true; 853 } 854 855 bool WalkUpFromDefaultStmt(DefaultStmt *S) { 856 Builder.markChildToken(S->getKeywordLoc(), 857 syntax::NodeRole::IntroducerKeyword); 858 Builder.markStmtChild(S->getSubStmt(), syntax::NodeRole::BodyStatement); 859 Builder.foldNode(Builder.getStmtRange(S), 860 new (allocator()) syntax::DefaultStatement, S); 861 return true; 862 } 863 864 bool WalkUpFromIfStmt(IfStmt *S) { 865 Builder.markChildToken(S->getIfLoc(), syntax::NodeRole::IntroducerKeyword); 866 Builder.markStmtChild(S->getThen(), 867 syntax::NodeRole::IfStatement_thenStatement); 868 Builder.markChildToken(S->getElseLoc(), 869 syntax::NodeRole::IfStatement_elseKeyword); 870 Builder.markStmtChild(S->getElse(), 871 syntax::NodeRole::IfStatement_elseStatement); 872 Builder.foldNode(Builder.getStmtRange(S), 873 new (allocator()) syntax::IfStatement, S); 874 return true; 875 } 876 877 bool WalkUpFromForStmt(ForStmt *S) { 878 Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword); 879 Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 880 Builder.foldNode(Builder.getStmtRange(S), 881 new (allocator()) syntax::ForStatement, S); 882 return true; 883 } 884 885 bool WalkUpFromWhileStmt(WhileStmt *S) { 886 Builder.markChildToken(S->getWhileLoc(), 887 syntax::NodeRole::IntroducerKeyword); 888 Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 889 Builder.foldNode(Builder.getStmtRange(S), 890 new (allocator()) syntax::WhileStatement, S); 891 return true; 892 } 893 894 bool WalkUpFromContinueStmt(ContinueStmt *S) { 895 Builder.markChildToken(S->getContinueLoc(), 896 syntax::NodeRole::IntroducerKeyword); 897 Builder.foldNode(Builder.getStmtRange(S), 898 new (allocator()) syntax::ContinueStatement, S); 899 return true; 900 } 901 902 bool WalkUpFromBreakStmt(BreakStmt *S) { 903 Builder.markChildToken(S->getBreakLoc(), 904 syntax::NodeRole::IntroducerKeyword); 905 Builder.foldNode(Builder.getStmtRange(S), 906 new (allocator()) syntax::BreakStatement, S); 907 return true; 908 } 909 910 bool WalkUpFromReturnStmt(ReturnStmt *S) { 911 Builder.markChildToken(S->getReturnLoc(), 912 syntax::NodeRole::IntroducerKeyword); 913 Builder.markExprChild(S->getRetValue(), 914 syntax::NodeRole::ReturnStatement_value); 915 Builder.foldNode(Builder.getStmtRange(S), 916 new (allocator()) syntax::ReturnStatement, S); 917 return true; 918 } 919 920 bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S) { 921 Builder.markChildToken(S->getForLoc(), syntax::NodeRole::IntroducerKeyword); 922 Builder.markStmtChild(S->getBody(), syntax::NodeRole::BodyStatement); 923 Builder.foldNode(Builder.getStmtRange(S), 924 new (allocator()) syntax::RangeBasedForStatement, S); 925 return true; 926 } 927 928 bool WalkUpFromEmptyDecl(EmptyDecl *S) { 929 Builder.foldNode(Builder.getDeclarationRange(S), 930 new (allocator()) syntax::EmptyDeclaration, S); 931 return true; 932 } 933 934 bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S) { 935 Builder.markExprChild(S->getAssertExpr(), 936 syntax::NodeRole::StaticAssertDeclaration_condition); 937 Builder.markExprChild(S->getMessage(), 938 syntax::NodeRole::StaticAssertDeclaration_message); 939 Builder.foldNode(Builder.getDeclarationRange(S), 940 new (allocator()) syntax::StaticAssertDeclaration, S); 941 return true; 942 } 943 944 bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) { 945 Builder.foldNode(Builder.getDeclarationRange(S), 946 new (allocator()) syntax::LinkageSpecificationDeclaration, 947 S); 948 return true; 949 } 950 951 bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) { 952 Builder.foldNode(Builder.getDeclarationRange(S), 953 new (allocator()) syntax::NamespaceAliasDefinition, S); 954 return true; 955 } 956 957 bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) { 958 Builder.foldNode(Builder.getDeclarationRange(S), 959 new (allocator()) syntax::UsingNamespaceDirective, S); 960 return true; 961 } 962 963 bool WalkUpFromUsingDecl(UsingDecl *S) { 964 Builder.foldNode(Builder.getDeclarationRange(S), 965 new (allocator()) syntax::UsingDeclaration, S); 966 return true; 967 } 968 969 bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) { 970 Builder.foldNode(Builder.getDeclarationRange(S), 971 new (allocator()) syntax::UsingDeclaration, S); 972 return true; 973 } 974 975 bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) { 976 Builder.foldNode(Builder.getDeclarationRange(S), 977 new (allocator()) syntax::UsingDeclaration, S); 978 return true; 979 } 980 981 bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) { 982 Builder.foldNode(Builder.getDeclarationRange(S), 983 new (allocator()) syntax::TypeAliasDeclaration, S); 984 return true; 985 } 986 987 private: 988 template <class T> SourceLocation getQualifiedNameStart(T *D) { 989 static_assert((std::is_base_of<DeclaratorDecl, T>::value || 990 std::is_base_of<TypedefNameDecl, T>::value), 991 "only DeclaratorDecl and TypedefNameDecl are supported."); 992 993 auto DN = D->getDeclName(); 994 bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo(); 995 if (IsAnonymous) 996 return SourceLocation(); 997 998 if (const auto *DD = llvm::dyn_cast<DeclaratorDecl>(D)) { 999 if (DD->getQualifierLoc()) { 1000 return DD->getQualifierLoc().getBeginLoc(); 1001 } 1002 } 1003 1004 return D->getLocation(); 1005 } 1006 1007 SourceRange getInitializerRange(Decl *D) { 1008 if (auto *V = llvm::dyn_cast<VarDecl>(D)) { 1009 auto *I = V->getInit(); 1010 // Initializers in range-based-for are not part of the declarator 1011 if (I && !V->isCXXForRangeDecl()) 1012 return I->getSourceRange(); 1013 } 1014 1015 return SourceRange(); 1016 } 1017 1018 /// Folds SimpleDeclarator node (if present) and in case this is the last 1019 /// declarator in the chain it also folds SimpleDeclaration node. 1020 template <class T> bool processDeclaratorAndDeclaration(T *D) { 1021 SourceRange Initializer = getInitializerRange(D); 1022 auto Range = getDeclaratorRange(Builder.sourceManager(), 1023 D->getTypeSourceInfo()->getTypeLoc(), 1024 getQualifiedNameStart(D), Initializer); 1025 1026 // There doesn't have to be a declarator (e.g. `void foo(int)` only has 1027 // declaration, but no declarator). 1028 if (Range.getBegin().isValid()) { 1029 auto *N = new (allocator()) syntax::SimpleDeclarator; 1030 Builder.foldNode(Builder.getRange(Range), N, nullptr); 1031 Builder.markChild(N, syntax::NodeRole::SimpleDeclaration_declarator); 1032 } 1033 1034 if (Builder.isResponsibleForCreatingDeclaration(D)) { 1035 Builder.foldNode(Builder.getDeclarationRange(D), 1036 new (allocator()) syntax::SimpleDeclaration, D); 1037 } 1038 return true; 1039 } 1040 1041 /// Returns the range of the built node. 1042 syntax::TrailingReturnType *BuildTrailingReturn(FunctionProtoTypeLoc L) { 1043 assert(L.getTypePtr()->hasTrailingReturn()); 1044 1045 auto ReturnedType = L.getReturnLoc(); 1046 // Build node for the declarator, if any. 1047 auto ReturnDeclaratorRange = 1048 getDeclaratorRange(this->Builder.sourceManager(), ReturnedType, 1049 /*Name=*/SourceLocation(), 1050 /*Initializer=*/SourceLocation()); 1051 syntax::SimpleDeclarator *ReturnDeclarator = nullptr; 1052 if (ReturnDeclaratorRange.isValid()) { 1053 ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator; 1054 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange), 1055 ReturnDeclarator, nullptr); 1056 } 1057 1058 // Build node for trailing return type. 1059 auto Return = Builder.getRange(ReturnedType.getSourceRange()); 1060 const auto *Arrow = Return.begin() - 1; 1061 assert(Arrow->kind() == tok::arrow); 1062 auto Tokens = llvm::makeArrayRef(Arrow, Return.end()); 1063 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken); 1064 if (ReturnDeclarator) 1065 Builder.markChild(ReturnDeclarator, 1066 syntax::NodeRole::TrailingReturnType_declarator); 1067 auto *R = new (allocator()) syntax::TrailingReturnType; 1068 Builder.foldNode(Tokens, R, L); 1069 return R; 1070 } 1071 1072 void foldExplicitTemplateInstantiation( 1073 ArrayRef<syntax::Token> Range, const syntax::Token *ExternKW, 1074 const syntax::Token *TemplateKW, 1075 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) { 1076 assert(!ExternKW || ExternKW->kind() == tok::kw_extern); 1077 assert(TemplateKW && TemplateKW->kind() == tok::kw_template); 1078 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword); 1079 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword); 1080 Builder.markChild( 1081 InnerDeclaration, 1082 syntax::NodeRole::ExplicitTemplateInstantiation_declaration); 1083 Builder.foldNode( 1084 Range, new (allocator()) syntax::ExplicitTemplateInstantiation, From); 1085 } 1086 1087 syntax::TemplateDeclaration *foldTemplateDeclaration( 1088 ArrayRef<syntax::Token> Range, const syntax::Token *TemplateKW, 1089 ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) { 1090 assert(TemplateKW && TemplateKW->kind() == tok::kw_template); 1091 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword); 1092 1093 auto *N = new (allocator()) syntax::TemplateDeclaration; 1094 Builder.foldNode(Range, N, From); 1095 Builder.markChild(N, syntax::NodeRole::TemplateDeclaration_declaration); 1096 return N; 1097 } 1098 1099 /// A small helper to save some typing. 1100 llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); } 1101 1102 syntax::TreeBuilder &Builder; 1103 const LangOptions &LangOpts; 1104 }; 1105 } // namespace 1106 1107 void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) { 1108 DeclsWithoutSemicolons.insert(D); 1109 } 1110 1111 void syntax::TreeBuilder::markChildToken(SourceLocation Loc, NodeRole Role) { 1112 if (Loc.isInvalid()) 1113 return; 1114 Pending.assignRole(*findToken(Loc), Role); 1115 } 1116 1117 void syntax::TreeBuilder::markChildToken(const syntax::Token *T, NodeRole R) { 1118 if (!T) 1119 return; 1120 Pending.assignRole(*T, R); 1121 } 1122 1123 void syntax::TreeBuilder::markChild(syntax::Node *N, NodeRole R) { 1124 assert(N); 1125 setRole(N, R); 1126 } 1127 1128 void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) { 1129 auto *SN = Mapping.find(N); 1130 assert(SN != nullptr); 1131 setRole(SN, R); 1132 } 1133 1134 void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) { 1135 if (!Child) 1136 return; 1137 1138 syntax::Tree *ChildNode; 1139 if (Expr *ChildExpr = dyn_cast<Expr>(Child)) { 1140 // This is an expression in a statement position, consume the trailing 1141 // semicolon and form an 'ExpressionStatement' node. 1142 markExprChild(ChildExpr, NodeRole::ExpressionStatement_expression); 1143 ChildNode = new (allocator()) syntax::ExpressionStatement; 1144 // (!) 'getStmtRange()' ensures this covers a trailing semicolon. 1145 Pending.foldChildren(Arena, getStmtRange(Child), ChildNode); 1146 } else { 1147 ChildNode = Mapping.find(Child); 1148 } 1149 assert(ChildNode != nullptr); 1150 setRole(ChildNode, Role); 1151 } 1152 1153 void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) { 1154 if (!Child) 1155 return; 1156 Child = Child->IgnoreImplicit(); 1157 1158 syntax::Tree *ChildNode = Mapping.find(Child); 1159 assert(ChildNode != nullptr); 1160 setRole(ChildNode, Role); 1161 } 1162 1163 const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const { 1164 if (L.isInvalid()) 1165 return nullptr; 1166 auto It = LocationToToken.find(L.getRawEncoding()); 1167 assert(It != LocationToToken.end()); 1168 return It->second; 1169 } 1170 1171 syntax::TranslationUnit * 1172 syntax::buildSyntaxTree(Arena &A, const TranslationUnitDecl &TU) { 1173 TreeBuilder Builder(A); 1174 BuildTreeVisitor(TU.getASTContext(), Builder).TraverseAST(TU.getASTContext()); 1175 return std::move(Builder).finalize(); 1176 } 1177