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::Decltype: {
979 if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(
982 auto *NS =
new (allocator()) syntax::DecltypeNameSpecifier;
987 Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,
997 llvm::report_fatal_error(
"We don't yet support the __super specifier",
1009 for (
auto It = QualifierLoc; It; ) {
1010 auto *NS = buildNameSpecifier(It);
1015 if (
TypeLoc TL = It.getAsTypeLoc())
1016 It = TL.getPrefix();
1018 It = It.getAsNamespaceAndPrefix().Prefix;
1020 Builder.foldNode(Builder.getRange(QualifierLoc.
getSourceRange()),
1032 if (TemplateKeywordLoc.
isValid())
1033 Builder.markChildToken(TemplateKeywordLoc,
1038 Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1042 auto IdExpressionBeginLoc =
1045 auto *TheIdExpression =
new (allocator()) syntax::IdExpression;
1047 Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.
getEnd()),
1048 TheIdExpression, From);
1050 return TheIdExpression;
1072 Builder.foldNode(Builder.getExprRange(S),
1073 new (allocator()) syntax::MemberExpression, S);
1096 Builder.foldNode(Builder.getExprRange(S),
1097 new (allocator()) syntax::ThisExpression, S);
1106 Builder.foldNode(Builder.getExprRange(S),
1107 new (allocator()) syntax::ParenExpression, S);
1113 Builder.foldNode(Builder.getExprRange(S),
1114 new (allocator()) syntax::IntegerLiteralExpression, S);
1120 Builder.foldNode(Builder.getExprRange(S),
1121 new (allocator()) syntax::CharacterLiteralExpression, S);
1127 Builder.foldNode(Builder.getExprRange(S),
1128 new (allocator()) syntax::FloatingLiteralExpression, S);
1134 Builder.foldNode(Builder.getExprRange(S),
1135 new (allocator()) syntax::StringLiteralExpression, S);
1141 Builder.foldNode(Builder.getExprRange(S),
1142 new (allocator()) syntax::BoolLiteralExpression, S);
1148 Builder.foldNode(Builder.getExprRange(S),
1149 new (allocator()) syntax::CxxNullPtrExpression, S);
1159 Builder.foldNode(Builder.getExprRange(S),
1163 Builder.foldNode(Builder.getExprRange(S),
1175 Builder.foldNode(Builder.getExprRange(S),
1182 syntax::CallArguments *
1185 for (
auto *Arg : Args) {
1187 const auto *DelimiterToken =
1188 std::next(Builder.findToken(Arg->getEndLoc()));
1189 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1195 Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1196 (*(Args.end() - 1))->getEndLoc()),
1197 Arguments,
nullptr);
1205 const auto *LParenToken =
1209 if (LParenToken->kind() == clang::tok::l_paren)
1218 new (allocator()) syntax::CallExpression, S);
1227 return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1242 if (child->getSourceRange().isInvalid()) {
1244 syntax::NodeKind::PostfixUnaryOperatorExpression);
1255 case syntax::NodeKind::BinaryOperatorExpression:
1260 Builder.foldNode(Builder.getExprRange(S),
1263 case syntax::NodeKind::PrefixUnaryOperatorExpression:
1267 Builder.foldNode(Builder.getExprRange(S),
1271 case syntax::NodeKind::PostfixUnaryOperatorExpression:
1275 Builder.foldNode(Builder.getExprRange(S),
1279 case syntax::NodeKind::CallExpression: {
1282 const auto *LParenToken =
1286 if (LParenToken->kind() == clang::tok::l_paren)
1296 new (allocator()) syntax::CallExpression, S);
1299 case syntax::NodeKind::UnknownExpression:
1300 return WalkUpFromExpr(S);
1302 llvm_unreachable(
"getOperatorNodeKind() does not return this value");
1309 auto Tokens = Builder.getDeclarationRange(S);
1310 if (Tokens.front().kind() == tok::coloncolon) {
1347 syntax::ParameterDeclarationList *
1349 for (
auto *P : Params) {
1351 const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1352 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1356 if (!Params.empty())
1357 Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1358 Params.back()->getEndLoc()),
1359 Parameters,
nullptr);
1379 auto *TrailingReturnTokens = buildTrailingReturn(L);
1386 bool TraverseQualifier) {
1398 Builder.foldNode(Builder.getRange(SR),
1407 Builder.foldNode(Builder.getStmtRange(S),
1413 Builder.foldNode(Builder.getStmtRange(S),
1422 Builder.foldNode(Builder.getStmtRange(S),
1432 Builder.foldNode(Builder.getStmtRange(S),
1441 Builder.foldNode(Builder.getStmtRange(S),
1455 Builder.foldNode(Builder.getStmtRange(S),
1463 Builder.foldNode(Builder.getStmtRange(S),
1472 Builder.foldNode(Builder.getStmtRange(S),
1479 Builder.foldNode(Builder.getStmtRange(S),
1486 Builder.foldNode(Builder.getStmtRange(S),
1495 Builder.foldNode(Builder.getStmtRange(S),
1503 Builder.foldNode(Builder.getStmtRange(S),
1509 Builder.foldNode(Builder.getDeclarationRange(S),
1517 Builder.foldNode(Builder.getDeclarationRange(S),
1523 Builder.foldNode(Builder.getDeclarationRange(S),
1530 Builder.foldNode(Builder.getDeclarationRange(S),
1536 Builder.foldNode(Builder.getDeclarationRange(S),
1542 Builder.foldNode(Builder.getDeclarationRange(S),
1548 Builder.foldNode(Builder.getDeclarationRange(S),
1554 Builder.foldNode(Builder.getDeclarationRange(S),
1560 Builder.foldNode(Builder.getDeclarationRange(S),
1568 template <
class T>
bool processDeclaratorAndDeclaration(
T *D) {
1569 auto Range = getDeclaratorRange(
1570 Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1575 if (!
Range.getBegin().isValid()) {
1576 Builder.markChild(
new (allocator()) syntax::DeclaratorList,
1577 syntax::NodeRole::Declarators);
1578 Builder.foldNode(Builder.getDeclarationRange(D),
1579 new (allocator()) syntax::SimpleDeclaration, D);
1583 auto *N =
new (allocator()) syntax::SimpleDeclarator;
1584 Builder.foldNode(Builder.getRange(Range), N,
nullptr);
1585 Builder.markChild(N, syntax::NodeRole::ListElement);
1587 if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1590 const auto *DelimiterToken = std::next(Builder.findToken(
Range.getEnd()));
1591 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1592 Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1594 auto *DL =
new (allocator()) syntax::DeclaratorList;
1595 auto DeclarationRange = Builder.getDeclarationRange(D);
1596 Builder.foldList(DeclarationRange, DL,
nullptr);
1598 Builder.markChild(DL, syntax::NodeRole::Declarators);
1599 Builder.foldNode(DeclarationRange,
1600 new (allocator()) syntax::SimpleDeclaration, D);
1606 syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1611 auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1612 ReturnedType.getEndLoc());
1613 syntax::SimpleDeclarator *ReturnDeclarator =
nullptr;
1614 if (ReturnDeclaratorRange.isValid()) {
1615 ReturnDeclarator =
new (allocator()) syntax::SimpleDeclarator;
1616 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1617 ReturnDeclarator,
nullptr);
1621 auto Return = Builder.getRange(ReturnedType.getSourceRange());
1622 const auto *Arrow = Return.begin() - 1;
1623 assert(Arrow->kind() == tok::arrow);
1624 auto Tokens = llvm::ArrayRef(Arrow, Return.end());
1625 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1626 if (ReturnDeclarator)
1627 Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1628 auto *R =
new (allocator()) syntax::TrailingReturnType;
1629 Builder.foldNode(Tokens, R, L);
1633 void foldExplicitTemplateInstantiation(
1634 ArrayRef<syntax::Token> Range,
const syntax::Token *ExternKW,
1635 const syntax::Token *TemplateKW,
1636 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1637 assert(!ExternKW || ExternKW->
kind() == tok::kw_extern);
1638 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1639 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1640 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1641 Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1643 Range,
new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1646 syntax::TemplateDeclaration *foldTemplateDeclaration(
1647 ArrayRef<syntax::Token> Range,
const syntax::Token *TemplateKW,
1648 ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1649 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1650 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1652 auto *N =
new (allocator()) syntax::TemplateDeclaration;
1653 Builder.foldNode(Range, N, From);
1654 Builder.markChild(N, syntax::NodeRole::Declaration);
1659 llvm::BumpPtrAllocator &allocator() {
return Builder.allocator(); }
1661 syntax::TreeBuilder &Builder;
1662 const ASTContext &Context;
1666void syntax::TreeBuilder::noticeDeclWithoutSemicolon(
Decl *D) {
1667 DeclsWithoutSemicolons.insert(D);
1673 Pending.assignRole(*findToken(Loc),
Role);
1676void syntax::TreeBuilder::markChildToken(
const syntax::Token *
T, NodeRole R) {
1679 Pending.assignRole(*
T, R);
1682void syntax::TreeBuilder::markChild(
syntax::Node *N, NodeRole R) {
1687void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1688 auto *SN = Mapping.find(N);
1689 assert(SN !=
nullptr);
1693 auto *SN = Mapping.find(NNSLoc);
1694 assert(SN !=
nullptr);
1698void syntax::TreeBuilder::markStmtChild(
Stmt *Child, NodeRole
Role) {
1703 if (
Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1706 markExprChild(ChildExpr, NodeRole::Expression);
1709 Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);
1711 ChildNode = Mapping.find(Child);
1713 assert(ChildNode !=
nullptr);
1714 setRole(ChildNode,
Role);
1717void syntax::TreeBuilder::markExprChild(
Expr *Child, NodeRole
Role) {
1723 assert(ChildNode !=
nullptr);
1724 setRole(ChildNode,
Role);
1730 auto It = LocationToToken.find(L);
1731 assert(It != LocationToToken.end());
1738 TreeBuilder Builder(A, TBTM);
1739 BuildTreeVisitor(Context, Builder).TraverseAST(Context);
1740 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.
const FunctionProtoType * T
Expr * IgnoreImplicitSingleStep(Expr *E)
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
U cast(CodeGen::Address addr)