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) {
100 auto L = Visit(
T.getInnerLoc());
103 return T.getLParenLoc();
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) {
132 auto N =
T.getNextTypeLoc();
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);
740 bool WalkUpFromTemplateDecl(TemplateDecl *S) {
741 foldTemplateDeclaration(
742 Builder.getDeclarationRange(S),
748 bool WalkUpFromTagDecl(TagDecl *
C) {
750 if (!
C->isFreeStanding()) {
751 assert(
C->getNumTemplateParameterLists() == 0);
754 handleFreeStandingTagDecl(
C);
759 assert(
C->isFreeStanding());
761 auto DeclarationRange = Builder.getDeclarationRange(
C);
763 Builder.foldNode(DeclarationRange,
Result,
nullptr);
766 auto ConsumeTemplateParameters = [&](
const TemplateParameterList &L) {
767 const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
768 auto R = llvm::ArrayRef(TemplateKW, DeclarationRange.end());
770 foldTemplateDeclaration(R, TemplateKW, DeclarationRange,
nullptr);
771 DeclarationRange = R;
773 if (
auto *S = dyn_cast<ClassTemplatePartialSpecializationDecl>(
C))
774 ConsumeTemplateParameters(*S->getTemplateParameters());
775 for (
unsigned I =
C->getNumTemplateParameterLists(); 0 < I; --I)
776 ConsumeTemplateParameters(*
C->getTemplateParameterList(I - 1));
780 bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
789 Builder.markChildToken(S->
getLBracLoc(), NodeRole::OpenParen);
790 for (
auto *Child : S->
body())
791 Builder.markStmtChild(Child, NodeRole::Statement);
792 Builder.markChildToken(S->
getRBracLoc(), NodeRole::CloseParen);
794 Builder.foldNode(Builder.getStmtRange(S),
795 new (allocator()) syntax::CompoundStatement, S);
801 Builder.foldNode(Builder.getStmtRange(S),
802 new (allocator()) syntax::UnknownStatement, S);
806 bool TraverseIfStmt(IfStmt *S) {
807 bool Result = [&,
this]() {
830 bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
835 bool Result = [&,
this]() {
851 if (
auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
853 for (
auto *D : DS->decls())
854 Builder.noticeDeclWithoutSemicolon(D);
855 }
else if (
auto *E = dyn_cast_or_null<Expr>(S)) {
861 bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
867 bool WalkUpFromExpr(Expr *E) {
868 assert(!
isImplicitExpr(E) &&
"should be handled by TraverseStmt");
869 Builder.foldNode(Builder.getExprRange(E),
870 new (allocator()) syntax::UnknownExpression, E);
874 bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
880 return WalkUpFromUserDefinedLiteral(S);
883 syntax::UserDefinedLiteralExpression *
884 buildUserDefinedLiteral(UserDefinedLiteral *S) {
887 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
889 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
891 return new (allocator()) syntax::CharUserDefinedLiteralExpression;
893 return new (allocator()) syntax::StringUserDefinedLiteralExpression;
907 if (
Literal.isIntegerLiteral())
908 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
910 assert(
Literal.isFloatingLiteral());
911 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
914 llvm_unreachable(
"Unknown literal operator kind.");
917 bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
918 Builder.markChildToken(S->
getBeginLoc(), syntax::NodeRole::LiteralToken);
919 Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
923 syntax::NameSpecifier *buildIdentifier(SourceRange SR,
924 bool DropBack =
false) {
925 auto NameSpecifierTokens = Builder.getRange(SR).drop_back(DropBack);
926 assert(NameSpecifierTokens.size() == 1);
927 Builder.markChildToken(NameSpecifierTokens.begin(),
928 syntax::NodeRole::Unknown);
929 auto *NS =
new (allocator()) syntax::IdentifierNameSpecifier;
930 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
934 syntax::NameSpecifier *buildSimpleTemplateName(SourceRange SR) {
935 auto NameSpecifierTokens = Builder.getRange(SR);
941 auto *NS =
new (allocator()) syntax::SimpleTemplateNameSpecifier;
942 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
946 syntax::NameSpecifier *
947 buildNameSpecifier(
const NestedNameSpecifierLoc &NNSLoc) {
950 case NestedNameSpecifier::Kind::Global:
951 return new (allocator()) syntax::GlobalNameSpecifier;
953 case NestedNameSpecifier::Kind::Namespace:
959 case TypeLoc::Record:
960 case TypeLoc::InjectedClassName:
963 case TypeLoc::Typedef:
965 case TypeLoc::UnresolvedUsing:
966 return buildIdentifier(
970 case TypeLoc::DependentName:
972 case TypeLoc::TemplateSpecialization: {
975 if (BeginLoc.isInvalid())
976 BeginLoc = TST.getTemplateNameLoc();
977 return buildSimpleTemplateName({BeginLoc, TST.getEndLoc()});
979 case TypeLoc::Decltype: {
981 if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(
984 auto *NS =
new (allocator()) syntax::DecltypeNameSpecifier;
989 Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,
999 llvm::report_fatal_error(
"We don't yet support the __super specifier",
1011 for (
auto It = QualifierLoc; It; ) {
1012 auto *NS = buildNameSpecifier(It);
1017 if (
TypeLoc TL = It.getAsTypeLoc())
1018 It = TL.getPrefix();
1020 It = It.getAsNamespaceAndPrefix().Prefix;
1022 Builder.foldNode(Builder.getRange(QualifierLoc.
getSourceRange()),
1034 if (TemplateKeywordLoc.
isValid())
1035 Builder.markChildToken(TemplateKeywordLoc,
1040 Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1044 auto IdExpressionBeginLoc =
1047 auto *TheIdExpression =
new (allocator()) syntax::IdExpression;
1049 Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.
getEnd()),
1050 TheIdExpression, From);
1052 return TheIdExpression;
1074 Builder.foldNode(Builder.getExprRange(S),
1075 new (allocator()) syntax::MemberExpression, S);
1098 Builder.foldNode(Builder.getExprRange(S),
1099 new (allocator()) syntax::ThisExpression, S);
1108 Builder.foldNode(Builder.getExprRange(S),
1109 new (allocator()) syntax::ParenExpression, S);
1115 Builder.foldNode(Builder.getExprRange(S),
1116 new (allocator()) syntax::IntegerLiteralExpression, S);
1122 Builder.foldNode(Builder.getExprRange(S),
1123 new (allocator()) syntax::CharacterLiteralExpression, S);
1129 Builder.foldNode(Builder.getExprRange(S),
1130 new (allocator()) syntax::FloatingLiteralExpression, S);
1136 Builder.foldNode(Builder.getExprRange(S),
1137 new (allocator()) syntax::StringLiteralExpression, S);
1143 Builder.foldNode(Builder.getExprRange(S),
1144 new (allocator()) syntax::BoolLiteralExpression, S);
1150 Builder.foldNode(Builder.getExprRange(S),
1151 new (allocator()) syntax::CxxNullPtrExpression, S);
1161 Builder.foldNode(Builder.getExprRange(S),
1165 Builder.foldNode(Builder.getExprRange(S),
1177 Builder.foldNode(Builder.getExprRange(S),
1184 syntax::CallArguments *
1187 for (
auto *Arg : Args) {
1189 const auto *DelimiterToken =
1190 std::next(Builder.findToken(Arg->getEndLoc()));
1191 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1197 Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1198 (*(Args.end() - 1))->getEndLoc()),
1199 Arguments,
nullptr);
1207 const auto *LParenToken =
1211 if (LParenToken->kind() == clang::tok::l_paren)
1220 new (allocator()) syntax::CallExpression, S);
1229 return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1244 if (child->getSourceRange().isInvalid()) {
1246 syntax::NodeKind::PostfixUnaryOperatorExpression);
1257 case syntax::NodeKind::BinaryOperatorExpression:
1262 Builder.foldNode(Builder.getExprRange(S),
1265 case syntax::NodeKind::PrefixUnaryOperatorExpression:
1269 Builder.foldNode(Builder.getExprRange(S),
1273 case syntax::NodeKind::PostfixUnaryOperatorExpression:
1277 Builder.foldNode(Builder.getExprRange(S),
1281 case syntax::NodeKind::CallExpression: {
1284 const auto *LParenToken =
1288 if (LParenToken->kind() == clang::tok::l_paren)
1298 new (allocator()) syntax::CallExpression, S);
1301 case syntax::NodeKind::UnknownExpression:
1302 return WalkUpFromExpr(S);
1304 llvm_unreachable(
"getOperatorNodeKind() does not return this value");
1311 auto Tokens = Builder.getDeclarationRange(S);
1312 if (Tokens.front().kind() == tok::coloncolon) {
1349 syntax::ParameterDeclarationList *
1351 for (
auto *P : Params) {
1353 const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1354 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1358 if (!Params.empty())
1359 Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1360 Params.back()->getEndLoc()),
1361 Parameters,
nullptr);
1381 auto *TrailingReturnTokens = buildTrailingReturn(L);
1388 bool TraverseQualifier) {
1400 Builder.foldNode(Builder.getRange(SR),
1409 Builder.foldNode(Builder.getStmtRange(S),
1415 Builder.foldNode(Builder.getStmtRange(S),
1424 Builder.foldNode(Builder.getStmtRange(S),
1434 Builder.foldNode(Builder.getStmtRange(S),
1443 Builder.foldNode(Builder.getStmtRange(S),
1457 Builder.foldNode(Builder.getStmtRange(S),
1465 Builder.foldNode(Builder.getStmtRange(S),
1474 Builder.foldNode(Builder.getStmtRange(S),
1481 Builder.foldNode(Builder.getStmtRange(S),
1488 Builder.foldNode(Builder.getStmtRange(S),
1497 Builder.foldNode(Builder.getStmtRange(S),
1505 Builder.foldNode(Builder.getStmtRange(S),
1511 Builder.foldNode(Builder.getDeclarationRange(S),
1519 Builder.foldNode(Builder.getDeclarationRange(S),
1525 Builder.foldNode(Builder.getDeclarationRange(S),
1532 Builder.foldNode(Builder.getDeclarationRange(S),
1538 Builder.foldNode(Builder.getDeclarationRange(S),
1544 Builder.foldNode(Builder.getDeclarationRange(S),
1550 Builder.foldNode(Builder.getDeclarationRange(S),
1556 Builder.foldNode(Builder.getDeclarationRange(S),
1562 Builder.foldNode(Builder.getDeclarationRange(S),
1570 template <
class T>
bool processDeclaratorAndDeclaration(
T *D) {
1571 auto Range = getDeclaratorRange(
1572 Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1577 if (!
Range.getBegin().isValid()) {
1578 Builder.markChild(
new (allocator()) syntax::DeclaratorList,
1579 syntax::NodeRole::Declarators);
1580 Builder.foldNode(Builder.getDeclarationRange(D),
1581 new (allocator()) syntax::SimpleDeclaration, D);
1585 auto *N =
new (allocator()) syntax::SimpleDeclarator;
1586 Builder.foldNode(Builder.getRange(Range), N,
nullptr);
1587 Builder.markChild(N, syntax::NodeRole::ListElement);
1589 if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1592 const auto *DelimiterToken = std::next(Builder.findToken(
Range.getEnd()));
1593 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1594 Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1596 auto *DL =
new (allocator()) syntax::DeclaratorList;
1597 auto DeclarationRange = Builder.getDeclarationRange(D);
1598 Builder.foldList(DeclarationRange, DL,
nullptr);
1600 Builder.markChild(DL, syntax::NodeRole::Declarators);
1601 Builder.foldNode(DeclarationRange,
1602 new (allocator()) syntax::SimpleDeclaration, D);
1608 syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1613 auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1614 ReturnedType.getEndLoc());
1615 syntax::SimpleDeclarator *ReturnDeclarator =
nullptr;
1616 if (ReturnDeclaratorRange.isValid()) {
1617 ReturnDeclarator =
new (allocator()) syntax::SimpleDeclarator;
1618 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1619 ReturnDeclarator,
nullptr);
1623 auto Return = Builder.getRange(ReturnedType.getSourceRange());
1624 const auto *Arrow = Return.begin() - 1;
1625 assert(Arrow->kind() == tok::arrow);
1626 auto Tokens = llvm::ArrayRef(Arrow, Return.end());
1627 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1628 if (ReturnDeclarator)
1629 Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1630 auto *R =
new (allocator()) syntax::TrailingReturnType;
1631 Builder.foldNode(Tokens, R, L);
1635 void foldExplicitTemplateInstantiation(
1636 ArrayRef<syntax::Token> Range,
const syntax::Token *ExternKW,
1637 const syntax::Token *TemplateKW,
1638 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1639 assert(!ExternKW || ExternKW->
kind() == tok::kw_extern);
1640 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1641 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1642 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1643 Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1645 Range,
new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1648 syntax::TemplateDeclaration *foldTemplateDeclaration(
1649 ArrayRef<syntax::Token> Range,
const syntax::Token *TemplateKW,
1650 ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1651 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1652 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1654 auto *N =
new (allocator()) syntax::TemplateDeclaration;
1655 Builder.foldNode(Range, N, From);
1656 Builder.markChild(N, syntax::NodeRole::Declaration);
1661 llvm::BumpPtrAllocator &allocator() {
return Builder.allocator(); }
1663 syntax::TreeBuilder &Builder;
1664 const ASTContext &Context;
1668void syntax::TreeBuilder::noticeDeclWithoutSemicolon(
Decl *D) {
1669 DeclsWithoutSemicolons.insert(D);
1675 Pending.assignRole(*findToken(Loc),
Role);
1678void syntax::TreeBuilder::markChildToken(
const syntax::Token *
T, NodeRole R) {
1681 Pending.assignRole(*
T, R);
1684void syntax::TreeBuilder::markChild(
syntax::Node *N, NodeRole R) {
1689void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1690 auto *SN = Mapping.find(N);
1691 assert(SN !=
nullptr);
1695 auto *SN = Mapping.find(NNSLoc);
1696 assert(SN !=
nullptr);
1700void syntax::TreeBuilder::markStmtChild(
Stmt *Child, NodeRole
Role) {
1705 if (
Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1708 markExprChild(ChildExpr, NodeRole::Expression);
1711 Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);
1713 ChildNode = Mapping.find(Child);
1715 assert(ChildNode !=
nullptr);
1716 setRole(ChildNode,
Role);
1719void syntax::TreeBuilder::markExprChild(
Expr *Child, NodeRole
Role) {
1725 assert(ChildNode !=
nullptr);
1726 setRole(ChildNode,
Role);
1732 auto It = LocationToToken.find(L);
1733 assert(It != LocationToToken.end());
1740 TreeBuilder Builder(A, TBTM);
1741 BuildTreeVisitor(Context, Builder).TraverseAST(Context);
1742 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.
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)