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"
48 if (
auto *
C = dyn_cast<CXXConstructExpr>(E)) {
49 auto NumArgs =
C->getNumArgs();
51 Expr *A =
C->getArg(0);
52 if (
C->getParenOrBraceRange().isInvalid())
67 if (
auto *F = dyn_cast<CXXFunctionalCastExpr>(E)) {
68 if (F->getCastKind() == CK_ConstructorConversion)
69 return F->getSubExpr();
97 SourceLocation VisitParenTypeLoc(ParenTypeLoc
T) {
98 auto L = Visit(
T.getInnerLoc());
101 return T.getLParenLoc();
105 SourceLocation VisitPointerTypeLoc(PointerTypeLoc
T) {
106 return HandlePointer(
T);
109 SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc
T) {
110 return HandlePointer(
T);
113 SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc
T) {
114 return HandlePointer(
T);
117 SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc
T) {
118 return HandlePointer(
T);
121 SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc
T) {
122 return HandlePointer(
T);
129 SourceLocation VisitTypeLoc(TypeLoc
T) {
130 auto N =
T.getNextTypeLoc();
132 return SourceLocation();
136 SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc
T) {
138 return SourceLocation();
139 return VisitTypeLoc(
T);
143 template <
class PtrLoc> SourceLocation HandlePointer(PtrLoc
T) {
144 auto L = Visit(
T.getPointeeLoc());
147 return T.getLocalSourceRange().getBegin();
153 auto FirstDefaultArg =
155 return llvm::make_range(Args.begin(), FirstDefaultArg);
162 case OO_ExclaimEqual:
164 case OO_GreaterEqual:
171 case OO_PercentEqual:
174 case OO_LessLessEqual:
175 case OO_GreaterGreaterEqual:
186 case OO_GreaterGreater:
191 return syntax::NodeKind::BinaryOperatorExpression;
194 return syntax::NodeKind::PrefixUnaryOperatorExpression;
200 return syntax::NodeKind::PrefixUnaryOperatorExpression;
202 return syntax::NodeKind::PostfixUnaryOperatorExpression;
204 llvm_unreachable(
"Invalid number of arguments for operator");
213 return syntax::NodeKind::PrefixUnaryOperatorExpression;
215 return syntax::NodeKind::BinaryOperatorExpression;
217 llvm_unreachable(
"Invalid number of arguments for operator");
219 return syntax::NodeKind::BinaryOperatorExpression;
224 case OO_Array_Delete:
228 return syntax::NodeKind::UnknownExpression;
230 return syntax::NodeKind::CallExpression;
234 llvm_unreachable(
"Not an overloadable operator");
236 llvm_unreachable(
"Unknown OverloadedOperatorKind enum");
246 "only DeclaratorDecl and TypedefNameDecl are supported.");
249 bool IsAnonymous = DN.
isIdentifier() && !DN.getAsIdentifierInfo();
253 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
254 if (DD->getQualifierLoc()) {
255 return DD->getQualifierLoc().getBeginLoc();
268 if (
auto *
V = dyn_cast<VarDecl>(D)) {
269 auto *I =
V->getInit();
271 if (I && !
V->isCXXForRangeDecl())
272 return I->getSourceRange();
296 if (End.
isInvalid() ||
SM.isBeforeInTranslationUnit(End, Name))
301 assert(
SM.isBeforeInTranslationUnit(End, InitializerEnd) ||
302 End == InitializerEnd);
303 End = InitializerEnd;
310using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>;
314class ASTToSyntaxMapping {
316 void add(ASTPtr From, syntax::Tree *To) {
317 assert(To !=
nullptr);
318 assert(!From.isNull());
320 bool Added = Nodes.insert({From, To}).second;
322 assert(Added &&
"mapping added twice");
325 void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
326 assert(To !=
nullptr);
329 bool Added = NNSNodes.insert({From, To}).second;
331 assert(Added &&
"mapping added twice");
334 syntax::Tree *find(ASTPtr P)
const {
return Nodes.lookup(P); }
336 syntax::Tree *find(NestedNameSpecifierLoc P)
const {
337 return NNSNodes.lookup(P);
341 llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes;
342 llvm::DenseMap<NestedNameSpecifierLoc, syntax::Tree *> NNSNodes;
361class syntax::TreeBuilder {
363 TreeBuilder(syntax::Arena &Arena, TokenBufferTokenManager& TBTM)
366 Pending(Arena, TBTM.tokenBuffer()) {
367 for (
const auto &
T : TBTM.tokenBuffer().expandedTokens())
368 LocationToToken.insert({T.location(), &T});
371 llvm::BumpPtrAllocator &allocator() {
return Arena.
getAllocator(); }
372 const SourceManager &sourceManager()
const {
373 return TBTM.sourceManager();
378 void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *
New, ASTPtr From) {
380 Pending.foldChildren(TBTM.tokenBuffer(), Range,
New);
382 Mapping.add(From,
New);
385 void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *
New, TypeLoc L) {
387 foldNode(Range,
New,
nullptr);
390 void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *
New,
391 NestedNameSpecifierLoc From) {
393 Pending.foldChildren(TBTM.tokenBuffer(), Range,
New);
395 Mapping.add(From,
New);
400 void foldList(ArrayRef<syntax::Token> SuperRange, syntax::List *
New,
403 auto ListRange = Pending.shrinkToFitList(SuperRange);
404 Pending.foldChildren(TBTM.tokenBuffer(), ListRange,
New);
406 Mapping.add(From,
New);
411 void noticeDeclWithoutSemicolon(Decl *D);
417 void markStmtChild(Stmt *Child, NodeRole
Role);
420 void markExprChild(Expr *Child, NodeRole
Role);
422 void markChildToken(SourceLocation Loc, NodeRole R);
424 void markChildToken(
const syntax::Token *
T, NodeRole R);
427 void markChild(syntax::Node *N, NodeRole R);
429 void markChild(ASTPtr N, NodeRole R);
431 void markChild(NestedNameSpecifierLoc N, NodeRole R);
434 syntax::TranslationUnit *
finalize() && {
435 auto Tokens = TBTM.tokenBuffer().expandedTokens();
436 assert(!Tokens.empty());
437 assert(Tokens.back().kind() == tok::eof);
440 Pending.foldChildren(TBTM.tokenBuffer(), Tokens.drop_back(),
444 TU->assertInvariantsRecursive();
449 const syntax::Token *findToken(SourceLocation L)
const;
452 ArrayRef<syntax::Token>
getRange(SourceRange Range)
const {
453 assert(
Range.isValid());
461 SourceLocation
Last)
const {
462 assert(
First.isValid());
463 assert(
Last.isValid());
465 TBTM.sourceManager().isBeforeInTranslationUnit(
First,
Last));
466 return llvm::ArrayRef(findToken(
First), std::next(findToken(
Last)));
469 ArrayRef<syntax::Token>
470 getTemplateRange(
const ClassTemplateSpecializationDecl *D)
const {
472 return maybeAppendSemicolon(Tokens, D);
477 bool isResponsibleForCreatingDeclaration(
const Decl *D)
const {
479 "only DeclaratorDecl and TypedefNameDecl are supported.");
484 if (
Next ==
nullptr) {
503 ArrayRef<syntax::Token> getDeclarationRange(Decl *D) {
504 ArrayRef<syntax::Token> Tokens;
506 if (
const auto *S = dyn_cast<TagDecl>(D))
507 Tokens =
getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());
510 return maybeAppendSemicolon(Tokens, D);
513 ArrayRef<syntax::Token> getExprRange(
const Expr *E)
const {
519 ArrayRef<syntax::Token> getStmtRange(
const Stmt *S)
const {
526 if (Tokens.back().kind() == tok::semi)
528 return withTrailingSemicolon(Tokens);
532 ArrayRef<syntax::Token> maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,
533 const Decl *D)
const {
536 if (DeclsWithoutSemicolons.count(D))
540 return withTrailingSemicolon(Tokens);
543 ArrayRef<syntax::Token>
544 withTrailingSemicolon(ArrayRef<syntax::Token> Tokens)
const {
545 assert(!Tokens.empty());
546 assert(Tokens.back().kind() != tok::eof);
548 if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi)
549 return llvm::ArrayRef(Tokens.begin(), Tokens.end() + 1);
553 void setRole(syntax::Node *N, NodeRole R) {
554 assert(N->
getRole() == NodeRole::Detached);
565 Forest(syntax::Arena &A,
const syntax::TokenBuffer &TB) {
572 syntax::Leaf(
reinterpret_cast<TokenManager::Key
>(&
T));
575 Trees.insert(Trees.end(), {&T, L});
580 assert(!
Range.empty());
581 auto It = Trees.lower_bound(
Range.begin());
582 assert(It != Trees.end() &&
"no node found");
583 assert(It->first ==
Range.begin() &&
"no child with the specified range");
584 assert((std::next(It) == Trees.end() ||
585 std::next(It)->first ==
Range.end()) &&
586 "no child with the specified range");
587 assert(It->second->getRole() == NodeRole::Detached &&
588 "re-assigning role for a child");
589 It->second->setRole(
Role);
594 ArrayRef<syntax::Token> shrinkToFitList(ArrayRef<syntax::Token> Range) {
595 auto BeginChildren = Trees.lower_bound(
Range.begin());
596 assert((BeginChildren == Trees.end() ||
597 BeginChildren->first ==
Range.begin()) &&
598 "Range crosses boundaries of existing subtrees");
600 auto EndChildren = Trees.lower_bound(
Range.end());
602 (EndChildren == Trees.end() || EndChildren->first ==
Range.end()) &&
603 "Range crosses boundaries of existing subtrees");
605 auto BelongsToList = [](
decltype(Trees)::value_type KV) {
606 auto Role = KV.second->getRole();
607 return Role == syntax::NodeRole::ListElement ||
608 Role == syntax::NodeRole::ListDelimiter;
611 auto BeginListChildren =
612 std::find_if(BeginChildren, EndChildren, BelongsToList);
614 auto EndListChildren =
615 std::find_if_not(BeginListChildren, EndChildren, BelongsToList);
617 return ArrayRef<syntax::Token>(BeginListChildren->first,
618 EndListChildren->first);
622 void foldChildren(
const syntax::TokenBuffer &TB,
623 ArrayRef<syntax::Token> Tokens, syntax::Tree *Node) {
625 assert(Node->
getFirstChild() ==
nullptr &&
"node already has children");
627 auto *FirstToken = Tokens.begin();
628 auto BeginChildren = Trees.lower_bound(FirstToken);
630 assert((BeginChildren == Trees.end() ||
631 BeginChildren->first == FirstToken) &&
632 "fold crosses boundaries of existing subtrees");
633 auto EndChildren = Trees.lower_bound(Tokens.end());
635 (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&
636 "fold crosses boundaries of existing subtrees");
638 for (
auto It = BeginChildren; It != EndChildren; ++It) {
639 auto *
C = It->second;
640 if (
C->getRole() == NodeRole::Detached)
641 C->setRole(NodeRole::Unknown);
642 Node->appendChildLowLevel(
C);
646 Node->Original =
true;
650 Trees.erase(BeginChildren, EndChildren);
651 Trees.insert({FirstToken, Node});
656 assert(Trees.size() == 1);
657 auto *Root = Trees.begin()->second;
662 std::string str(
const syntax::TokenBufferTokenManager &STM)
const {
664 for (
auto It = Trees.begin(); It != Trees.end(); ++It) {
665 unsigned CoveredTokens =
667 ? (std::next(It)->first - It->first)
668 : STM.tokenBuffer().expandedTokens().end() - It->first;
671 formatv(
"- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(),
673 R += It->second->dump(STM);
682 std::map<const syntax::Token *, syntax::Node *> Trees;
686 std::string str() {
return Pending.str(TBTM); }
688 syntax::Arena &Arena;
689 TokenBufferTokenManager& TBTM;
691 llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken;
693 llvm::DenseSet<Decl *> DeclsWithoutSemicolons;
694 ASTToSyntaxMapping Mapping;
700 explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
701 : Builder(Builder), Context(Context) {}
705 bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {
706 return processDeclaratorAndDeclaration(DD);
709 bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) {
710 return processDeclaratorAndDeclaration(TD);
715 Builder.foldNode(Builder.getDeclarationRange(D),
716 new (allocator()) syntax::UnknownDeclaration(), D);
724 TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *
C) {
725 if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(
C))
727 if (
C->isExplicitSpecialization())
731 foldExplicitTemplateInstantiation(
732 Builder.getTemplateRange(
C),
733 Builder.findToken(
C->getExternKeywordLoc()),
734 Builder.findToken(
C->getTemplateKeywordLoc()),
Declaration,
C);
738 bool WalkUpFromTemplateDecl(TemplateDecl *S) {
739 foldTemplateDeclaration(
740 Builder.getDeclarationRange(S),
746 bool WalkUpFromTagDecl(TagDecl *
C) {
748 if (!
C->isFreeStanding()) {
749 assert(
C->getNumTemplateParameterLists() == 0);
752 handleFreeStandingTagDecl(
C);
757 assert(
C->isFreeStanding());
759 auto DeclarationRange = Builder.getDeclarationRange(
C);
761 Builder.foldNode(DeclarationRange,
Result,
nullptr);
764 auto ConsumeTemplateParameters = [&](
const TemplateParameterList &L) {
765 const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
766 auto R = llvm::ArrayRef(TemplateKW, DeclarationRange.end());
768 foldTemplateDeclaration(R, TemplateKW, DeclarationRange,
nullptr);
769 DeclarationRange = R;
771 if (
auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(
C))
772 ConsumeTemplateParameters(*S->getTemplateParameters());
773 for (
unsigned I =
C->getNumTemplateParameterLists(); 0 < I; --I)
774 ConsumeTemplateParameters(*
C->getTemplateParameterList(I - 1));
778 bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
787 Builder.markChildToken(S->
getLBracLoc(), NodeRole::OpenParen);
788 for (
auto *Child : S->
body())
789 Builder.markStmtChild(Child, NodeRole::Statement);
790 Builder.markChildToken(S->
getRBracLoc(), NodeRole::CloseParen);
792 Builder.foldNode(Builder.getStmtRange(S),
793 new (allocator()) syntax::CompoundStatement, S);
799 Builder.foldNode(Builder.getStmtRange(S),
800 new (allocator()) syntax::UnknownStatement, S);
804 bool TraverseIfStmt(IfStmt *S) {
805 bool Result = [&,
this]() {
828 bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
833 bool Result = [&,
this]() {
849 if (
auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
851 for (
auto *D : DS->decls())
852 Builder.noticeDeclWithoutSemicolon(D);
853 }
else if (
auto *E = dyn_cast_or_null<Expr>(S)) {
859 bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
865 bool WalkUpFromExpr(Expr *E) {
866 assert(!
isImplicitExpr(E) &&
"should be handled by TraverseStmt");
867 Builder.foldNode(Builder.getExprRange(E),
868 new (allocator()) syntax::UnknownExpression, E);
872 bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
878 return WalkUpFromUserDefinedLiteral(S);
881 syntax::UserDefinedLiteralExpression *
882 buildUserDefinedLiteral(UserDefinedLiteral *S) {
885 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
887 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
889 return new (allocator()) syntax::CharUserDefinedLiteralExpression;
891 return new (allocator()) syntax::StringUserDefinedLiteralExpression;
905 if (
Literal.isIntegerLiteral())
906 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
908 assert(
Literal.isFloatingLiteral());
909 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
912 llvm_unreachable(
"Unknown literal operator kind.");
915 bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
916 Builder.markChildToken(S->
getBeginLoc(), syntax::NodeRole::LiteralToken);
917 Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
921 syntax::NameSpecifier *buildIdentifier(SourceRange SR,
922 bool DropBack =
false) {
923 auto NameSpecifierTokens = Builder.getRange(SR).drop_back(DropBack);
924 assert(NameSpecifierTokens.size() == 1);
925 Builder.markChildToken(NameSpecifierTokens.begin(),
926 syntax::NodeRole::Unknown);
927 auto *NS =
new (allocator()) syntax::IdentifierNameSpecifier;
928 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
932 syntax::NameSpecifier *buildSimpleTemplateName(SourceRange SR) {
933 auto NameSpecifierTokens = Builder.getRange(SR);
939 auto *NS =
new (allocator()) syntax::SimpleTemplateNameSpecifier;
940 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
944 syntax::NameSpecifier *
945 buildNameSpecifier(
const NestedNameSpecifierLoc &NNSLoc) {
948 case NestedNameSpecifier::Kind::Global:
949 return new (allocator()) syntax::GlobalNameSpecifier;
951 case NestedNameSpecifier::Kind::Namespace:
957 case TypeLoc::Record:
958 case TypeLoc::InjectedClassName:
961 case TypeLoc::Typedef:
963 case TypeLoc::UnresolvedUsing:
964 return buildIdentifier(
968 case TypeLoc::DependentName:
970 case TypeLoc::TemplateSpecialization: {
973 if (BeginLoc.isInvalid())
974 BeginLoc = TST.getTemplateNameLoc();
975 return buildSimpleTemplateName({BeginLoc, TST.getEndLoc()});
977 case TypeLoc::DependentTemplateSpecialization: {
980 if (BeginLoc.isInvalid())
981 BeginLoc = DT.getTemplateNameLoc();
982 return buildSimpleTemplateName({BeginLoc, DT.getEndLoc()});
984 case TypeLoc::Decltype: {
986 if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(
989 auto *NS =
new (allocator()) syntax::DecltypeNameSpecifier;
994 Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,
1004 llvm::report_fatal_error(
"We don't yet support the __super specifier",
1016 for (
auto It = QualifierLoc; It; ) {
1017 auto *NS = buildNameSpecifier(It);
1022 if (
TypeLoc TL = It.getAsTypeLoc())
1023 It = TL.getPrefix();
1025 It = It.getAsNamespaceAndPrefix().Prefix;
1027 Builder.foldNode(Builder.getRange(QualifierLoc.
getSourceRange()),
1039 if (TemplateKeywordLoc.
isValid())
1040 Builder.markChildToken(TemplateKeywordLoc,
1045 Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1049 auto IdExpressionBeginLoc =
1052 auto *TheIdExpression =
new (allocator()) syntax::IdExpression;
1054 Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.
getEnd()),
1055 TheIdExpression, From);
1057 return TheIdExpression;
1079 Builder.foldNode(Builder.getExprRange(S),
1080 new (allocator()) syntax::MemberExpression, S);
1103 Builder.foldNode(Builder.getExprRange(S),
1104 new (allocator()) syntax::ThisExpression, S);
1113 Builder.foldNode(Builder.getExprRange(S),
1114 new (allocator()) syntax::ParenExpression, S);
1120 Builder.foldNode(Builder.getExprRange(S),
1121 new (allocator()) syntax::IntegerLiteralExpression, S);
1127 Builder.foldNode(Builder.getExprRange(S),
1128 new (allocator()) syntax::CharacterLiteralExpression, S);
1134 Builder.foldNode(Builder.getExprRange(S),
1135 new (allocator()) syntax::FloatingLiteralExpression, S);
1141 Builder.foldNode(Builder.getExprRange(S),
1142 new (allocator()) syntax::StringLiteralExpression, S);
1148 Builder.foldNode(Builder.getExprRange(S),
1149 new (allocator()) syntax::BoolLiteralExpression, S);
1155 Builder.foldNode(Builder.getExprRange(S),
1156 new (allocator()) syntax::CxxNullPtrExpression, S);
1166 Builder.foldNode(Builder.getExprRange(S),
1170 Builder.foldNode(Builder.getExprRange(S),
1182 Builder.foldNode(Builder.getExprRange(S),
1189 syntax::CallArguments *
1192 for (
auto *Arg : Args) {
1194 const auto *DelimiterToken =
1195 std::next(Builder.findToken(Arg->getEndLoc()));
1196 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1202 Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1203 (*(Args.end() - 1))->getEndLoc()),
1204 Arguments,
nullptr);
1212 const auto *LParenToken =
1216 if (LParenToken->kind() == clang::tok::l_paren)
1225 new (allocator()) syntax::CallExpression, S);
1234 return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1249 if (child->getSourceRange().isInvalid()) {
1251 syntax::NodeKind::PostfixUnaryOperatorExpression);
1262 case syntax::NodeKind::BinaryOperatorExpression:
1267 Builder.foldNode(Builder.getExprRange(S),
1270 case syntax::NodeKind::PrefixUnaryOperatorExpression:
1274 Builder.foldNode(Builder.getExprRange(S),
1278 case syntax::NodeKind::PostfixUnaryOperatorExpression:
1282 Builder.foldNode(Builder.getExprRange(S),
1286 case syntax::NodeKind::CallExpression: {
1289 const auto *LParenToken =
1293 if (LParenToken->kind() == clang::tok::l_paren)
1303 new (allocator()) syntax::CallExpression, S);
1306 case syntax::NodeKind::UnknownExpression:
1307 return WalkUpFromExpr(S);
1309 llvm_unreachable(
"getOperatorNodeKind() does not return this value");
1316 auto Tokens = Builder.getDeclarationRange(S);
1317 if (Tokens.front().kind() == tok::coloncolon) {
1354 syntax::ParameterDeclarationList *
1356 for (
auto *P : Params) {
1358 const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1359 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1363 if (!Params.empty())
1364 Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1365 Params.back()->getEndLoc()),
1366 Parameters,
nullptr);
1386 auto *TrailingReturnTokens = buildTrailingReturn(L);
1393 bool TraverseQualifier) {
1405 Builder.foldNode(Builder.getRange(SR),
1414 Builder.foldNode(Builder.getStmtRange(S),
1420 Builder.foldNode(Builder.getStmtRange(S),
1429 Builder.foldNode(Builder.getStmtRange(S),
1439 Builder.foldNode(Builder.getStmtRange(S),
1448 Builder.foldNode(Builder.getStmtRange(S),
1462 Builder.foldNode(Builder.getStmtRange(S),
1470 Builder.foldNode(Builder.getStmtRange(S),
1479 Builder.foldNode(Builder.getStmtRange(S),
1486 Builder.foldNode(Builder.getStmtRange(S),
1493 Builder.foldNode(Builder.getStmtRange(S),
1502 Builder.foldNode(Builder.getStmtRange(S),
1510 Builder.foldNode(Builder.getStmtRange(S),
1516 Builder.foldNode(Builder.getDeclarationRange(S),
1524 Builder.foldNode(Builder.getDeclarationRange(S),
1530 Builder.foldNode(Builder.getDeclarationRange(S),
1537 Builder.foldNode(Builder.getDeclarationRange(S),
1543 Builder.foldNode(Builder.getDeclarationRange(S),
1549 Builder.foldNode(Builder.getDeclarationRange(S),
1555 Builder.foldNode(Builder.getDeclarationRange(S),
1561 Builder.foldNode(Builder.getDeclarationRange(S),
1567 Builder.foldNode(Builder.getDeclarationRange(S),
1575 template <
class T>
bool processDeclaratorAndDeclaration(
T *D) {
1576 auto Range = getDeclaratorRange(
1577 Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1582 if (!
Range.getBegin().isValid()) {
1583 Builder.markChild(
new (allocator()) syntax::DeclaratorList,
1584 syntax::NodeRole::Declarators);
1585 Builder.foldNode(Builder.getDeclarationRange(D),
1586 new (allocator()) syntax::SimpleDeclaration, D);
1590 auto *N =
new (allocator()) syntax::SimpleDeclarator;
1591 Builder.foldNode(Builder.getRange(Range), N,
nullptr);
1592 Builder.markChild(N, syntax::NodeRole::ListElement);
1594 if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1597 const auto *DelimiterToken = std::next(Builder.findToken(
Range.getEnd()));
1598 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1599 Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1601 auto *DL =
new (allocator()) syntax::DeclaratorList;
1602 auto DeclarationRange = Builder.getDeclarationRange(D);
1603 Builder.foldList(DeclarationRange, DL,
nullptr);
1605 Builder.markChild(DL, syntax::NodeRole::Declarators);
1606 Builder.foldNode(DeclarationRange,
1607 new (allocator()) syntax::SimpleDeclaration, D);
1613 syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1618 auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1619 ReturnedType.getEndLoc());
1620 syntax::SimpleDeclarator *ReturnDeclarator =
nullptr;
1621 if (ReturnDeclaratorRange.isValid()) {
1622 ReturnDeclarator =
new (allocator()) syntax::SimpleDeclarator;
1623 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1624 ReturnDeclarator,
nullptr);
1628 auto Return = Builder.getRange(ReturnedType.getSourceRange());
1629 const auto *Arrow = Return.begin() - 1;
1630 assert(Arrow->kind() == tok::arrow);
1631 auto Tokens = llvm::ArrayRef(Arrow, Return.end());
1632 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1633 if (ReturnDeclarator)
1634 Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1635 auto *R =
new (allocator()) syntax::TrailingReturnType;
1636 Builder.foldNode(Tokens, R, L);
1640 void foldExplicitTemplateInstantiation(
1641 ArrayRef<syntax::Token> Range,
const syntax::Token *ExternKW,
1642 const syntax::Token *TemplateKW,
1643 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1644 assert(!ExternKW || ExternKW->
kind() == tok::kw_extern);
1645 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1646 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1647 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1648 Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1650 Range,
new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1653 syntax::TemplateDeclaration *foldTemplateDeclaration(
1654 ArrayRef<syntax::Token> Range,
const syntax::Token *TemplateKW,
1655 ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1656 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1657 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1659 auto *N =
new (allocator()) syntax::TemplateDeclaration;
1660 Builder.foldNode(Range, N, From);
1661 Builder.markChild(N, syntax::NodeRole::Declaration);
1666 llvm::BumpPtrAllocator &allocator() {
return Builder.allocator(); }
1668 syntax::TreeBuilder &Builder;
1669 const ASTContext &Context;
1673void syntax::TreeBuilder::noticeDeclWithoutSemicolon(
Decl *D) {
1674 DeclsWithoutSemicolons.insert(D);
1680 Pending.assignRole(*findToken(Loc),
Role);
1683void syntax::TreeBuilder::markChildToken(
const syntax::Token *
T, NodeRole R) {
1686 Pending.assignRole(*
T, R);
1689void syntax::TreeBuilder::markChild(
syntax::Node *N, NodeRole R) {
1694void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1695 auto *SN = Mapping.find(N);
1696 assert(SN !=
nullptr);
1700 auto *SN = Mapping.find(NNSLoc);
1701 assert(SN !=
nullptr);
1705void syntax::TreeBuilder::markStmtChild(
Stmt *Child, NodeRole
Role) {
1710 if (
Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1713 markExprChild(ChildExpr, NodeRole::Expression);
1716 Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);
1718 ChildNode = Mapping.find(Child);
1720 assert(ChildNode !=
nullptr);
1721 setRole(ChildNode,
Role);
1724void syntax::TreeBuilder::markExprChild(
Expr *Child, NodeRole
Role) {
1730 assert(ChildNode !=
nullptr);
1731 setRole(ChildNode,
Role);
1737 auto It = LocationToToken.find(L);
1738 assert(It != LocationToToken.end());
1745 TreeBuilder Builder(A, TBTM);
1746 BuildTreeVisitor(Context, Builder).TraverseAST(Context);
1747 return std::move(Builder).finalize();
Forward declaration of all AST node types.
bool WalkUpFromStringLiteral(StringLiteral *S)
bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S)
bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L)
bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S)
bool WalkUpFromParenExpr(ParenExpr *S)
bool WalkUpFromBreakStmt(BreakStmt *S)
bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S)
bool WalkUpFromFloatingLiteral(FloatingLiteral *S)
bool WalkUpFromCaseStmt(CaseStmt *S)
bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S)
syntax::ParameterDeclarationList * buildParameterDeclarationList(ArrayRef< ParmVarDecl * > Params)
bool WalkUpFromParenTypeLoc(ParenTypeLoc L)
bool WalkUpFromBinaryOperator(BinaryOperator *S)
bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S)
bool TraverseParenTypeLoc(ParenTypeLoc L, bool TraverseQualifier)
bool WalkUpFromCXXThisExpr(CXXThisExpr *S)
bool WalkUpFromDeclRefExpr(DeclRefExpr *S)
bool WalkUpFromSwitchStmt(SwitchStmt *S)
bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S)
bool WalkUpFromDeclStmt(DeclStmt *S)
bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S)
bool WalkUpFromWhileStmt(WhileStmt *S)
bool WalkUpFromNamespaceDecl(NamespaceDecl *S)
bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S)
bool WalkUpFromMemberExpr(MemberExpr *S)
bool WalkUpFromCharacterLiteral(CharacterLiteral *S)
static Expr * IgnoreImplicit(Expr *E)
bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S)
bool WalkUpFromNullStmt(NullStmt *S)
syntax::IdExpression * buildIdExpression(NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKeywordLoc, SourceRange UnqualifiedIdLoc, ASTPtr From)
bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S)
bool WalkUpFromEmptyDecl(EmptyDecl *S)
bool WalkUpFromIntegerLiteral(IntegerLiteral *S)
static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args)
bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S)
static LLVM_ATTRIBUTE_UNUSED bool isImplicitExpr(Expr *E)
bool WalkUpFromUnaryOperator(UnaryOperator *S)
static Expr * IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E)
bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S)
static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E)
bool WalkUpFromCXXForRangeStmt(CXXForRangeStmt *S)
bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L)
bool WalkUpFromUsingDecl(UsingDecl *S)
bool WalkUpFromReturnStmt(ReturnStmt *S)
bool WalkUpFromContinueStmt(ContinueStmt *S)
bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S)
bool WalkUpFromIfStmt(IfStmt *S)
bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L, bool TraverseQualifier)
static SourceLocation getQualifiedNameStart(NamedDecl *D)
Get the start of the qualified name.
bool WalkUpFromCallExpr(CallExpr *S)
bool WalkUpFromFunctionProtoTypeLoc(FunctionProtoTypeLoc L)
bool WalkUpFromArrayTypeLoc(ArrayTypeLoc L)
bool WalkUpFromDefaultStmt(DefaultStmt *S)
bool WalkUpFromForStmt(ForStmt *S)
static Expr * IgnoreImplicitConstructorSingleStep(Expr *E)
bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S)
syntax::CallArguments * buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs)
Builds CallArguments syntax node from arguments that appear in source code, i.e. not default argument...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
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 (<init>; <cond>; <increment>) <body>
if (cond) <then-statement> else <else-statement> FIXME: add condition that models 'expression or vari...
extern <string-literal> declaration extern <string-literal> { <decls> }
Member pointer inside a declarator E.g.
namespace <name> = <namespace-reference>
namespace <name> { <decls> }
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 (<decl> : <init>) <body>
static_assert(<condition>, <message>) static_assert(<condition>)
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 <scope>::<name> using typename <scope>::<name>
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.
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.
Expr * IgnoreImplicitSingleStep(Expr *E)
const FunctionProtoType * T
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
U cast(CodeGen::Address addr)