clang: lib/Tooling/Syntax/BuildTree.cpp Source File (original) (raw)

1

2

3

4

5

6

7

32#include "llvm/ADT/ArrayRef.h"

33#include "llvm/ADT/DenseMap.h"

34#include "llvm/ADT/PointerUnion.h"

35#include "llvm/ADT/STLExtras.h"

36#include "llvm/ADT/SmallVector.h"

37#include "llvm/Support/Allocator.h"

38#include "llvm/Support/Compiler.h"

39#include "llvm/Support/FormatVariadic.h"

40#include

41

42using namespace clang;

43

44

45

46

48 if (auto *C = dyn_cast(E)) {

49 auto NumArgs = C->getNumArgs();

51 Expr *A = C->getArg(0);

52 if (C->getParenOrBraceRange().isInvalid())

53 return A;

54 }

55 }

56 return E;

57}

58

59

60

61

62

63

64

65

67 if (auto *F = dyn_cast(E)) {

68 if (F->getCastKind() == CK_ConstructorConversion)

69 return F->getSubExpr();

70 }

71 return E;

72}

73

79

80[[maybe_unused]]

84

85namespace {

86

87

88

89

90

91

92

93

94

95

96

97

98struct GetStartLoc : TypeLocVisitor<GetStartLoc, SourceLocation> {

99 SourceLocation VisitParenTypeLoc(ParenTypeLoc T) {

100 auto L = Visit(T.getInnerLoc());

101 if (L.isValid())

102 return L;

103 return T.getLParenLoc();

104 }

105

106

107 SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) {

108 return HandlePointer(T);

109 }

110

111 SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {

112 return HandlePointer(T);

113 }

114

115 SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {

116 return HandlePointer(T);

117 }

118

119 SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) {

120 return HandlePointer(T);

121 }

122

123 SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) {

124 return HandlePointer(T);

125 }

126

127

128

129

130

131 SourceLocation VisitTypeLoc(TypeLoc T) {

132 auto N = T.getNextTypeLoc();

133 if (!N)

134 return SourceLocation();

135 return Visit(N);

136 }

137

138 SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) {

140 return SourceLocation();

141 return VisitTypeLoc(T);

142 }

143

144private:

145 template SourceLocation HandlePointer(PtrLoc T) {

146 auto L = Visit(T.getPointeeLoc());

147 if (L.isValid())

148 return L;

149 return T.getLocalSourceRange().getBegin();

150 }

151};

152}

153

155 auto FirstDefaultArg =

157 return llvm::make_range(Args.begin(), FirstDefaultArg);

158}

159

162

163 case OO_EqualEqual:

164 case OO_ExclaimEqual:

165 case OO_Greater:

166 case OO_GreaterEqual:

167 case OO_Less:

168 case OO_LessEqual:

169 case OO_Spaceship:

170

171 case OO_Equal:

172 case OO_SlashEqual:

173 case OO_PercentEqual:

174 case OO_CaretEqual:

175 case OO_PipeEqual:

176 case OO_LessLessEqual:

177 case OO_GreaterGreaterEqual:

178 case OO_PlusEqual:

179 case OO_MinusEqual:

180 case OO_StarEqual:

181 case OO_AmpEqual:

182

183 case OO_Slash:

184 case OO_Percent:

185 case OO_Caret:

186 case OO_Pipe:

187 case OO_LessLess:

188 case OO_GreaterGreater:

189 case OO_AmpAmp:

190 case OO_PipePipe:

191 case OO_ArrowStar:

192 case OO_Comma:

193 return syntax::NodeKind::BinaryOperatorExpression;

194 case OO_Tilde:

195 case OO_Exclaim:

196 return syntax::NodeKind::PrefixUnaryOperatorExpression;

197

198 case OO_PlusPlus:

199 case OO_MinusMinus:

201 case 1:

202 return syntax::NodeKind::PrefixUnaryOperatorExpression;

203 case 2:

204 return syntax::NodeKind::PostfixUnaryOperatorExpression;

205 default:

206 llvm_unreachable("Invalid number of arguments for operator");

207 }

208

209 case OO_Plus:

210 case OO_Minus:

211 case OO_Star:

212 case OO_Amp:

214 case 1:

215 return syntax::NodeKind::PrefixUnaryOperatorExpression;

216 case 2:

217 return syntax::NodeKind::BinaryOperatorExpression;

218 default:

219 llvm_unreachable("Invalid number of arguments for operator");

220 }

221 return syntax::NodeKind::BinaryOperatorExpression;

222

223 case OO_New:

224 case OO_Delete:

225 case OO_Array_New:

226 case OO_Array_Delete:

227 case OO_Coawait:

228 case OO_Subscript:

229 case OO_Arrow:

230 return syntax::NodeKind::UnknownExpression;

231 case OO_Call:

232 return syntax::NodeKind::CallExpression;

233 case OO_Conditional:

236 llvm_unreachable("Not an overloadable operator");

237 }

238 llvm_unreachable("Unknown OverloadedOperatorKind enum");

239}

240

241

242

243

244

245

248 "only DeclaratorDecl and TypedefNameDecl are supported.");

249

251 bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo();

252 if (IsAnonymous)

254

255 if (const auto *DD = dyn_cast(D)) {

256 if (DD->getQualifierLoc()) {

257 return DD->getQualifierLoc().getBeginLoc();

258 }

259 }

260

262}

263

264

265

266

267

268

270 if (auto *V = dyn_cast(D)) {

271 auto *I = V->getInit();

272

273 if (I && V->isCXXForRangeDecl())

274 return I->getSourceRange();

275 }

276

278}

279

280

281

282

283

284

285

286

287

295 Start = Name;

296

297

298 if (End.isInvalid() || SM.isBeforeInTranslationUnit(End, Name))

299 End = Name;

300 }

302 auto InitializerEnd = Initializer.getEnd();

303 assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) ||

304 End == InitializerEnd);

305 End = InitializerEnd;

306 }

308}

309

310namespace {

311

312using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>;

313

314

315

316class ASTToSyntaxMapping {

317public:

318 void add(ASTPtr From, syntax::Tree *To) {

319 assert(To != nullptr);

320 assert(!From.isNull());

321

322 bool Added = Nodes.insert({From, To}).second;

323 (void)Added;

324 assert(Added && "mapping added twice");

325 }

326

327 void add(NestedNameSpecifierLoc From, syntax::Tree *To) {

328 assert(To != nullptr);

330

331 bool Added = NNSNodes.insert({From, To}).second;

332 (void)Added;

333 assert(Added && "mapping added twice");

334 }

335

336 syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }

337

338 syntax::Tree *find(NestedNameSpecifierLoc P) const {

339 return NNSNodes.lookup(P);

340 }

341

342private:

343 llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes;

344 llvm::DenseMap<NestedNameSpecifierLoc, syntax::Tree *> NNSNodes;

345};

346}

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363class syntax::TreeBuilder {

364public:

365 TreeBuilder(syntax::Arena &Arena, TokenBufferTokenManager& TBTM)

366 : Arena(Arena),

367 TBTM(TBTM),

368 Pending(Arena, TBTM.tokenBuffer()) {

369 for (const auto &T : TBTM.tokenBuffer().expandedTokens())

370 LocationToToken.insert({T.location(), &T});

371 }

372

373 llvm::BumpPtrAllocator &allocator() { return Arena.getAllocator(); }

374 const SourceManager &sourceManager() const {

375 return TBTM.sourceManager();

376 }

377

378

379

380 void foldNode(ArrayRefsyntax::Token Range, syntax::Tree *New, ASTPtr From) {

381 assert(New);

382 Pending.foldChildren(TBTM.tokenBuffer(), Range, New);

383 if (From)

384 Mapping.add(From, New);

385 }

386

387 void foldNode(ArrayRefsyntax::Token Range, syntax::Tree *New, TypeLoc L) {

388

389 foldNode(Range, New, nullptr);

390 }

391

392 void foldNode(llvm::ArrayRefsyntax::Token Range, syntax::Tree *New,

393 NestedNameSpecifierLoc From) {

394 assert(New);

395 Pending.foldChildren(TBTM.tokenBuffer(), Range, New);

396 if (From)

397 Mapping.add(From, New);

398 }

399

400

401

402 void foldList(ArrayRefsyntax::Token SuperRange, syntax::List *New,

403 ASTPtr From) {

404 assert(New);

405 auto ListRange = Pending.shrinkToFitList(SuperRange);

406 Pending.foldChildren(TBTM.tokenBuffer(), ListRange, New);

407 if (From)

408 Mapping.add(From, New);

409 }

410

411

412

413 void noticeDeclWithoutSemicolon(Decl *D);

414

415

416

417

418

419 void markStmtChild(Stmt *Child, NodeRole Role);

420

421

422 void markExprChild(Expr *Child, NodeRole Role);

423

424 void markChildToken(SourceLocation Loc, NodeRole R);

425

426 void markChildToken(const syntax::Token *T, NodeRole R);

427

428

429 void markChild(syntax::Node *N, NodeRole R);

430

431 void markChild(ASTPtr N, NodeRole R);

432

433 void markChild(NestedNameSpecifierLoc N, NodeRole R);

434

435

436 syntax::TranslationUnit *finalize() && {

437 auto Tokens = TBTM.tokenBuffer().expandedTokens();

438 assert(!Tokens.empty());

439 assert(Tokens.back().kind() == tok::eof);

440

441

442 Pending.foldChildren(TBTM.tokenBuffer(), Tokens.drop_back(),

443 new (Arena.getAllocator()) syntax::TranslationUnit);

444

446 TU->assertInvariantsRecursive();

447 return TU;

448 }

449

450

451 const syntax::Token *findToken(SourceLocation L) const;

452

453

454 ArrayRefsyntax::Token getRange(SourceRange Range) const {

455 assert(Range.isValid());

457 }

458

459

460

461

462 ArrayRefsyntax::Token getRange(SourceLocation First,

463 SourceLocation Last) const {

464 assert(First.isValid());

465 assert(Last.isValid());

467 TBTM.sourceManager().isBeforeInTranslationUnit(First, Last));

468 return llvm::ArrayRef(findToken(First), std::next(findToken(Last)));

469 }

470

471 ArrayRefsyntax::Token

472 getTemplateRange(const ClassTemplateSpecializationDecl *D) const {

474 return maybeAppendSemicolon(Tokens, D);

475 }

476

477

478

479 bool isResponsibleForCreatingDeclaration(const Decl *D) const {

481 "only DeclaratorDecl and TypedefNameDecl are supported.");

482

484

485

486 if (Next == nullptr) {

487 return true;

488 }

489

490

492 return true;

493 }

494

495

497 return true;

498 }

499

500

501

502 return false;

503 }

504

505 ArrayRefsyntax::Token getDeclarationRange(Decl *D) {

506 ArrayRefsyntax::Token Tokens;

507

508 if (const auto *S = dyn_cast(D))

509 Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());

510 else

512 return maybeAppendSemicolon(Tokens, D);

513 }

514

515 ArrayRefsyntax::Token getExprRange(const Expr *E) const {

517 }

518

519

520

521 ArrayRefsyntax::Token getStmtRange(const Stmt *S) const {

524 return Tokens;

525

526

527

528 if (Tokens.back().kind() == tok::semi)

529 return Tokens;

530 return withTrailingSemicolon(Tokens);

531 }

532

533private:

534 ArrayRefsyntax::Token maybeAppendSemicolon(ArrayRefsyntax::Token Tokens,

535 const Decl *D) const {

537 return Tokens;

538 if (DeclsWithoutSemicolons.count(D))

539 return Tokens;

540

541

542 return withTrailingSemicolon(Tokens);

543 }

544

545 ArrayRefsyntax::Token

546 withTrailingSemicolon(ArrayRefsyntax::Token Tokens) const {

547 assert(!Tokens.empty());

548 assert(Tokens.back().kind() != tok::eof);

549

550 if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi)

551 return llvm::ArrayRef(Tokens.begin(), Tokens.end() + 1);

552 return Tokens;

553 }

554

555 void setRole(syntax::Node *N, NodeRole R) {

556 assert(N->getRole() == NodeRole::Detached);

557 N->setRole(R);

558 }

559

560

561

562

563

564

565

566 struct Forest {

567 Forest(syntax::Arena &A, const syntax::TokenBuffer &TB) {

569 assert(TB.expandedTokens().back().kind() == tok::eof);

570

571

574 syntax::Leaf(reinterpret_castTokenManager::Key\(&T));

575 L->Original = true;

577 Trees.insert(Trees.end(), {&T, L});

578 }

579 }

580

582 assert(Range.empty());

583 auto It = Trees.lower_bound(Range.begin());

584 assert(It != Trees.end() && "no node found");

585 assert(It->first == Range.begin() && "no child with the specified range");

586 assert((std::next(It) == Trees.end() ||

587 std::next(It)->first == Range.end()) &&

588 "no child with the specified range");

589 assert(It->second->getRole() == NodeRole::Detached &&

590 "re-assigning role for a child");

591 It->second->setRole(Role);

592 }

593

594

595

596 ArrayRefsyntax::Token shrinkToFitList(ArrayRefsyntax::Token Range) {

597 auto BeginChildren = Trees.lower_bound(Range.begin());

598 assert((BeginChildren == Trees.end() ||

599 BeginChildren->first == Range.begin()) &&

600 "Range crosses boundaries of existing subtrees");

601

602 auto EndChildren = Trees.lower_bound(Range.end());

603 assert(

604 (EndChildren == Trees.end() || EndChildren->first == Range.end()) &&

605 "Range crosses boundaries of existing subtrees");

606

607 auto BelongsToList = [](decltype(Trees)::value_type KV) {

608 auto Role = KV.second->getRole();

609 return Role == syntax::NodeRole::ListElement ||

610 Role == syntax::NodeRole::ListDelimiter;

611 };

612

613 auto BeginListChildren =

614 std::find_if(BeginChildren, EndChildren, BelongsToList);

615

616 auto EndListChildren =

617 std::find_if_not(BeginListChildren, EndChildren, BelongsToList);

618

619 return ArrayRefsyntax::Token(BeginListChildren->first,

620 EndListChildren->first);

621 }

622

623

624 void foldChildren(const syntax::TokenBuffer &TB,

625 ArrayRefsyntax::Token Tokens, syntax::Tree *Node) {

626

627 assert(Node->getFirstChild() == nullptr && "node already has children");

628

629 auto *FirstToken = Tokens.begin();

630 auto BeginChildren = Trees.lower_bound(FirstToken);

631

632 assert((BeginChildren == Trees.end() ||

633 BeginChildren->first == FirstToken) &&

634 "fold crosses boundaries of existing subtrees");

635 auto EndChildren = Trees.lower_bound(Tokens.end());

636 assert(

637 (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&

638 "fold crosses boundaries of existing subtrees");

639

640 for (auto It = BeginChildren; It != EndChildren; ++It) {

641 auto *C = It->second;

642 if (C->getRole() == NodeRole::Detached)

643 C->setRole(NodeRole::Unknown);

644 Node->appendChildLowLevel(C);

645 }

646

647

648 Node->Original = true;

649 Node->CanModify =

651

652 Trees.erase(BeginChildren, EndChildren);

653 Trees.insert({FirstToken, Node});

654 }

655

656

657 syntax::Node *finalize() && {

658 assert(Trees.size() == 1);

659 auto *Root = Trees.begin()->second;

660 Trees = {};

661 return Root;

662 }

663

664 std::string str(const syntax::TokenBufferTokenManager &STM) const {

665 std::string R;

666 for (auto It = Trees.begin(); It != Trees.end(); ++It) {

667 unsigned CoveredTokens =

668 It != Trees.end()

669 ? (std::next(It)->first - It->first)

670 : STM.tokenBuffer().expandedTokens().end() - It->first;

671

672 R += std::string(

673 formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(),

674 It->first->text(STM.sourceManager()), CoveredTokens));

675 R += It->second->dump(STM);

676 }

677 return R;

678 }

679

680 private:

681

682

683

684 std::map<const syntax::Token *, syntax::Node *> Trees;

685 };

686

687

688 std::string str() { return Pending.str(TBTM); }

689

690 syntax::Arena &Arena;

691 TokenBufferTokenManager& TBTM;

692

693 llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken;

694 Forest Pending;

695 llvm::DenseSet<Decl *> DeclsWithoutSemicolons;

696 ASTToSyntaxMapping Mapping;

697};

698

699namespace {

701public:

702 explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)

703 : Builder(Builder), Context(Context) {}

704

706

707 bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {

708 return processDeclaratorAndDeclaration(DD);

709 }

710

711 bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) {

712 return processDeclaratorAndDeclaration(TD);

713 }

714

717 Builder.foldNode(Builder.getDeclarationRange(D),

718 new (allocator()) syntax::UnknownDeclaration(), D);

719 return true;

720 }

721

722

723

724

725 bool

726 TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {

727 if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C))

728 return false;

729 if (C->isExplicitSpecialization())

730 return true;

733 foldExplicitTemplateInstantiation(

734 Builder.getTemplateRange(C),

735 Builder.findToken(C->getExternKeywordLoc()),

736 Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C);

737 return true;

738 }

739

740 bool WalkUpFromTemplateDecl(TemplateDecl *S) {

741 foldTemplateDeclaration(

742 Builder.getDeclarationRange(S),

745 return true;

746 }

747

748 bool WalkUpFromTagDecl(TagDecl *C) {

749

750 if (C->isFreeStanding()) {

751 assert(C->getNumTemplateParameterLists() == 0);

752 return true;

753 }

754 handleFreeStandingTagDecl(C);

755 return true;

756 }

757

759 assert(C->isFreeStanding());

760

761 auto DeclarationRange = Builder.getDeclarationRange(C);

763 Builder.foldNode(DeclarationRange, Result, nullptr);

764

765

766 auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) {

767 const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());

768 auto R = llvm::ArrayRef(TemplateKW, DeclarationRange.end());

770 foldTemplateDeclaration(R, TemplateKW, DeclarationRange, nullptr);

771 DeclarationRange = R;

772 };

773 if (auto *S = dyn_cast(C))

774 ConsumeTemplateParameters(*S->getTemplateParameters());

775 for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I)

776 ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1));

778 }

779

780 bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {

781

782

783 return true;

784 }

785

786 bool WalkUpFromCompoundStmt(CompoundStmt *S) {

788

789 Builder.markChildToken(S->getLBracLoc(), NodeRole::OpenParen);

790 for (auto *Child : S->body())

791 Builder.markStmtChild(Child, NodeRole::Statement);

792 Builder.markChildToken(S->getRBracLoc(), NodeRole::CloseParen);

793

794 Builder.foldNode(Builder.getStmtRange(S),

795 new (allocator()) syntax::CompoundStatement, S);

796 return true;

797 }

798

799

801 Builder.foldNode(Builder.getStmtRange(S),

802 new (allocator()) syntax::UnknownStatement, S);

803 return true;

804 }

805

806 bool TraverseIfStmt(IfStmt *S) {

807 bool Result = [&, this]() {

809 return false;

810 }

811

812

813

816 return false;

817 } else if (S->getCond() && !TraverseStmt(S->getCond()))

818 return false;

819

821 return false;

823 return false;

824 return true;

825 }();

828 }

829

830 bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {

831

832

833

834

835 bool Result = [&, this]() {

837 return false;

839 return false;

841 return false;

843 return false;

844 return true;

845 }();

848 }

849

851 if (auto *DS = dyn_cast_or_null(S)) {

852

853 for (auto *D : DS->decls())

854 Builder.noticeDeclWithoutSemicolon(D);

855 } else if (auto *E = dyn_cast_or_null(S)) {

857 }

859 }

860

861 bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {

862

863 return true;

864 }

865

866

867 bool WalkUpFromExpr(Expr *E) {

868 assert(isImplicitExpr(E) && "should be handled by TraverseStmt");

869 Builder.foldNode(Builder.getExprRange(E),

870 new (allocator()) syntax::UnknownExpression, E);

871 return true;

872 }

873

874 bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {

875

876

877

878

879

880 return WalkUpFromUserDefinedLiteral(S);

881 }

882

883 syntax::UserDefinedLiteralExpression *

884 buildUserDefinedLiteral(UserDefinedLiteral *S) {

887 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;

889 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;

891 return new (allocator()) syntax::CharUserDefinedLiteralExpression;

893 return new (allocator()) syntax::StringUserDefinedLiteralExpression;

896

897

898

899

901 auto TokSpelling =

904 NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(),

907 if (Literal.isIntegerLiteral())

908 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;

909 else {

910 assert(Literal.isFloatingLiteral());

911 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;

912 }

913 }

914 llvm_unreachable("Unknown literal operator kind.");

915 }

916

917 bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {

918 Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);

919 Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);

920 return true;

921 }

922

923 syntax::NameSpecifier *buildIdentifier(SourceRange SR,

924 bool DropBack = false) {

925 auto NameSpecifierTokens = Builder.getRange(SR).drop_back(DropBack);

926 assert(NameSpecifierTokens.size() == 1);

927 Builder.markChildToken(NameSpecifierTokens.begin(),

928 syntax::NodeRole::Unknown);

929 auto *NS = new (allocator()) syntax::IdentifierNameSpecifier;

930 Builder.foldNode(NameSpecifierTokens, NS, nullptr);

931 return NS;

932 }

933

934 syntax::NameSpecifier *buildSimpleTemplateName(SourceRange SR) {

935 auto NameSpecifierTokens = Builder.getRange(SR);

936

937

938

939

940

941 auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier;

942 Builder.foldNode(NameSpecifierTokens, NS, nullptr);

943 return NS;

944 }

945

946 syntax::NameSpecifier *

947 buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {

950 case NestedNameSpecifier::Kind::Global:

951 return new (allocator()) syntax::GlobalNameSpecifier;

952

953 case NestedNameSpecifier::Kind::Namespace:

955

959 case TypeLoc::Record:

960 case TypeLoc::InjectedClassName:

961 case TypeLoc::Enum:

963 case TypeLoc::Typedef:

965 case TypeLoc::UnresolvedUsing:

966 return buildIdentifier(

968 case TypeLoc::Using:

970 case TypeLoc::DependentName:

972 case TypeLoc::TemplateSpecialization: {

974 SourceLocation BeginLoc = TST.getTemplateKeywordLoc();

975 if (BeginLoc.isInvalid())

976 BeginLoc = TST.getTemplateNameLoc();

977 return buildSimpleTemplateName({BeginLoc, TST.getEndLoc()});

978 }

979 case TypeLoc::Decltype: {

981 if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(

982 DTL, true))

983 return nullptr;

984 auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;

985

986

987

988

989 Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,

990 nullptr);

991 return NS;

992 }

993 default:

995 }

996 }

998

999 llvm::report_fatal_error("We don't yet support the __super specifier",

1000 true);

1001 }

1002 }

1003

1004

1005

1006

1007

1009 if (!QualifierLoc)

1010 return true;

1011 for (auto It = QualifierLoc; It; ) {

1012 auto *NS = buildNameSpecifier(It);

1013 if (!NS)

1014 return false;

1017 if (TypeLoc TL = It.getAsTypeLoc())

1018 It = TL.getPrefix();

1019 else

1020 It = It.getAsNamespaceAndPrefix().Prefix;

1021 }

1022 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),

1024 QualifierLoc);

1025 return true;

1026 }

1027

1031 ASTPtr From) {

1032 if (QualifierLoc) {

1034 if (TemplateKeywordLoc.isValid())

1035 Builder.markChildToken(TemplateKeywordLoc,

1037 }

1038

1040 Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,

1041 nullptr);

1043

1044 auto IdExpressionBeginLoc =

1045 QualifierLoc ? QualifierLoc.getBeginLoc() : UnqualifiedIdLoc.getBegin();

1046

1047 auto *TheIdExpression = new (allocator()) syntax::IdExpression;

1048 Builder.foldNode(

1049 Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.getEnd()),

1050 TheIdExpression, From);

1051

1052 return TheIdExpression;

1053 }

1054

1056

1057

1058

1062 return true;

1063 }

1064

1068

1070

1073

1074 Builder.foldNode(Builder.getExprRange(S),

1075 new (allocator()) syntax::MemberExpression, S);

1076 return true;

1077 }

1078

1082

1083 return true;

1084 }

1085

1086

1090

1091 return true;

1092 }

1093

1096 Builder.markChildToken(S->getLocation(),

1098 Builder.foldNode(Builder.getExprRange(S),

1099 new (allocator()) syntax::ThisExpression, S);

1100 }

1101 return true;

1102 }

1103

1108 Builder.foldNode(Builder.getExprRange(S),

1109 new (allocator()) syntax::ParenExpression, S);

1110 return true;

1111 }

1112

1115 Builder.foldNode(Builder.getExprRange(S),

1116 new (allocator()) syntax::IntegerLiteralExpression, S);

1117 return true;

1118 }

1119

1122 Builder.foldNode(Builder.getExprRange(S),

1123 new (allocator()) syntax::CharacterLiteralExpression, S);

1124 return true;

1125 }

1126

1129 Builder.foldNode(Builder.getExprRange(S),

1130 new (allocator()) syntax::FloatingLiteralExpression, S);

1131 return true;

1132 }

1133

1136 Builder.foldNode(Builder.getExprRange(S),

1137 new (allocator()) syntax::StringLiteralExpression, S);

1138 return true;

1139 }

1140

1143 Builder.foldNode(Builder.getExprRange(S),

1144 new (allocator()) syntax::BoolLiteralExpression, S);

1145 return true;

1146 }

1147

1150 Builder.foldNode(Builder.getExprRange(S),

1151 new (allocator()) syntax::CxxNullPtrExpression, S);

1152 return true;

1153 }

1154

1159

1161 Builder.foldNode(Builder.getExprRange(S),

1163 S);

1164 else

1165 Builder.foldNode(Builder.getExprRange(S),

1167 S);

1168

1169 return true;

1170 }

1171

1177 Builder.foldNode(Builder.getExprRange(S),

1179 return true;

1180 }

1181

1182

1183

1184 syntax::CallArguments *

1187 for (auto *Arg : Args) {

1189 const auto *DelimiterToken =

1190 std::next(Builder.findToken(Arg->getEndLoc()));

1191 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)

1193 }

1194

1196 if (!Args.empty())

1197 Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),

1198 (*(Args.end() - 1))->getEndLoc()),

1199 Arguments, nullptr);

1200

1201 return Arguments;

1202 }

1203

1206

1207 const auto *LParenToken =

1209

1210

1211 if (LParenToken->kind() == clang::tok::l_paren)

1213

1216

1218

1219 Builder.foldNode(Builder.getRange(S->getSourceRange()),

1220 new (allocator()) syntax::CallExpression, S);

1221 return true;

1222 }

1223

1225

1228 return true;

1229 return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);

1230 }

1231

1233

1234

1235

1236

1237 for (auto *child : S->arguments()) {

1238

1239

1240

1241

1242

1243

1244 if (child->getSourceRange().isInvalid()) {

1246 syntax::NodeKind::PostfixUnaryOperatorExpression);

1247 continue;

1248 }

1250 return false;

1251 }

1253 }

1254

1257 case syntax::NodeKind::BinaryOperatorExpression:

1262 Builder.foldNode(Builder.getExprRange(S),

1264 return true;

1265 case syntax::NodeKind::PrefixUnaryOperatorExpression:

1269 Builder.foldNode(Builder.getExprRange(S),

1271 S);

1272 return true;

1273 case syntax::NodeKind::PostfixUnaryOperatorExpression:

1277 Builder.foldNode(Builder.getExprRange(S),

1279 S);

1280 return true;

1281 case syntax::NodeKind::CallExpression: {

1283

1284 const auto *LParenToken =

1285 std::next(Builder.findToken(S->getArg(0)->getEndLoc()));

1286

1287

1288 if (LParenToken->kind() == clang::tok::l_paren)

1290

1294

1296

1297 Builder.foldNode(Builder.getRange(S->getSourceRange()),

1298 new (allocator()) syntax::CallExpression, S);

1299 return true;

1300 }

1301 case syntax::NodeKind::UnknownExpression:

1302 return WalkUpFromExpr(S);

1303 default:

1304 llvm_unreachable("getOperatorNodeKind() does not return this value");

1305 }

1306 }

1307

1309

1311 auto Tokens = Builder.getDeclarationRange(S);

1312 if (Tokens.front().kind() == tok::coloncolon) {

1313

1314

1315

1316 return true;

1317 }

1319 return true;

1320 }

1321

1322

1323

1325

1327 return false;

1329 }

1330

1338

1339

1348

1349 syntax::ParameterDeclarationList *

1351 for (auto *P : Params) {

1353 const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));

1354 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)

1356 }

1358 if (!Params.empty())

1359 Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),

1360 Params.back()->getEndLoc()),

1361 Parameters, nullptr);

1362 return Parameters;

1363 }

1364

1367

1370

1374 return true;

1375 }

1376

1380

1381 auto *TrailingReturnTokens = buildTrailingReturn(L);

1382

1385 }

1386

1388 bool TraverseQualifier) {

1389

1390

1391

1392

1394 return false;

1396 }

1397

1400 Builder.foldNode(Builder.getRange(SR),

1402 return true;

1403 }

1404

1405

1406

1407

1409 Builder.foldNode(Builder.getStmtRange(S),

1411 return true;

1412 }

1413

1415 Builder.foldNode(Builder.getStmtRange(S),

1417 return true;

1418 }

1419

1424 Builder.foldNode(Builder.getStmtRange(S),

1426 return true;

1427 }

1428

1434 Builder.foldNode(Builder.getStmtRange(S),

1436 return true;

1437 }

1438

1443 Builder.foldNode(Builder.getStmtRange(S),

1445 return true;

1446 }

1447

1450 Stmt *ConditionStatement = S->getCond();

1457 Builder.foldNode(Builder.getStmtRange(S),

1459 return true;

1460 }

1461

1465 Builder.foldNode(Builder.getStmtRange(S),

1467 return true;

1468 }

1469

1471 Builder.markChildToken(S->getWhileLoc(),

1474 Builder.foldNode(Builder.getStmtRange(S),

1476 return true;

1477 }

1478

1481 Builder.foldNode(Builder.getStmtRange(S),

1483 return true;

1484 }

1485

1488 Builder.foldNode(Builder.getStmtRange(S),

1490 return true;

1491 }

1492

1497 Builder.foldNode(Builder.getStmtRange(S),

1499 return true;

1500 }

1501

1505 Builder.foldNode(Builder.getStmtRange(S),

1507 return true;

1508 }

1509

1511 Builder.foldNode(Builder.getDeclarationRange(S),

1513 return true;

1514 }

1515

1519 Builder.foldNode(Builder.getDeclarationRange(S),

1521 return true;

1522 }

1523

1525 Builder.foldNode(Builder.getDeclarationRange(S),

1527 S);

1528 return true;

1529 }

1530

1532 Builder.foldNode(Builder.getDeclarationRange(S),

1534 return true;

1535 }

1536

1538 Builder.foldNode(Builder.getDeclarationRange(S),

1540 return true;

1541 }

1542

1544 Builder.foldNode(Builder.getDeclarationRange(S),

1546 return true;

1547 }

1548

1550 Builder.foldNode(Builder.getDeclarationRange(S),

1552 return true;

1553 }

1554

1556 Builder.foldNode(Builder.getDeclarationRange(S),

1558 return true;

1559 }

1560

1562 Builder.foldNode(Builder.getDeclarationRange(S),

1564 return true;

1565 }

1566

1567private:

1568

1569

1570 template bool processDeclaratorAndDeclaration(T *D) {

1571 auto Range = getDeclaratorRange(

1572 Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),

1574

1575

1576

1577 if (Range.getBegin().isValid()) {

1578 Builder.markChild(new (allocator()) syntax::DeclaratorList,

1579 syntax::NodeRole::Declarators);

1580 Builder.foldNode(Builder.getDeclarationRange(D),

1581 new (allocator()) syntax::SimpleDeclaration, D);

1582 return true;

1583 }

1584

1585 auto *N = new (allocator()) syntax::SimpleDeclarator;

1586 Builder.foldNode(Builder.getRange(Range), N, nullptr);

1587 Builder.markChild(N, syntax::NodeRole::ListElement);

1588

1589 if (!Builder.isResponsibleForCreatingDeclaration(D)) {

1590

1591

1592 const auto *DelimiterToken = std::next(Builder.findToken(Range.getEnd()));

1593 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)

1594 Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);

1595 } else {

1596 auto *DL = new (allocator()) syntax::DeclaratorList;

1597 auto DeclarationRange = Builder.getDeclarationRange(D);

1598 Builder.foldList(DeclarationRange, DL, nullptr);

1599

1600 Builder.markChild(DL, syntax::NodeRole::Declarators);

1601 Builder.foldNode(DeclarationRange,

1602 new (allocator()) syntax::SimpleDeclaration, D);

1603 }

1604 return true;

1605 }

1606

1607

1608 syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {

1610

1612

1613 auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),

1614 ReturnedType.getEndLoc());

1615 syntax::SimpleDeclarator *ReturnDeclarator = nullptr;

1616 if (ReturnDeclaratorRange.isValid()) {

1617 ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator;

1618 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),

1619 ReturnDeclarator, nullptr);

1620 }

1621

1622

1623 auto Return = Builder.getRange(ReturnedType.getSourceRange());

1624 const auto *Arrow = Return.begin() - 1;

1625 assert(Arrow->kind() == tok::arrow);

1626 auto Tokens = llvm::ArrayRef(Arrow, Return.end());

1627 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);

1628 if (ReturnDeclarator)

1629 Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);

1630 auto *R = new (allocator()) syntax::TrailingReturnType;

1631 Builder.foldNode(Tokens, R, L);

1632 return R;

1633 }

1634

1635 void foldExplicitTemplateInstantiation(

1636 ArrayRefsyntax::Token Range, const syntax::Token *ExternKW,

1637 const syntax::Token *TemplateKW,

1638 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {

1639 assert(!ExternKW || ExternKW->kind() == tok::kw_extern);

1640 assert(TemplateKW && TemplateKW->kind() == tok::kw_template);

1641 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);

1642 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);

1643 Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);

1644 Builder.foldNode(

1645 Range, new (allocator()) syntax::ExplicitTemplateInstantiation, From);

1646 }

1647

1648 syntax::TemplateDeclaration *foldTemplateDeclaration(

1649 ArrayRefsyntax::Token Range, const syntax::Token *TemplateKW,

1650 ArrayRefsyntax::Token TemplatedDeclaration, Decl *From) {

1651 assert(TemplateKW && TemplateKW->kind() == tok::kw_template);

1652 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);

1653

1654 auto *N = new (allocator()) syntax::TemplateDeclaration;

1655 Builder.foldNode(Range, N, From);

1656 Builder.markChild(N, syntax::NodeRole::Declaration);

1657 return N;

1658 }

1659

1660

1661 llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); }

1662

1663 syntax::TreeBuilder &Builder;

1664 const ASTContext &Context;

1665};

1666}

1667

1668void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) {

1669 DeclsWithoutSemicolons.insert(D);

1670}

1671

1672void syntax::TreeBuilder::markChildToken(SourceLocation Loc, NodeRole Role) {

1674 return;

1675 Pending.assignRole(*findToken(Loc), Role);

1676}

1677

1678void syntax::TreeBuilder::markChildToken(const syntax::Token *T, NodeRole R) {

1679 if (T)

1680 return;

1681 Pending.assignRole(*T, R);

1682}

1683

1684void syntax::TreeBuilder::markChild(syntax::Node *N, NodeRole R) {

1685 assert(N);

1686 setRole(N, R);

1687}

1688

1689void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {

1690 auto *SN = Mapping.find(N);

1691 assert(SN != nullptr);

1692 setRole(SN, R);

1693}

1695 auto *SN = Mapping.find(NNSLoc);

1696 assert(SN != nullptr);

1697 setRole(SN, R);

1698}

1699

1700void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) {

1701 if (!Child)

1702 return;

1703

1705 if (Expr *ChildExpr = dyn_cast(Child)) {

1706

1707

1708 markExprChild(ChildExpr, NodeRole::Expression);

1710

1711 Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);

1712 } else {

1713 ChildNode = Mapping.find(Child);

1714 }

1715 assert(ChildNode != nullptr);

1716 setRole(ChildNode, Role);

1717}

1718

1719void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) {

1720 if (!Child)

1721 return;

1723

1724 syntax::Tree *ChildNode = Mapping.find(Child);

1725 assert(ChildNode != nullptr);

1726 setRole(ChildNode, Role);

1727}

1728

1731 return nullptr;

1732 auto It = LocationToToken.find(L);

1733 assert(It != LocationToToken.end());

1734 return It->second;

1735}

1736

1740 TreeBuilder Builder(A, TBTM);

1741 BuildTreeVisitor(Context, Builder).TraverseAST(Context);

1742 return std::move(Builder).finalize();

1743}

Forward declaration of all AST node types.

bool WalkUpFromStringLiteral(StringLiteral *S)

Definition BuildTree.cpp:1134

bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S)

Definition BuildTree.cpp:1537

bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L)

Definition BuildTree.cpp:1365

bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S)

Definition BuildTree.cpp:1549

bool WalkUpFromParenExpr(ParenExpr *S)

Definition BuildTree.cpp:1104

bool WalkUpFromBreakStmt(BreakStmt *S)

Definition BuildTree.cpp:1486

bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S)

Definition BuildTree.cpp:1516

bool WalkUpFromFloatingLiteral(FloatingLiteral *S)

Definition BuildTree.cpp:1127

bool WalkUpFromCaseStmt(CaseStmt *S)

Definition BuildTree.cpp:1429

bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S)

Definition BuildTree.cpp:1524

syntax::ParameterDeclarationList * buildParameterDeclarationList(ArrayRef< ParmVarDecl * > Params)

Definition BuildTree.cpp:1350

bool WalkUpFromParenTypeLoc(ParenTypeLoc L)

Definition BuildTree.cpp:1331

bool WalkUpFromBinaryOperator(BinaryOperator *S)

Definition BuildTree.cpp:1172

bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S)

Definition BuildTree.cpp:1555

bool TraverseParenTypeLoc(ParenTypeLoc L, bool TraverseQualifier)

Definition BuildTree.cpp:1324

bool WalkUpFromCXXThisExpr(CXXThisExpr *S)

Definition BuildTree.cpp:1094

bool WalkUpFromDeclRefExpr(DeclRefExpr *S)

Definition BuildTree.cpp:1079

bool WalkUpFromSwitchStmt(SwitchStmt *S)

Definition BuildTree.cpp:1420

bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S)

Definition BuildTree.cpp:1561

bool WalkUpFromDeclStmt(DeclStmt *S)

Definition BuildTree.cpp:1408

bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S)

Definition BuildTree.cpp:1255

bool WalkUpFromWhileStmt(WhileStmt *S)

Definition BuildTree.cpp:1470

bool WalkUpFromNamespaceDecl(NamespaceDecl *S)

Definition BuildTree.cpp:1310

bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S)

Definition BuildTree.cpp:1308

bool WalkUpFromMemberExpr(MemberExpr *S)

Definition BuildTree.cpp:1055

bool WalkUpFromCharacterLiteral(CharacterLiteral *S)

Definition BuildTree.cpp:1120

static Expr * IgnoreImplicit(Expr *E)

Definition BuildTree.cpp:74

bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S)

Definition BuildTree.cpp:1087

bool WalkUpFromNullStmt(NullStmt *S)

Definition BuildTree.cpp:1414

syntax::IdExpression * buildIdExpression(NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKeywordLoc, SourceRange UnqualifiedIdLoc, ASTPtr From)

Definition BuildTree.cpp:1028

bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S)

Definition BuildTree.cpp:1232

bool WalkUpFromEmptyDecl(EmptyDecl *S)

Definition BuildTree.cpp:1510

bool WalkUpFromIntegerLiteral(IntegerLiteral *S)

Definition BuildTree.cpp:1113

static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args)

Definition BuildTree.cpp:154

static bool isImplicitExpr(Expr *E)

Definition BuildTree.cpp:81

bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S)

Definition BuildTree.cpp:1148

bool WalkUpFromUnaryOperator(UnaryOperator *S)

Definition BuildTree.cpp:1155

static Expr * IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E)

Definition BuildTree.cpp:66

bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S)

Definition BuildTree.cpp:1224

static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E)

Definition BuildTree.cpp:160

bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S)

Definition BuildTree.cpp:1502

bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L)

Definition BuildTree.cpp:1398

bool WalkUpFromUsingDecl(UsingDecl *S)

Definition BuildTree.cpp:1543

bool WalkUpFromReturnStmt(ReturnStmt *S)

Definition BuildTree.cpp:1493

bool WalkUpFromContinueStmt(ContinueStmt *S)

Definition BuildTree.cpp:1479

bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S)

Definition BuildTree.cpp:1531

bool WalkUpFromIfStmt(IfStmt *S)

Definition BuildTree.cpp:1448

bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L, bool TraverseQualifier)

Definition BuildTree.cpp:1387

static SourceLocation getQualifiedNameStart(NamedDecl *D)

Get the start of the qualified name.

Definition BuildTree.cpp:246

bool WalkUpFromCallExpr(CallExpr *S)

Definition BuildTree.cpp:1204

bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L)

Definition BuildTree.cpp:1377

bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L)

Definition BuildTree.cpp:1340

bool WalkUpFromDefaultStmt(DefaultStmt *S)

Definition BuildTree.cpp:1439

bool WalkUpFromForStmt(ForStmt *S)

Definition BuildTree.cpp:1462

static Expr * IgnoreImplicitConstructorSingleStep(Expr *E)

Definition BuildTree.cpp:47

bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S)

Definition BuildTree.cpp:1141

syntax::CallArguments * buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs)

Builds CallArguments syntax node from arguments that appear in source code, i.e. not default argument...

Definition BuildTree.cpp:1185

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

std::shared_ptr< TokenRole > Role

A token can have a special role that can carry extra information about the token's formatting.

FormatToken * Next

The next token in the unwrapped line.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Defines the clang::TokenKind enum and support functions.

Defines the clang::TypeLoc interface and its subclasses.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SourceManager & getSourceManager()

const LangOptions & getLangOpts() const

DiagnosticsEngine & getDiagnostics() const

const TargetInfo & getTargetInfo() const

Wrapper for source info for arrays.

SourceLocation getLBracketLoc() const

Expr * getSizeExpr() const

SourceLocation getRBracketLoc() const

A builtin binary operation expression such as "x + y" or "x <= y".

SourceLocation getOperatorLoc() const

BreakStmt - This represents a break.

A boolean literal, per ([C++ lex.bool] Boolean literals).

SourceLocation getLocation() const

Represents a call to a C++ constructor.

SourceRange getParenOrBraceRange() const

Expr * getArg(unsigned Arg)

Return the specified argument.

unsigned getNumArgs() const

Return the number of arguments to the constructor call.

A default argument (C++ [dcl.fct.default]).

CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...

SourceLocation getForLoc() const

VarDecl * getLoopVariable()

The null pointer literal (C++11 [lex.nullptr])

SourceLocation getLocation() const

A call to an overloaded operator written using operator syntax.

SourceLocation getOperatorLoc() const

Returns the location of the operator symbol in the expression.

OverloadedOperatorKind getOperator() const

Returns the kind of overloaded operator that this expression refers to.

SourceRange getSourceRange() const

Represents the this expression in C++.

SourceLocation getLocation() const

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

llvm::iterator_range< arg_iterator > arg_range

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this call.

SourceLocation getRParenLoc() const

CaseStmt - Represent a case statement.

SourceLocation getLocation() const

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

SourceLocation getLBracLoc() const

SourceLocation getRBracLoc() const

ContinueStmt - This represents a continue.

A reference to a declared variable, function, enum, etc.

SourceLocation getTemplateKeywordLoc() const

Retrieve the location of the template keyword preceding this name, if any.

NestedNameSpecifierLoc getQualifierLoc() const

If the name was qualified, retrieves the nested-name-specifier that precedes the name,...

SourceLocation getEndLoc() const LLVM_READONLY

SourceLocation getLocation() const

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

Decl - This represents one declaration (or definition), e.g.

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

Decl * getNextDeclInContext()

SourceLocation getLocation() const

SourceLocation getBeginLoc() const LLVM_READONLY

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

bool isIdentifier() const

Predicate functions for querying what type of name this is.

SourceLocation getNameLoc() const

A qualified reference to a name whose declaration cannot yet be resolved.

NestedNameSpecifierLoc getQualifierLoc() const

Retrieve the nested-name-specifier that qualifies the name, with source location information.

SourceLocation getLocation() const

Retrieve the location of the name within the expression.

SourceLocation getEndLoc() const LLVM_READONLY

SourceLocation getTemplateKeywordLoc() const

Retrieve the location of the template keyword preceding this name, if any.

SourceLocation getNameLoc() const

Represents an empty-declaration.

This represents one expression.

SourceLocation getLocation() const

ForStmt - This represents a 'for (init;cond;inc)' stmt.

SourceLocation getForLoc() const

bool hasTrailingReturn() const

Whether this function prototype has a trailing return type.

Wrapper for source info for functions.

ArrayRef< ParmVarDecl * > getParams() const

TypeLoc getReturnLoc() const

SourceLocation getLParenLoc() const

SourceLocation getRParenLoc() const

IfStmt - This represents an if/then/else.

SourceLocation getIfLoc() const

bool hasVarStorage() const

True if this IfStmt has storage for a variable declaration.

SourceLocation getElseLoc() const

DeclStmt * getConditionVariableDeclStmt()

If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...

const TypeClass * getTypePtr() const

SourceLocation getLocation() const

Retrieve the location of the literal.

Represents a linkage specification.

SourceLocation getKwLoc() const

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

SourceLocation getMemberLoc() const

getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'.

SourceLocation getOperatorLoc() const

SourceLocation getTemplateKeywordLoc() const

Retrieve the location of the template keyword preceding the member name, if any.

NestedNameSpecifierLoc getQualifierLoc() const

If the member name was qualified, retrieves the nested-name-specifier that precedes the member name,...

bool isImplicitAccess() const

Determine whether the base of this explicit is implicit.

SourceLocation getEndLoc() const LLVM_READONLY

Wrapper for source info for member pointers.

SourceRange getLocalSourceRange() const

This represents a decl that may have a name.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

Represents a C++ namespace alias.

Represent a C++ namespace.

A C++ nested-name-specifier augmented with source location information.

NestedNameSpecifier getNestedNameSpecifier() const

Retrieve the nested-name-specifier to which this instance refers.

SourceRange getSourceRange() const LLVM_READONLY

Retrieve the source range covering the entirety of this nested-name-specifier.

SourceLocation getBeginLoc() const

Retrieve the location of the beginning of this nested-name-specifier.

TypeLoc castAsTypeLoc() const

For a nested-name-specifier that refers to a type, retrieve the type with source-location information...

bool hasQualifier() const

Evaluates true when this nested-name-specifier location is non-empty.

SourceRange getLocalSourceRange() const

Retrieve the source range covering just the last part of this nested-name-specifier,...

@ Type

A type, stored as a Type*.

NullStmt - This is the null statement ";": C99 6.8.3p3.

ParenExpr - This represents a parenthesized expression, e.g.

SourceLocation getLParen() const

Get the location of the left parentheses '('.

const Expr * getSubExpr() const

SourceLocation getRParen() const

Get the location of the right parentheses ')'.

SourceLocation getRParenLoc() const

SourceLocation getLParenLoc() const

TypeLoc getInnerLoc() const

TypeLoc getPointeeLoc() const

A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...

bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)

Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...

bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)

Recursively visit a C++ nested-name-specifier with location information.

bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier=true)

Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...

bool WalkUpFromStmt(Stmt *S)

bool shouldTraversePostOrder() const

Return whether this visitor should traverse post-order.

ReturnStmt - This represents a return, optionally of an expression: return; return 4;.

SourceLocation getReturnLoc() const

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Represents a C++11 static_assert declaration.

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

StringLiteral - This represents a string literal expression, e.g.

SourceLocation getBeginLoc() const LLVM_READONLY

SourceLocation getKeywordLoc() const

SwitchStmt - This represents a 'switch' stmt.

SourceLocation getSwitchLoc() const

SourceLocation getNameLoc() const

NamedDecl * getTemplatedDecl() const

Get the underlying, templated declaration.

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

SourceLocation getTemplateLoc() const

Represents the declaration of a typedef-name via a C++11 alias-declaration.

Base wrapper for a particular "section" of type source info.

T castAs() const

Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.

SourceRange getLocalSourceRange() const

Get the local source range.

TypeLocClass getTypeLocClass() const

SourceLocation getEndLoc() const

Get the end source location.

Wrapper for source info for typedefs.

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

static bool isPostfix(Opcode Op)

isPostfix - Return true if this is a postfix operation, like x++.

SourceLocation getOperatorLoc() const

getOperatorLoc - Return the location of the operator.

Expr * getSubExpr() const

Wrapper for source info for unresolved typename using decls.

Represents a dependent using declaration which was marked with typename.

Represents a dependent using declaration which was not marked with typename.

LiteralOperatorKind getLiteralOperatorKind() const

Returns the kind of literal operator invocation which this expression represents.

SourceLocation getBeginLoc() const

@ LOK_String

operator "" X (const CharT *, size_t)

@ LOK_Raw

Raw form: operator "" X (const char *)

@ LOK_Floating

operator "" X (long double)

@ LOK_Integer

operator "" X (unsigned long long)

@ LOK_Template

Raw form: operator "" X<cs...> ()

@ LOK_Character

operator "" X (CharT)

Represents a C++ using-declaration.

Represents C++ using-directive.

Wrapper for source info for types used via transparent aliases.

WhileStmt - This represents a 'while' stmt.

SourceLocation getWhileLoc() const

A memory arena for syntax trees.

llvm::BumpPtrAllocator & getAllocator()

Array size specified inside a declarator.

Models arguments of a function call.

A semicolon in the top-level context. Does not declare anything.

The no-op statement, i.e. ';'.

Expression in a statement position, e.g.

for (; ; )

if (cond) else FIXME: add condition that models 'expression or vari...

extern declaration extern { }

Member pointer inside a declarator E.g.

namespace =

namespace { }

Models a nested-name-specifier.

Models a parameter-declaration-list which appears within parameters-and-qualifiers.

Parameter list for a function type and a trailing return type, if the function has one.

Declarator inside parentheses.

for ( : )

static_assert(, ) static_assert()

A TokenBuffer-powered token manager.

SourceManager & sourceManager()

llvm::ArrayRef< syntax::Token > expandedTokens() const

All tokens produced by the preprocessor after all macro replacements, directives, etc.

std::optional< llvm::ArrayRef< syntax::Token > > spelledForExpanded(llvm::ArrayRef< syntax::Token > Expanded) const

Returns the subrange of spelled tokens corresponding to AST node spanning Expanded.

A token coming directly from a file or from a macro invocation.

tok::TokenKind kind() const

A node that has children and represents a syntactic language construct.

Models an unqualified-id.

using :: using typename ::

uint32_t Literal

Literals are represented as positive integers.

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

NodeRole

A relation between a parent and child node, e.g.

@ ListElement

List API roles.

@ LiteralToken

A token that represents a literal, e.g. 'nullptr', '1', 'true', etc.

@ CloseParen

A closing parenthesis in argument lists and blocks, e.g. '}', ')', etc.

@ IntroducerKeyword

A keywords that introduces some grammar construct, e.g. 'if', 'try', etc.

@ BodyStatement

An inner statement for those that have only a single child of kind statement, e.g.

@ OpenParen

An opening parenthesis in argument lists and blocks, e.g. '{', '(', etc.

syntax::TranslationUnit * buildSyntaxTree(Arena &A, TokenBufferTokenManager &TBTM, ASTContext &Context)

Build a syntax tree for the main file.

Definition BuildTree.cpp:1737

NodeKind

A kind of a syntax node, used for implementing casts.

The JSON file list parser is used to communicate input to InstallAPI.

@ OO_None

Not an overloaded operator.

@ NUM_OVERLOADED_OPERATORS

bool isa(CodeGen::Address addr)

Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)

Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...

@ Result

The result type of a method or function.

const FunctionProtoType * T

Expr * IgnoreImplicitSingleStep(Expr *E)

void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)

U cast(CodeGen::Address addr)