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 const auto *Info =
C->getExplicitInstantiationInfo();
734 foldExplicitTemplateInstantiation(
735 Builder.getTemplateRange(
C), Builder.findToken(Info->ExternKeywordLoc),
736 Builder.findToken(Info->TemplateKeywordLoc),
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<ClassTemplateSpecializationDecl>(
C))
782 if (
const auto *Info = S->getExplicitSpecializationInfo())
783 ConsumeTemplateParameters(*Info->TemplateParams);
784 for (TemplateParameterList *TPL :
C->getTemplateParameterLists())
785 ConsumeTemplateParameters(*TPL);
789 bool WalkUpFromTranslationUnitDecl(TranslationUnitDecl *TU) {
798 Builder.markChildToken(S->
getLBracLoc(), NodeRole::OpenParen);
799 for (
auto *Child : S->
body())
800 Builder.markStmtChild(Child, NodeRole::Statement);
801 Builder.markChildToken(S->
getRBracLoc(), NodeRole::CloseParen);
803 Builder.foldNode(Builder.getStmtRange(S),
804 new (allocator()) syntax::CompoundStatement, S);
810 Builder.foldNode(Builder.getStmtRange(S),
811 new (allocator()) syntax::UnknownStatement, S);
815 bool TraverseIfStmt(IfStmt *S) {
816 bool Result = [&,
this]() {
839 bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) {
844 bool Result = [&,
this]() {
860 if (
auto *DS = dyn_cast_or_null<DeclStmt>(S)) {
862 for (
auto *D : DS->decls())
863 Builder.noticeDeclWithoutSemicolon(D);
864 }
else if (
auto *E = dyn_cast_or_null<Expr>(S)) {
870 bool TraverseOpaqueValueExpr(OpaqueValueExpr *VE) {
876 bool WalkUpFromExpr(Expr *E) {
877 assert(!
isImplicitExpr(E) &&
"should be handled by TraverseStmt");
878 Builder.foldNode(Builder.getExprRange(E),
879 new (allocator()) syntax::UnknownExpression, E);
883 bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
889 return WalkUpFromUserDefinedLiteral(S);
892 syntax::UserDefinedLiteralExpression *
893 buildUserDefinedLiteral(UserDefinedLiteral *S) {
896 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
898 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
900 return new (allocator()) syntax::CharUserDefinedLiteralExpression;
902 return new (allocator()) syntax::StringUserDefinedLiteralExpression;
916 if (
Literal.isIntegerLiteral())
917 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
919 assert(
Literal.isFloatingLiteral());
920 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
923 llvm_unreachable(
"Unknown literal operator kind.");
926 bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
927 Builder.markChildToken(S->
getBeginLoc(), syntax::NodeRole::LiteralToken);
928 Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
932 syntax::NameSpecifier *buildIdentifier(SourceRange SR,
933 bool DropBack =
false) {
934 auto NameSpecifierTokens = Builder.getRange(SR).drop_back(DropBack);
935 assert(NameSpecifierTokens.size() == 1);
936 Builder.markChildToken(NameSpecifierTokens.begin(),
937 syntax::NodeRole::Unknown);
938 auto *NS =
new (allocator()) syntax::IdentifierNameSpecifier;
939 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
943 syntax::NameSpecifier *buildSimpleTemplateName(SourceRange SR) {
944 auto NameSpecifierTokens = Builder.getRange(SR);
950 auto *NS =
new (allocator()) syntax::SimpleTemplateNameSpecifier;
951 Builder.foldNode(NameSpecifierTokens, NS,
nullptr);
955 syntax::NameSpecifier *
956 buildNameSpecifier(
const NestedNameSpecifierLoc &NNSLoc) {
959 case NestedNameSpecifier::Kind::Global:
960 return new (allocator()) syntax::GlobalNameSpecifier;
962 case NestedNameSpecifier::Kind::Namespace:
968 case TypeLoc::Record:
969 case TypeLoc::InjectedClassName:
972 case TypeLoc::Typedef:
974 case TypeLoc::UnresolvedUsing:
975 return buildIdentifier(
979 case TypeLoc::DependentName:
981 case TypeLoc::TemplateSpecialization: {
984 if (BeginLoc.isInvalid())
985 BeginLoc = TST.getTemplateNameLoc();
986 return buildSimpleTemplateName({BeginLoc, TST.getEndLoc()});
988 case TypeLoc::Decltype: {
990 if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(
993 auto *NS =
new (allocator()) syntax::DecltypeNameSpecifier;
998 Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,
1008 llvm::report_fatal_error(
"We don't yet support the __super specifier",
1020 for (
auto It = QualifierLoc; It; ) {
1021 auto *NS = buildNameSpecifier(It);
1026 if (
TypeLoc TL = It.getAsTypeLoc())
1027 It = TL.getPrefix();
1029 It = It.getAsNamespaceAndPrefix().Prefix;
1031 Builder.foldNode(Builder.getRange(QualifierLoc.
getSourceRange()),
1043 if (TemplateKeywordLoc.
isValid())
1044 Builder.markChildToken(TemplateKeywordLoc,
1049 Builder.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
1053 auto IdExpressionBeginLoc =
1056 auto *TheIdExpression =
new (allocator()) syntax::IdExpression;
1058 Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.
getEnd()),
1059 TheIdExpression, From);
1061 return TheIdExpression;
1083 Builder.foldNode(Builder.getExprRange(S),
1084 new (allocator()) syntax::MemberExpression, S);
1107 Builder.foldNode(Builder.getExprRange(S),
1108 new (allocator()) syntax::ThisExpression, S);
1117 Builder.foldNode(Builder.getExprRange(S),
1118 new (allocator()) syntax::ParenExpression, S);
1124 Builder.foldNode(Builder.getExprRange(S),
1125 new (allocator()) syntax::IntegerLiteralExpression, S);
1131 Builder.foldNode(Builder.getExprRange(S),
1132 new (allocator()) syntax::CharacterLiteralExpression, S);
1138 Builder.foldNode(Builder.getExprRange(S),
1139 new (allocator()) syntax::FloatingLiteralExpression, S);
1145 Builder.foldNode(Builder.getExprRange(S),
1146 new (allocator()) syntax::StringLiteralExpression, S);
1152 Builder.foldNode(Builder.getExprRange(S),
1153 new (allocator()) syntax::BoolLiteralExpression, S);
1159 Builder.foldNode(Builder.getExprRange(S),
1160 new (allocator()) syntax::CxxNullPtrExpression, S);
1170 Builder.foldNode(Builder.getExprRange(S),
1174 Builder.foldNode(Builder.getExprRange(S),
1186 Builder.foldNode(Builder.getExprRange(S),
1193 syntax::CallArguments *
1196 for (
auto *Arg : Args) {
1198 const auto *DelimiterToken =
1199 std::next(Builder.findToken(Arg->getEndLoc()));
1200 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1206 Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
1207 (*(Args.end() - 1))->getEndLoc()),
1208 Arguments,
nullptr);
1216 const auto *LParenToken =
1220 if (LParenToken->kind() == clang::tok::l_paren)
1229 new (allocator()) syntax::CallExpression, S);
1238 return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
1253 if (child->getSourceRange().isInvalid()) {
1255 syntax::NodeKind::PostfixUnaryOperatorExpression);
1266 case syntax::NodeKind::BinaryOperatorExpression:
1271 Builder.foldNode(Builder.getExprRange(S),
1274 case syntax::NodeKind::PrefixUnaryOperatorExpression:
1278 Builder.foldNode(Builder.getExprRange(S),
1282 case syntax::NodeKind::PostfixUnaryOperatorExpression:
1286 Builder.foldNode(Builder.getExprRange(S),
1290 case syntax::NodeKind::CallExpression: {
1293 const auto *LParenToken =
1297 if (LParenToken->kind() == clang::tok::l_paren)
1307 new (allocator()) syntax::CallExpression, S);
1310 case syntax::NodeKind::UnknownExpression:
1311 return WalkUpFromExpr(S);
1313 llvm_unreachable(
"getOperatorNodeKind() does not return this value");
1320 auto Tokens = Builder.getDeclarationRange(S);
1321 if (Tokens.front().kind() == tok::coloncolon) {
1358 syntax::ParameterDeclarationList *
1360 for (
auto *P : Params) {
1362 const auto *DelimiterToken = std::next(Builder.findToken(P->getEndLoc()));
1363 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1367 if (!Params.empty())
1368 Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
1369 Params.back()->getEndLoc()),
1370 Parameters,
nullptr);
1390 auto *TrailingReturnTokens = buildTrailingReturn(L);
1397 bool TraverseQualifier) {
1409 Builder.foldNode(Builder.getRange(SR),
1418 Builder.foldNode(Builder.getStmtRange(S),
1424 Builder.foldNode(Builder.getStmtRange(S),
1433 Builder.foldNode(Builder.getStmtRange(S),
1443 Builder.foldNode(Builder.getStmtRange(S),
1452 Builder.foldNode(Builder.getStmtRange(S),
1466 Builder.foldNode(Builder.getStmtRange(S),
1474 Builder.foldNode(Builder.getStmtRange(S),
1483 Builder.foldNode(Builder.getStmtRange(S),
1490 Builder.foldNode(Builder.getStmtRange(S),
1497 Builder.foldNode(Builder.getStmtRange(S),
1506 Builder.foldNode(Builder.getStmtRange(S),
1514 Builder.foldNode(Builder.getStmtRange(S),
1520 Builder.foldNode(Builder.getDeclarationRange(S),
1528 Builder.foldNode(Builder.getDeclarationRange(S),
1534 Builder.foldNode(Builder.getDeclarationRange(S),
1541 Builder.foldNode(Builder.getDeclarationRange(S),
1547 Builder.foldNode(Builder.getDeclarationRange(S),
1553 Builder.foldNode(Builder.getDeclarationRange(S),
1559 Builder.foldNode(Builder.getDeclarationRange(S),
1565 Builder.foldNode(Builder.getDeclarationRange(S),
1571 Builder.foldNode(Builder.getDeclarationRange(S),
1579 template <
class T>
bool processDeclaratorAndDeclaration(T *D) {
1580 auto Range = getDeclaratorRange(
1581 Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
1586 if (!
Range.getBegin().isValid()) {
1587 Builder.markChild(
new (allocator()) syntax::DeclaratorList,
1588 syntax::NodeRole::Declarators);
1589 Builder.foldNode(Builder.getDeclarationRange(D),
1590 new (allocator()) syntax::SimpleDeclaration, D);
1594 auto *N =
new (allocator()) syntax::SimpleDeclarator;
1595 Builder.foldNode(Builder.getRange(Range), N,
nullptr);
1596 Builder.markChild(N, syntax::NodeRole::ListElement);
1598 if (!Builder.isResponsibleForCreatingDeclaration(D)) {
1601 const auto *DelimiterToken = std::next(Builder.findToken(
Range.getEnd()));
1602 if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
1603 Builder.markChildToken(DelimiterToken, syntax::NodeRole::ListDelimiter);
1605 auto *DL =
new (allocator()) syntax::DeclaratorList;
1606 auto DeclarationRange = Builder.getDeclarationRange(D);
1607 Builder.foldList(DeclarationRange, DL,
nullptr);
1609 Builder.markChild(DL, syntax::NodeRole::Declarators);
1610 Builder.foldNode(DeclarationRange,
1611 new (allocator()) syntax::SimpleDeclaration, D);
1617 syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
1622 auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType),
1623 ReturnedType.getEndLoc());
1624 syntax::SimpleDeclarator *ReturnDeclarator =
nullptr;
1625 if (ReturnDeclaratorRange.isValid()) {
1626 ReturnDeclarator =
new (allocator()) syntax::SimpleDeclarator;
1627 Builder.foldNode(Builder.getRange(ReturnDeclaratorRange),
1628 ReturnDeclarator,
nullptr);
1632 auto Return = Builder.getRange(ReturnedType.getSourceRange());
1633 const auto *Arrow = Return.begin() - 1;
1634 assert(Arrow->kind() == tok::arrow);
1635 auto Tokens = llvm::ArrayRef(Arrow, Return.end());
1636 Builder.markChildToken(Arrow, syntax::NodeRole::ArrowToken);
1637 if (ReturnDeclarator)
1638 Builder.markChild(ReturnDeclarator, syntax::NodeRole::Declarator);
1639 auto *
R =
new (allocator()) syntax::TrailingReturnType;
1640 Builder.foldNode(Tokens, R, L);
1644 void foldExplicitTemplateInstantiation(
1645 ArrayRef<syntax::Token> Range,
const syntax::Token *ExternKW,
1646 const syntax::Token *TemplateKW,
1647 syntax::SimpleDeclaration *InnerDeclaration, Decl *From) {
1648 assert(!ExternKW || ExternKW->
kind() == tok::kw_extern);
1649 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1650 Builder.markChildToken(ExternKW, syntax::NodeRole::ExternKeyword);
1651 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1652 Builder.markChild(InnerDeclaration, syntax::NodeRole::Declaration);
1654 Range,
new (allocator()) syntax::ExplicitTemplateInstantiation, From);
1657 syntax::TemplateDeclaration *foldTemplateDeclaration(
1658 ArrayRef<syntax::Token> Range,
const syntax::Token *TemplateKW,
1659 ArrayRef<syntax::Token> TemplatedDeclaration, Decl *From) {
1660 assert(TemplateKW && TemplateKW->
kind() == tok::kw_template);
1661 Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
1663 auto *N =
new (allocator()) syntax::TemplateDeclaration;
1664 Builder.foldNode(Range, N, From);
1665 Builder.markChild(N, syntax::NodeRole::Declaration);
1670 llvm::BumpPtrAllocator &allocator() {
return Builder.allocator(); }
1672 syntax::TreeBuilder &Builder;
1673 const ASTContext &Context;
1677void syntax::TreeBuilder::noticeDeclWithoutSemicolon(
Decl *D) {
1678 DeclsWithoutSemicolons.insert(D);
1684 Pending.assignRole(*findToken(Loc),
Role);
1687void syntax::TreeBuilder::markChildToken(
const syntax::Token *T, NodeRole R) {
1690 Pending.assignRole(*T, R);
1693void syntax::TreeBuilder::markChild(
syntax::Node *N, NodeRole R) {
1698void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) {
1699 auto *SN = Mapping.find(N);
1700 assert(SN !=
nullptr);
1704 auto *SN = Mapping.find(NNSLoc);
1705 assert(SN !=
nullptr);
1709void syntax::TreeBuilder::markStmtChild(
Stmt *Child, NodeRole
Role) {
1714 if (
Expr *ChildExpr = dyn_cast<Expr>(Child)) {
1717 markExprChild(ChildExpr, NodeRole::Expression);
1720 Pending.foldChildren(TBTM.tokenBuffer(), getStmtRange(Child), ChildNode);
1722 ChildNode = Mapping.find(Child);
1724 assert(ChildNode !=
nullptr);
1725 setRole(ChildNode,
Role);
1728void syntax::TreeBuilder::markExprChild(
Expr *Child, NodeRole
Role) {
1734 assert(ChildNode !=
nullptr);
1735 setRole(ChildNode,
Role);
1741 auto It = LocationToToken.find(L);
1742 assert(It != LocationToToken.end());
1749 TreeBuilder Builder(A, TBTM);
1750 BuildTreeVisitor(Context, Builder).TraverseAST(Context);
1751 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)