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();
99 SourceLocation VisitParenTypeLoc(ParenTypeLoc T) {
107 SourceLocation VisitPointerTypeLoc(PointerTypeLoc T) {
108 return HandlePointer(T);
111 SourceLocation VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
112 return HandlePointer(T);
115 SourceLocation VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
116 return HandlePointer(T);
119 SourceLocation VisitReferenceTypeLoc(ReferenceTypeLoc T) {
120 return HandlePointer(T);
123 SourceLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc T) {
124 return HandlePointer(T);
131 SourceLocation VisitTypeLoc(TypeLoc T) {
134 return SourceLocation();
138 SourceLocation VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc T) {
140 return SourceLocation();
141 return VisitTypeLoc(T);
145 template <
class PtrLoc> SourceLocation HandlePointer(PtrLoc T) {
146 auto L = Visit(T.getPointeeLoc());
149 return T.getLocalSourceRange().getBegin();
155 auto FirstDefaultArg =
157 return llvm::make_range(Args.begin(), FirstDefaultArg);
164 case OO_ExclaimEqual:
166 case OO_GreaterEqual:
173 case OO_PercentEqual:
176 case OO_LessLessEqual:
177 case OO_GreaterGreaterEqual:
188 case OO_GreaterGreater:
193 return syntax::NodeKind::BinaryOperatorExpression;
196 return syntax::NodeKind::PrefixUnaryOperatorExpression;
202 return syntax::NodeKind::PrefixUnaryOperatorExpression;
204 return syntax::NodeKind::PostfixUnaryOperatorExpression;
206 llvm_unreachable(
"Invalid number of arguments for operator");
215 return syntax::NodeKind::PrefixUnaryOperatorExpression;
217 return syntax::NodeKind::BinaryOperatorExpression;
219 llvm_unreachable(
"Invalid number of arguments for operator");
221 return syntax::NodeKind::BinaryOperatorExpression;
226 case OO_Array_Delete:
230 return syntax::NodeKind::UnknownExpression;
232 return syntax::NodeKind::CallExpression;
236 llvm_unreachable(
"Not an overloadable operator");
238 llvm_unreachable(
"Unknown OverloadedOperatorKind enum");
248 "only DeclaratorDecl and TypedefNameDecl are supported.");
251 bool IsAnonymous = DN.
isIdentifier() && !DN.getAsIdentifierInfo();
255 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
256 if (DD->getQualifierLoc()) {
257 return DD->getQualifierLoc().getBeginLoc();
270 if (
auto *
V = dyn_cast<VarDecl>(D)) {
271 auto *I =
V->getInit();
273 if (I && !
V->isCXXForRangeDecl())
274 return I->getSourceRange();
298 if (End.
isInvalid() ||
SM.isBeforeInTranslationUnit(End, Name))
303 assert(
SM.isBeforeInTranslationUnit(End, InitializerEnd) ||
304 End == InitializerEnd);
305 End = InitializerEnd;
312using ASTPtr = llvm::PointerUnion<Stmt *, Decl *>;
316class ASTToSyntaxMapping {
318 void add(ASTPtr From, syntax::Tree *To) {
319 assert(To !=
nullptr);
320 assert(!From.isNull());
322 bool Added = Nodes.insert({From, To}).second;
324 assert(Added &&
"mapping added twice");
327 void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
328 assert(To !=
nullptr);
331 bool Added = NNSNodes.insert({From, To}).second;
333 assert(Added &&
"mapping added twice");
336 syntax::Tree *find(ASTPtr P)
const {
return Nodes.lookup(P); }
338 syntax::Tree *find(NestedNameSpecifierLoc P)
const {
339 return NNSNodes.lookup(P);
343 llvm::DenseMap<ASTPtr, syntax::Tree *> Nodes;
344 llvm::DenseMap<NestedNameSpecifierLoc, syntax::Tree *> NNSNodes;
363class syntax::TreeBuilder {
365 TreeBuilder(syntax::Arena &Arena, TokenBufferTokenManager& TBTM)
368 Pending(Arena, TBTM.tokenBuffer()) {
369 for (
const auto &T : TBTM.tokenBuffer().expandedTokens())
370 LocationToToken.insert({T.location(), &T});
373 llvm::BumpPtrAllocator &allocator() {
return Arena.
getAllocator(); }
374 const SourceManager &sourceManager()
const {
375 return TBTM.sourceManager();
380 void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *
New, ASTPtr From) {
382 Pending.foldChildren(TBTM.tokenBuffer(), Range,
New);
384 Mapping.add(From,
New);
387 void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *
New, TypeLoc L) {
389 foldNode(Range,
New,
nullptr);
392 void foldNode(llvm::ArrayRef<syntax::Token> Range, syntax::Tree *
New,
393 NestedNameSpecifierLoc From) {
395 Pending.foldChildren(TBTM.tokenBuffer(), Range,
New);
397 Mapping.add(From,
New);
402 void foldList(ArrayRef<syntax::Token> SuperRange, syntax::List *
New,
405 auto ListRange = Pending.shrinkToFitList(SuperRange);
406 Pending.foldChildren(TBTM.tokenBuffer(), ListRange,
New);
408 Mapping.add(From,
New);
413 void noticeDeclWithoutSemicolon(Decl *D);
419 void markStmtChild(Stmt *Child, NodeRole
Role);
422 void markExprChild(Expr *Child, NodeRole
Role);
424 void markChildToken(SourceLocation Loc, NodeRole R);
426 void markChildToken(
const syntax::Token *T, NodeRole R);
429 void markChild(syntax::Node *N, NodeRole R);
431 void markChild(ASTPtr N, NodeRole R);
433 void markChild(NestedNameSpecifierLoc N, NodeRole R);
436 syntax::TranslationUnit *
finalize() && {
437 auto Tokens = TBTM.tokenBuffer().expandedTokens();
438 assert(!Tokens.empty());
439 assert(Tokens.back().kind() == tok::eof);
442 Pending.foldChildren(TBTM.tokenBuffer(), Tokens.drop_back(),
446 TU->assertInvariantsRecursive();
451 const syntax::Token *findToken(SourceLocation L)
const;
454 ArrayRef<syntax::Token>
getRange(SourceRange Range)
const {
455 assert(
Range.isValid());
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)));
471 ArrayRef<syntax::Token>
472 getTemplateRange(
const ClassTemplateSpecializationDecl *D)
const {
474 return maybeAppendSemicolon(Tokens, D);
479 bool isResponsibleForCreatingDeclaration(
const Decl *D)
const {
481 "only DeclaratorDecl and TypedefNameDecl are supported.");
486 if (
Next ==
nullptr) {
505 ArrayRef<syntax::Token> getDeclarationRange(Decl *D) {
506 ArrayRef<syntax::Token> Tokens;
508 if (
const auto *S = dyn_cast<TagDecl>(D))
509 Tokens =
getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());
512 return maybeAppendSemicolon(Tokens, D);
515 ArrayRef<syntax::Token> getExprRange(
const Expr *E)
const {
521 ArrayRef<syntax::Token> getStmtRange(
const Stmt *S)
const {
528 if (Tokens.back().kind() == tok::semi)
530 return withTrailingSemicolon(Tokens);
534 ArrayRef<syntax::Token> maybeAppendSemicolon(ArrayRef<syntax::Token> Tokens,
535 const Decl *D)
const {
538 if (DeclsWithoutSemicolons.count(D))
542 return withTrailingSemicolon(Tokens);
545 ArrayRef<syntax::Token>
546 withTrailingSemicolon(ArrayRef<syntax::Token> Tokens)
const {
547 assert(!Tokens.empty());
548 assert(Tokens.back().kind() != tok::eof);
550 if (Tokens.back().kind() != tok::semi && Tokens.end()->kind() == tok::semi)
551 return llvm::ArrayRef(Tokens.begin(), Tokens.end() + 1);
555 void setRole(syntax::Node *N, NodeRole R) {
556 assert(N->
getRole() == NodeRole::Detached);
567 Forest(syntax::Arena &A,
const syntax::TokenBuffer &TB) {
574 syntax::Leaf(
reinterpret_cast<TokenManager::Key
>(&T));
577 Trees.insert(Trees.end(), {&T, L});
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);
596 ArrayRef<syntax::Token> shrinkToFitList(ArrayRef<syntax::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");
602 auto EndChildren = Trees.lower_bound(
Range.end());
604 (EndChildren == Trees.end() || EndChildren->first ==
Range.end()) &&
605 "Range crosses boundaries of existing subtrees");
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;
613 auto BeginListChildren =
614 std::find_if(BeginChildren, EndChildren, BelongsToList);
616 auto EndListChildren =
617 std::find_if_not(BeginListChildren, EndChildren, BelongsToList);
619 return ArrayRef<syntax::Token>(BeginListChildren->first,
620 EndListChildren->first);
624 void foldChildren(
const syntax::TokenBuffer &TB,
625 ArrayRef<syntax::Token> Tokens, syntax::Tree *Node) {
627 assert(Node->
getFirstChild() ==
nullptr &&
"node already has children");
629 auto *FirstToken = Tokens.begin();
630 auto BeginChildren = Trees.lower_bound(FirstToken);
632 assert((BeginChildren == Trees.end() ||
633 BeginChildren->first == FirstToken) &&
634 "fold crosses boundaries of existing subtrees");
635 auto EndChildren = Trees.lower_bound(Tokens.end());
637 (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&
638 "fold crosses boundaries of existing subtrees");
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);
648 Node->Original =
true;
652 Trees.erase(BeginChildren, EndChildren);
653 Trees.insert({FirstToken, Node});
658 assert(Trees.size() == 1);
659 auto *Root = Trees.begin()->second;
664 std::string str(
const syntax::TokenBufferTokenManager &STM)
const {
666 for (
auto It = Trees.begin(); It != Trees.end(); ++It) {
667 unsigned CoveredTokens =
669 ? (std::next(It)->first - It->first)
670 : STM.tokenBuffer().expandedTokens().end() - It->first;
673 formatv(
"- '{0}' covers '{1}'+{2} tokens\n", It->second->getKind(),
675 R += It->second->dump(STM);
684 std::map<const syntax::Token *, syntax::Node *> Trees;
688 std::string str() {
return Pending.str(TBTM); }
690 syntax::Arena &Arena;
691 TokenBufferTokenManager& TBTM;
693 llvm::DenseMap<SourceLocation, const syntax::Token *> LocationToToken;
695 llvm::DenseSet<Decl *> DeclsWithoutSemicolons;
696 ASTToSyntaxMapping Mapping;
702 explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
703 : Builder(Builder), Context(Context) {}
707 bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {
708 return processDeclaratorAndDeclaration(DD);
711 bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) {
712 return processDeclaratorAndDeclaration(TD);
717 Builder.foldNode(Builder.getDeclarationRange(D),
718 new (allocator()) syntax::UnknownDeclaration(), D);
726 TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *
C) {
727 if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(
C))
729 if (
C->isExplicitSpecialization())
733 foldExplicitTemplateInstantiation(
734 Builder.getTemplateRange(
C),
735 Builder.findToken(
C->getExternKeywordLoc()),
736 Builder.findToken(
C->getTemplateKeywordLoc()),
Declaration,
C);
744 bool TraverseExplicitInstantiationDecl(ExplicitInstantiationDecl *) {
748 bool WalkUpFromTemplateDecl(TemplateDecl *S) {
749 foldTemplateDeclaration(
750 Builder.getDeclarationRange(S),
756 bool WalkUpFromTagDecl(TagDecl *
C) {
758 if (!
C->isFreeStanding()) {
759 assert(
C->getTemplateParameterLists().empty());
762 handleFreeStandingTagDecl(
C);
767 assert(
C->isFreeStanding());
769 auto DeclarationRange = Builder.getDeclarationRange(
C);
771 Builder.foldNode(DeclarationRange,
Result,
nullptr);
774 auto ConsumeTemplateParameters = [&](
const TemplateParameterList &L) {
775 const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
776 auto R = llvm::ArrayRef(TemplateKW, DeclarationRange.end());
778 foldTemplateDeclaration(R, TemplateKW, DeclarationRange,
nullptr);
779 DeclarationRange =
R;
781 if (
auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(
C))
782 ConsumeTemplateParameters(*S->getTemplateParameters());
783 for (TemplateParameterList *TPL :
C->getTemplateParameterLists())
784 ConsumeTemplateParameters(*TPL);
788 bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
797 Builder.markChildToken(S->
getLBracLoc(), NodeRole::OpenParen);
798 for (
auto *Child : S->
body())
799 Builder.markStmtChild(Child, NodeRole::Statement);
800 Builder.markChildToken(S->
getRBracLoc(), NodeRole::CloseParen);
802 Builder.foldNode(Builder.getStmtRange(S),
803 new (allocator()) syntax::CompoundStatement, S);
809 Builder.foldNode(Builder.getStmtRange(S),
810 new (allocator()) syntax::UnknownStatement, S);
814 bool TraverseIfStmt(IfStmt *S) {
815 bool Result = [&,
this]() {
838 bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
843 bool Result = [&,
this]() {
859 if (
auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
861 for (
auto *D : DS->decls())
862 Builder.noticeDeclWithoutSemicolon(D);
863 }
else if (
auto *E = dyn_cast_or_null<Expr>(S)) {
869 bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
875 bool WalkUpFromExpr(Expr *E) {
876 assert(!
isImplicitExpr(E) &&
"should be handled by TraverseStmt");
877 Builder.foldNode(Builder.getExprRange(E),
878 new (allocator()) syntax::UnknownExpression, E);
882 bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
888 return WalkUpFromUserDefinedLiteral(S);
891 syntax::UserDefinedLiteralExpression *
892 buildUserDefinedLiteral(UserDefinedLiteral *S) {
895 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
897 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
899 return new (allocator()) syntax::CharUserDefinedLiteralExpression;
901 return new (allocator()) syntax::StringUserDefinedLiteralExpression;
915 if (
Literal.isIntegerLiteral())
916 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
918 assert(
Literal.isFloatingLiteral());
919 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
922 llvm_unreachable(
"Unknown literal operator kind.");
925 bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
926 Builder.markChildToken(S->
getBeginLoc(), syntax::NodeRole::LiteralToken);
927 Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
931 syntax::NameSpecifier *buildIdentifier(SourceRange SR,
932 bool DropBack =
false) {
933 auto NameSpecifierTokens = Builder.getRange(SR).drop_back(DropBack);
934 assert(NameSpecifierTokens.size() == 1);
935 Builder.markChildToken(NameSpecifierTokens.begin(),
936 syntax::NodeRole::Unknown);
937 auto *NS =
new (allocator()) syntax::IdentifierNameSpecifier;
938 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
942 syntax::NameSpecifier *buildSimpleTemplateName(SourceRange SR) {
943 auto NameSpecifierTokens = Builder.getRange(SR);
949 auto *NS =
new (allocator()) syntax::SimpleTemplateNameSpecifier;
950 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
954 syntax::NameSpecifier *
955 buildNameSpecifier(
const NestedNameSpecifierLoc &NNSLoc) {
958 case NestedNameSpecifier::Kind::Global:
959 return new (allocator()) syntax::GlobalNameSpecifier;
961 case NestedNameSpecifier::Kind::Namespace:
967 case TypeLoc::Record:
968 case TypeLoc::InjectedClassName:
971 case TypeLoc::Typedef:
973 case TypeLoc::UnresolvedUsing:
974 return buildIdentifier(
978 case TypeLoc::DependentName:
980 case TypeLoc::TemplateSpecialization: {
983 if (BeginLoc.isInvalid())
984 BeginLoc = TST.getTemplateNameLoc();
985 return buildSimpleTemplateName({BeginLoc, TST.getEndLoc()});
987 case TypeLoc::Decltype: {
989 if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(
992 auto *NS =
new (allocator()) syntax::DecltypeNameSpecifier;
997 Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,
1007 llvm::report_fatal_error(
"We don't yet support the __super specifier",
1019 for (
auto It = QualifierLoc; It; ) {
1020 auto *NS = buildNameSpecifier(It);
1025 if (
TypeLoc TL = It.getAsTypeLoc())
1026 It = TL.getPrefix();
1028 It = It.getAsNamespaceAndPrefix().Prefix;
1030 Builder.foldNode(Builder.getRange(QualifierLoc.
getSourceRange()),
1042 if (TemplateKeywordLoc.
isValid())
1043 Builder.markChildToken(TemplateKeywordLoc,
1048 Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1052 auto IdExpressionBeginLoc =
1055 auto *TheIdExpression =
new (allocator()) syntax::IdExpression;
1057 Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.
getEnd()),
1058 TheIdExpression, From);
1060 return TheIdExpression;
1082 Builder.foldNode(Builder.getExprRange(S),
1083 new (allocator()) syntax::MemberExpression, S);
1106 Builder.foldNode(Builder.getExprRange(S),
1107 new (allocator()) syntax::ThisExpression, S);
1116 Builder.foldNode(Builder.getExprRange(S),
1117 new (allocator()) syntax::ParenExpression, S);
1123 Builder.foldNode(Builder.getExprRange(S),
1124 new (allocator()) syntax::IntegerLiteralExpression, S);
1130 Builder.foldNode(Builder.getExprRange(S),
1131 new (allocator()) syntax::CharacterLiteralExpression, S);
1137 Builder.foldNode(Builder.getExprRange(S),
1138 new (allocator()) syntax::FloatingLiteralExpression, S);
1144 Builder.foldNode(Builder.getExprRange(S),
1145 new (allocator()) syntax::StringLiteralExpression, S);
1151 Builder.foldNode(Builder.getExprRange(S),
1152 new (allocator()) syntax::BoolLiteralExpression, S);
1158 Builder.foldNode(Builder.getExprRange(S),
1159 new (allocator()) syntax::CxxNullPtrExpression, S);
1169 Builder.foldNode(Builder.getExprRange(S),
1173 Builder.foldNode(Builder.getExprRange(S),
1185 Builder.foldNode(Builder.getExprRange(S),
1192 syntax::CallArguments *
1195 for (
auto *Arg : Args) {
1197 const auto *DelimiterToken =
1198 std::next(Builder.findToken(Arg->getEndLoc()));
1199 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1205 Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1206 (*(Args.end() - 1))->getEndLoc()),
1207 Arguments,
nullptr);
1215 const auto *LParenToken =
1219 if (LParenToken->kind() == clang::tok::l_paren)
1228 new (allocator()) syntax::CallExpression, S);
1237 return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1252 if (child->getSourceRange().isInvalid()) {
1254 syntax::NodeKind::PostfixUnaryOperatorExpression);
1265 case syntax::NodeKind::BinaryOperatorExpression:
1270 Builder.foldNode(Builder.getExprRange(S),
1273 case syntax::NodeKind::PrefixUnaryOperatorExpression:
1277 Builder.foldNode(Builder.getExprRange(S),
1281 case syntax::NodeKind::PostfixUnaryOperatorExpression:
1285 Builder.foldNode(Builder.getExprRange(S),
1289 case syntax::NodeKind::CallExpression: {
1292 const auto *LParenToken =
1296 if (LParenToken->kind() == clang::tok::l_paren)
1306 new (allocator()) syntax::CallExpression, S);
1309 case syntax::NodeKind::UnknownExpression:
1310 return WalkUpFromExpr(S);
1312 llvm_unreachable(
"getOperatorNodeKind() does not return this value");
1319 auto Tokens = Builder.getDeclarationRange(S);
1320 if (Tokens.front().kind() == tok::coloncolon) {
1357 syntax::ParameterDeclarationList *
1359 for (
auto *P : Params) {
1361 const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1362 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1366 if (!Params.empty())
1367 Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1368 Params.back()->getEndLoc()),
1369 Parameters,
nullptr);
1389 auto *TrailingReturnTokens = buildTrailingReturn(L);
1396 bool TraverseQualifier) {
1408 Builder.foldNode(Builder.getRange(SR),
1417 Builder.foldNode(Builder.getStmtRange(S),
1423 Builder.foldNode(Builder.getStmtRange(S),
1432 Builder.foldNode(Builder.getStmtRange(S),
1442 Builder.foldNode(Builder.getStmtRange(S),
1451 Builder.foldNode(Builder.getStmtRange(S),
1465 Builder.foldNode(Builder.getStmtRange(S),
1473 Builder.foldNode(Builder.getStmtRange(S),
1482 Builder.foldNode(Builder.getStmtRange(S),
1489 Builder.foldNode(Builder.getStmtRange(S),
1496 Builder.foldNode(Builder.getStmtRange(S),
1505 Builder.foldNode(Builder.getStmtRange(S),
1513 Builder.foldNode(Builder.getStmtRange(S),
1519 Builder.foldNode(Builder.getDeclarationRange(S),
1527 Builder.foldNode(Builder.getDeclarationRange(S),
1533 Builder.foldNode(Builder.getDeclarationRange(S),
1540 Builder.foldNode(Builder.getDeclarationRange(S),
1546 Builder.foldNode(Builder.getDeclarationRange(S),
1552 Builder.foldNode(Builder.getDeclarationRange(S),
1558 Builder.foldNode(Builder.getDeclarationRange(S),
1564 Builder.foldNode(Builder.getDeclarationRange(S),
1570 Builder.foldNode(Builder.getDeclarationRange(S),
1578 template <
class T>
bool processDeclaratorAndDeclaration(T *D) {
1579 auto Range = getDeclaratorRange(
1580 Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1585 if (!
Range.getBegin().isValid()) {
1586 Builder.markChild(
new (allocator()) syntax::DeclaratorList,
1587 syntax::NodeRole::Declarators);
1588 Builder.foldNode(Builder.getDeclarationRange(D),
1589 new (allocator()) syntax::SimpleDeclaration, D);
1593 auto *N =
new (allocator()) syntax::SimpleDeclarator;
1594 Builder.foldNode(Builder.getRange(Range), N,
nullptr);
1595 Builder.markChild(N, syntax::NodeRole::ListElement);
1597 if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1600 const auto *DelimiterToken = std::next(Builder.findToken(
Range.getEnd()));
1601 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1602 Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1604 auto *DL =
new (allocator()) syntax::DeclaratorList;
1605 auto DeclarationRange = Builder.getDeclarationRange(D);
1606 Builder.foldList(DeclarationRange, DL,
nullptr);
1608 Builder.markChild(DL, syntax::NodeRole::Declarators);
1609 Builder.foldNode(DeclarationRange,
1610 new (allocator()) syntax::SimpleDeclaration, D);
1616 syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1621 auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1622 ReturnedType.getEndLoc());
1623 syntax::SimpleDeclarator *ReturnDeclarator =
nullptr;
1624 if (ReturnDeclaratorRange.isValid()) {
1625 ReturnDeclarator =
new (allocator()) syntax::SimpleDeclarator;
1626 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1627 ReturnDeclarator,
nullptr);
1631 auto Return = Builder.getRange(ReturnedType.getSourceRange());
1632 const auto *Arrow = Return.begin() - 1;
1633 assert(Arrow->kind() == tok::arrow);
1634 auto Tokens = llvm::ArrayRef(Arrow, Return.end());
1635 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1636 if (ReturnDeclarator)
1637 Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1638 auto *
R =
new (allocator()) syntax::TrailingReturnType;
1639 Builder.foldNode(Tokens, R, L);
1643 void foldExplicitTemplateInstantiation(
1644 ArrayRef<syntax::Token> Range,
const syntax::Token *ExternKW,
1645 const syntax::Token *TemplateKW,
1646 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1647 assert(!ExternKW || ExternKW->
kind() == tok::kw_extern);
1648 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1649 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1650 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1651 Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1653 Range,
new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1656 syntax::TemplateDeclaration *foldTemplateDeclaration(
1657 ArrayRef<syntax::Token> Range,
const syntax::Token *TemplateKW,
1658 ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1659 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1660 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1662 auto *N =
new (allocator()) syntax::TemplateDeclaration;
1663 Builder.foldNode(Range, N, From);
1664 Builder.markChild(N, syntax::NodeRole::Declaration);
1669 llvm::BumpPtrAllocator &allocator() {
return Builder.allocator(); }
1671 syntax::TreeBuilder &Builder;
1672 const ASTContext &Context;
1676void syntax::TreeBuilder::noticeDeclWithoutSemicolon(
Decl *D) {
1677 DeclsWithoutSemicolons.insert(D);
1683 Pending.assignRole(*findToken(Loc),
Role);
1686void syntax::TreeBuilder::markChildToken(
const syntax::Token *T, NodeRole R) {
1689 Pending.assignRole(*T, R);
1692void syntax::TreeBuilder::markChild(
syntax::Node *N, NodeRole R) {
1697void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1698 auto *SN = Mapping.find(N);
1699 assert(SN !=
nullptr);
1703 auto *SN = Mapping.find(NNSLoc);
1704 assert(SN !=
nullptr);
1708void syntax::TreeBuilder::markStmtChild(
Stmt *Child, NodeRole
Role) {
1713 if (
Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1716 markExprChild(ChildExpr, NodeRole::Expression);
1719 Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);
1721 ChildNode = Mapping.find(Child);
1723 assert(ChildNode !=
nullptr);
1724 setRole(ChildNode,
Role);
1727void syntax::TreeBuilder::markExprChild(
Expr *Child, NodeRole
Role) {
1733 assert(ChildNode !=
nullptr);
1734 setRole(ChildNode,
Role);
1740 auto It = LocationToToken.find(L);
1741 assert(It != LocationToToken.end());
1748 TreeBuilder Builder(A, TBTM);
1749 BuildTreeVisitor(Context, Builder).TraverseAST(Context);
1750 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)
static bool isImplicitExpr(Expr *E)
bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S)
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.
Result
Implement __builtin_bit_cast and related operations.
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.
TypeLoc getNextTypeLoc() const
Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the TypeLoc is a PointerLoc and next Typ...
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...
Expr * IgnoreImplicitSingleStep(Expr *E)
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
U cast(CodeGen::Address addr)