46#include "llvm/ADT/ArrayRef.h"
47#include "llvm/ADT/SmallVector.h"
48#include "llvm/ADT/StringExtras.h"
49#include "llvm/ADT/StringRef.h"
50#include "llvm/Support/Compiler.h"
51#include "llvm/Support/ErrorHandling.h"
52#include "llvm/Support/raw_ostream.h"
65 class StmtPrinter :
public StmtVisitor<StmtPrinter> {
76 StringRef NL =
"\n",
const ASTContext *Context =
nullptr)
77 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
78 NL(NL), Context(Context) {}
82 void PrintStmt(
Stmt *S,
int SubIndent) {
83 IndentLevel += SubIndent;
84 if (isa_and_nonnull<Expr>(S)) {
92 Indent() <<
"<<<NULL STATEMENT>>>" << NL;
94 IndentLevel -= SubIndent;
97 void PrintInitStmt(
Stmt *S,
unsigned PrefixWidth) {
99 IndentLevel += (PrefixWidth + 1) / 2;
100 if (
auto *DS = dyn_cast<DeclStmt>(S))
101 PrintRawDeclStmt(DS);
103 PrintExpr(cast<Expr>(S));
105 IndentLevel -= (PrefixWidth + 1) / 2;
108 void PrintControlledStmt(
Stmt *S) {
109 if (
auto *CS = dyn_cast<CompoundStmt>(S)) {
111 PrintRawCompoundStmt(CS);
120 void PrintRawDecl(
Decl *
D);
121 void PrintRawDeclStmt(
const DeclStmt *S);
128 bool ForceNoStmt =
false);
133 void PrintExpr(
Expr *
E) {
140 raw_ostream &Indent(
int Delta = 0) {
141 for (
int i = 0, e = IndentLevel+Delta; i < e; ++i)
152 void VisitStmt(
Stmt *
Node) LLVM_ATTRIBUTE_UNUSED {
153 Indent() <<
"<<unknown stmt type>>" << NL;
156 void VisitExpr(
Expr *
Node) LLVM_ATTRIBUTE_UNUSED {
157 OS <<
"<<unknown expr type>>";
162#define ABSTRACT_STMT(CLASS)
163#define STMT(CLASS, PARENT) \
164 void Visit##CLASS(CLASS *Node);
165#include "clang/AST/StmtNodes.inc"
177 assert(
Node &&
"Compound statement cannot be null");
179 PrintFPPragmas(
Node);
180 for (
auto *I :
Node->body())
187 if (!S->hasStoredFPFeatures())
190 bool FEnvAccess =
false;
191 if (FPO.hasAllowFEnvAccessOverride()) {
192 FEnvAccess = FPO.getAllowFEnvAccessOverride();
193 Indent() <<
"#pragma STDC FENV_ACCESS " << (FEnvAccess ?
"ON" :
"OFF")
196 if (FPO.hasSpecifiedExceptionModeOverride()) {
198 FPO.getSpecifiedExceptionModeOverride();
199 if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
200 Indent() <<
"#pragma clang fp exceptions(";
201 switch (FPO.getSpecifiedExceptionModeOverride()) {
204 case LangOptions::FPE_Ignore:
207 case LangOptions::FPE_MayTrap:
210 case LangOptions::FPE_Strict:
217 if (FPO.hasConstRoundingModeOverride()) {
219 Indent() <<
"#pragma STDC FENV_ROUND ";
221 case llvm::RoundingMode::TowardZero:
222 OS <<
"FE_TOWARDZERO";
224 case llvm::RoundingMode::NearestTiesToEven:
225 OS <<
"FE_TONEAREST";
227 case llvm::RoundingMode::TowardPositive:
230 case llvm::RoundingMode::TowardNegative:
233 case llvm::RoundingMode::NearestTiesToAway:
234 OS <<
"FE_TONEARESTFROMZERO";
236 case llvm::RoundingMode::Dynamic:
240 llvm_unreachable(
"Invalid rounding mode");
246void StmtPrinter::PrintRawDecl(
Decl *
D) {
247 D->
print(OS, Policy, IndentLevel);
250void StmtPrinter::PrintRawDeclStmt(
const DeclStmt *S) {
256 Indent() <<
";" << NL;
261 PrintRawDeclStmt(
Node);
267 PrintRawCompoundStmt(
Node);
272 Indent(-1) <<
"case ";
273 PrintExpr(
Node->getLHS());
274 if (
Node->getRHS()) {
276 PrintExpr(
Node->getRHS());
280 PrintStmt(
Node->getSubStmt(), 0);
284 Indent(-1) <<
"default:" << NL;
285 PrintStmt(
Node->getSubStmt(), 0);
289 Indent(-1) <<
Node->getName() <<
":" << NL;
290 PrintStmt(
Node->getSubStmt(), 0);
295 for (
const auto *
Attr : Attrs) {
297 if (
Attr != Attrs.back())
301 PrintStmt(
Node->getSubStmt(), 0);
304void StmtPrinter::PrintRawIfStmt(
IfStmt *
If) {
305 if (
If->isConsteval()) {
307 if (
If->isNegatedConsteval())
311 PrintStmt(
If->getThen());
312 if (
Stmt *Else =
If->getElse()) {
323 PrintInitStmt(
If->getInit(), 4);
324 if (
const DeclStmt *DS =
If->getConditionVariableDeclStmt())
325 PrintRawDeclStmt(DS);
327 PrintExpr(
If->getCond());
330 if (
auto *CS = dyn_cast<CompoundStmt>(
If->getThen())) {
332 PrintRawCompoundStmt(CS);
333 OS << (
If->getElse() ?
" " : NL);
336 PrintStmt(
If->getThen());
337 if (
If->getElse()) Indent();
340 if (
Stmt *Else =
If->getElse()) {
343 if (
auto *CS = dyn_cast<CompoundStmt>(Else)) {
345 PrintRawCompoundStmt(CS);
347 }
else if (
auto *ElseIf = dyn_cast<IfStmt>(Else)) {
349 PrintRawIfStmt(ElseIf);
352 PrintStmt(
If->getElse());
357void StmtPrinter::VisitIfStmt(
IfStmt *
If) {
363 Indent() <<
"switch (";
365 PrintInitStmt(
Node->getInit(), 8);
366 if (
const DeclStmt *DS =
Node->getConditionVariableDeclStmt())
367 PrintRawDeclStmt(DS);
369 PrintExpr(
Node->getCond());
371 PrintControlledStmt(
Node->getBody());
375 Indent() <<
"while (";
376 if (
const DeclStmt *DS =
Node->getConditionVariableDeclStmt())
377 PrintRawDeclStmt(DS);
379 PrintExpr(
Node->getCond());
381 PrintStmt(
Node->getBody());
386 if (
auto *CS = dyn_cast<CompoundStmt>(
Node->getBody())) {
387 PrintRawCompoundStmt(CS);
391 PrintStmt(
Node->getBody());
396 PrintExpr(
Node->getCond());
403 PrintInitStmt(
Node->getInit(), 5);
405 OS << (
Node->getCond() ?
"; " :
";");
406 if (
const DeclStmt *DS =
Node->getConditionVariableDeclStmt())
407 PrintRawDeclStmt(DS);
408 else if (
Node->getCond())
409 PrintExpr(
Node->getCond());
411 if (
Node->getInc()) {
413 PrintExpr(
Node->getInc());
416 PrintControlledStmt(
Node->getBody());
421 if (
auto *DS = dyn_cast<DeclStmt>(
Node->getElement()))
422 PrintRawDeclStmt(DS);
424 PrintExpr(cast<Expr>(
Node->getElement()));
426 PrintExpr(
Node->getCollection());
428 PrintControlledStmt(
Node->getBody());
434 PrintInitStmt(
Node->getInit(), 5);
436 SubPolicy.SuppressInitializers =
true;
437 Node->getLoopVariable()->
print(OS, SubPolicy, IndentLevel);
439 PrintExpr(
Node->getRangeInit());
441 PrintControlledStmt(
Node->getBody());
446 if (
Node->isIfExists())
447 OS <<
"__if_exists (";
449 OS <<
"__if_not_exists (";
452 =
Node->getQualifierLoc().getNestedNameSpecifier())
455 OS <<
Node->getNameInfo() <<
") ";
457 PrintRawCompoundStmt(
Node->getSubStmt());
461 Indent() <<
"goto " <<
Node->getLabel()->getName() <<
";";
466 Indent() <<
"goto *";
467 PrintExpr(
Node->getTarget());
473 Indent() <<
"continue;";
478 Indent() <<
"break;";
483 Indent() <<
"return";
484 if (
Node->getRetValue()) {
486 PrintExpr(
Node->getRetValue());
495 if (
Node->isVolatile())
498 if (
Node->isAsmGoto())
502 VisitStringLiteral(
Node->getAsmString());
505 if (
Node->getNumOutputs() != 0 ||
Node->getNumInputs() != 0 ||
506 Node->getNumClobbers() != 0 ||
Node->getNumLabels() != 0)
509 for (
unsigned i = 0, e =
Node->getNumOutputs(); i != e; ++i) {
513 if (!
Node->getOutputName(i).empty()) {
515 OS <<
Node->getOutputName(i);
519 VisitStringLiteral(
Node->getOutputConstraintLiteral(i));
521 Visit(
Node->getOutputExpr(i));
526 if (
Node->getNumInputs() != 0 ||
Node->getNumClobbers() != 0 ||
527 Node->getNumLabels() != 0)
530 for (
unsigned i = 0, e =
Node->getNumInputs(); i != e; ++i) {
534 if (!
Node->getInputName(i).empty()) {
536 OS <<
Node->getInputName(i);
540 VisitStringLiteral(
Node->getInputConstraintLiteral(i));
542 Visit(
Node->getInputExpr(i));
547 if (
Node->getNumClobbers() != 0 ||
Node->getNumLabels())
550 for (
unsigned i = 0, e =
Node->getNumClobbers(); i != e; ++i) {
554 VisitStringLiteral(
Node->getClobberStringLiteral(i));
558 if (
Node->getNumLabels() != 0)
561 for (
unsigned i = 0, e =
Node->getNumLabels(); i != e; ++i) {
564 OS <<
Node->getLabelName(i);
573 Indent() <<
"__asm ";
574 if (
Node->hasBraces())
576 OS <<
Node->getAsmString() << NL;
577 if (
Node->hasBraces())
578 Indent() <<
"}" << NL;
582 PrintStmt(
Node->getCapturedDecl()->getBody());
587 if (
auto *TS = dyn_cast<CompoundStmt>(
Node->getTryBody())) {
588 PrintRawCompoundStmt(TS);
593 Indent() <<
"@catch(";
594 if (
Decl *DS = catchStmt->getCatchParamDecl())
597 if (
auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
598 PrintRawCompoundStmt(CS);
604 Indent() <<
"@finally";
605 if (
auto *CS = dyn_cast<CompoundStmt>(FS->getFinallyBody())) {
606 PrintRawCompoundStmt(CS);
616 Indent() <<
"@catch (...) { /* todo */ } " << NL;
620 Indent() <<
"@throw";
621 if (
Node->getThrowExpr()) {
623 PrintExpr(
Node->getThrowExpr());
628void StmtPrinter::VisitObjCAvailabilityCheckExpr(
630 OS <<
"@available(...)";
634 Indent() <<
"@synchronized (";
635 PrintExpr(
Node->getSynchExpr());
637 PrintRawCompoundStmt(
Node->getSynchBody());
642 Indent() <<
"@autoreleasepool";
643 PrintRawCompoundStmt(cast<CompoundStmt>(
Node->getSubStmt()));
649 if (
Decl *ExDecl =
Node->getExceptionDecl())
650 PrintRawDecl(ExDecl);
654 PrintRawCompoundStmt(cast<CompoundStmt>(
Node->getHandlerBlock()));
659 PrintRawCXXCatchStmt(
Node);
665 PrintRawCompoundStmt(
Node->getTryBlock());
666 for (
unsigned i = 0, e =
Node->getNumHandlers(); i < e; ++i) {
668 PrintRawCXXCatchStmt(
Node->getHandler(i));
674 Indent() << (
Node->getIsCXXTry() ?
"try " :
"__try ");
675 PrintRawCompoundStmt(
Node->getTryBlock());
679 PrintRawSEHExceptHandler(
E);
681 assert(F &&
"Must have a finally block...");
682 PrintRawSEHFinallyStmt(F);
689 PrintRawCompoundStmt(
Node->getBlock());
695 VisitExpr(
Node->getFilterExpr());
697 PrintRawCompoundStmt(
Node->getBlock());
703 PrintRawSEHExceptHandler(
Node);
709 PrintRawSEHFinallyStmt(
Node);
714 Indent() <<
"__leave;";
723 PrintStmt(
Node->getLoopStmt());
730 for (
auto *Clause : Clauses)
731 if (Clause && !Clause->isImplicit()) {
733 Printer.Visit(Clause);
736 if (!ForceNoStmt && S->hasAssociatedStmt())
737 PrintStmt(S->getRawStmt());
741 Indent() <<
"#pragma omp metadirective";
742 PrintOMPExecutableDirective(
Node);
746 Indent() <<
"#pragma omp parallel";
747 PrintOMPExecutableDirective(
Node);
751 Indent() <<
"#pragma omp simd";
752 PrintOMPExecutableDirective(
Node);
756 Indent() <<
"#pragma omp tile";
757 PrintOMPExecutableDirective(
Node);
761 Indent() <<
"#pragma omp unroll";
762 PrintOMPExecutableDirective(
Node);
766 Indent() <<
"#pragma omp reverse";
767 PrintOMPExecutableDirective(
Node);
771 Indent() <<
"#pragma omp interchange";
772 PrintOMPExecutableDirective(
Node);
776 Indent() <<
"#pragma omp for";
777 PrintOMPExecutableDirective(
Node);
781 Indent() <<
"#pragma omp for simd";
782 PrintOMPExecutableDirective(
Node);
786 Indent() <<
"#pragma omp sections";
787 PrintOMPExecutableDirective(
Node);
791 Indent() <<
"#pragma omp section";
792 PrintOMPExecutableDirective(
Node);
796 Indent() <<
"#pragma omp scope";
797 PrintOMPExecutableDirective(
Node);
801 Indent() <<
"#pragma omp single";
802 PrintOMPExecutableDirective(
Node);
806 Indent() <<
"#pragma omp master";
807 PrintOMPExecutableDirective(
Node);
811 Indent() <<
"#pragma omp critical";
812 if (
Node->getDirectiveName().getName()) {
814 Node->getDirectiveName().printName(OS, Policy);
817 PrintOMPExecutableDirective(
Node);
821 Indent() <<
"#pragma omp parallel for";
822 PrintOMPExecutableDirective(
Node);
825void StmtPrinter::VisitOMPParallelForSimdDirective(
827 Indent() <<
"#pragma omp parallel for simd";
828 PrintOMPExecutableDirective(
Node);
831void StmtPrinter::VisitOMPParallelMasterDirective(
833 Indent() <<
"#pragma omp parallel master";
834 PrintOMPExecutableDirective(
Node);
837void StmtPrinter::VisitOMPParallelMaskedDirective(
839 Indent() <<
"#pragma omp parallel masked";
840 PrintOMPExecutableDirective(
Node);
843void StmtPrinter::VisitOMPParallelSectionsDirective(
845 Indent() <<
"#pragma omp parallel sections";
846 PrintOMPExecutableDirective(
Node);
850 Indent() <<
"#pragma omp task";
851 PrintOMPExecutableDirective(
Node);
855 Indent() <<
"#pragma omp taskyield";
856 PrintOMPExecutableDirective(
Node);
860 Indent() <<
"#pragma omp barrier";
861 PrintOMPExecutableDirective(
Node);
865 Indent() <<
"#pragma omp taskwait";
866 PrintOMPExecutableDirective(
Node);
870 Indent() <<
"#pragma omp assume";
871 PrintOMPExecutableDirective(
Node);
875 Indent() <<
"#pragma omp error";
876 PrintOMPExecutableDirective(
Node);
880 Indent() <<
"#pragma omp taskgroup";
881 PrintOMPExecutableDirective(
Node);
885 Indent() <<
"#pragma omp flush";
886 PrintOMPExecutableDirective(
Node);
890 Indent() <<
"#pragma omp depobj";
891 PrintOMPExecutableDirective(
Node);
895 Indent() <<
"#pragma omp scan";
896 PrintOMPExecutableDirective(
Node);
900 Indent() <<
"#pragma omp ordered";
905 Indent() <<
"#pragma omp atomic";
906 PrintOMPExecutableDirective(
Node);
910 Indent() <<
"#pragma omp target";
911 PrintOMPExecutableDirective(
Node);
915 Indent() <<
"#pragma omp target data";
916 PrintOMPExecutableDirective(
Node);
919void StmtPrinter::VisitOMPTargetEnterDataDirective(
921 Indent() <<
"#pragma omp target enter data";
922 PrintOMPExecutableDirective(
Node,
true);
925void StmtPrinter::VisitOMPTargetExitDataDirective(
927 Indent() <<
"#pragma omp target exit data";
928 PrintOMPExecutableDirective(
Node,
true);
931void StmtPrinter::VisitOMPTargetParallelDirective(
933 Indent() <<
"#pragma omp target parallel";
934 PrintOMPExecutableDirective(
Node);
937void StmtPrinter::VisitOMPTargetParallelForDirective(
939 Indent() <<
"#pragma omp target parallel for";
940 PrintOMPExecutableDirective(
Node);
944 Indent() <<
"#pragma omp teams";
945 PrintOMPExecutableDirective(
Node);
948void StmtPrinter::VisitOMPCancellationPointDirective(
950 Indent() <<
"#pragma omp cancellation point "
951 << getOpenMPDirectiveName(
Node->getCancelRegion());
952 PrintOMPExecutableDirective(
Node);
956 Indent() <<
"#pragma omp cancel "
957 << getOpenMPDirectiveName(
Node->getCancelRegion());
958 PrintOMPExecutableDirective(
Node);
962 Indent() <<
"#pragma omp taskloop";
963 PrintOMPExecutableDirective(
Node);
966void StmtPrinter::VisitOMPTaskLoopSimdDirective(
968 Indent() <<
"#pragma omp taskloop simd";
969 PrintOMPExecutableDirective(
Node);
972void StmtPrinter::VisitOMPMasterTaskLoopDirective(
974 Indent() <<
"#pragma omp master taskloop";
975 PrintOMPExecutableDirective(
Node);
978void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
980 Indent() <<
"#pragma omp masked taskloop";
981 PrintOMPExecutableDirective(
Node);
984void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
986 Indent() <<
"#pragma omp master taskloop simd";
987 PrintOMPExecutableDirective(
Node);
990void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
992 Indent() <<
"#pragma omp masked taskloop simd";
993 PrintOMPExecutableDirective(
Node);
996void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
998 Indent() <<
"#pragma omp parallel master taskloop";
999 PrintOMPExecutableDirective(
Node);
1002void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
1004 Indent() <<
"#pragma omp parallel masked taskloop";
1005 PrintOMPExecutableDirective(
Node);
1008void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
1010 Indent() <<
"#pragma omp parallel master taskloop simd";
1011 PrintOMPExecutableDirective(
Node);
1014void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
1016 Indent() <<
"#pragma omp parallel masked taskloop simd";
1017 PrintOMPExecutableDirective(
Node);
1021 Indent() <<
"#pragma omp distribute";
1022 PrintOMPExecutableDirective(
Node);
1025void StmtPrinter::VisitOMPTargetUpdateDirective(
1027 Indent() <<
"#pragma omp target update";
1028 PrintOMPExecutableDirective(
Node,
true);
1031void StmtPrinter::VisitOMPDistributeParallelForDirective(
1033 Indent() <<
"#pragma omp distribute parallel for";
1034 PrintOMPExecutableDirective(
Node);
1037void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1039 Indent() <<
"#pragma omp distribute parallel for simd";
1040 PrintOMPExecutableDirective(
Node);
1043void StmtPrinter::VisitOMPDistributeSimdDirective(
1045 Indent() <<
"#pragma omp distribute simd";
1046 PrintOMPExecutableDirective(
Node);
1049void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1051 Indent() <<
"#pragma omp target parallel for simd";
1052 PrintOMPExecutableDirective(
Node);
1056 Indent() <<
"#pragma omp target simd";
1057 PrintOMPExecutableDirective(
Node);
1060void StmtPrinter::VisitOMPTeamsDistributeDirective(
1062 Indent() <<
"#pragma omp teams distribute";
1063 PrintOMPExecutableDirective(
Node);
1066void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1068 Indent() <<
"#pragma omp teams distribute simd";
1069 PrintOMPExecutableDirective(
Node);
1072void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1074 Indent() <<
"#pragma omp teams distribute parallel for simd";
1075 PrintOMPExecutableDirective(
Node);
1078void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1080 Indent() <<
"#pragma omp teams distribute parallel for";
1081 PrintOMPExecutableDirective(
Node);
1085 Indent() <<
"#pragma omp target teams";
1086 PrintOMPExecutableDirective(
Node);
1089void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1091 Indent() <<
"#pragma omp target teams distribute";
1092 PrintOMPExecutableDirective(
Node);
1095void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1097 Indent() <<
"#pragma omp target teams distribute parallel for";
1098 PrintOMPExecutableDirective(
Node);
1101void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1103 Indent() <<
"#pragma omp target teams distribute parallel for simd";
1104 PrintOMPExecutableDirective(
Node);
1107void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1109 Indent() <<
"#pragma omp target teams distribute simd";
1110 PrintOMPExecutableDirective(
Node);
1114 Indent() <<
"#pragma omp interop";
1115 PrintOMPExecutableDirective(
Node);
1119 Indent() <<
"#pragma omp dispatch";
1120 PrintOMPExecutableDirective(
Node);
1124 Indent() <<
"#pragma omp masked";
1125 PrintOMPExecutableDirective(
Node);
1129 Indent() <<
"#pragma omp loop";
1130 PrintOMPExecutableDirective(
Node);
1133void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1135 Indent() <<
"#pragma omp teams loop";
1136 PrintOMPExecutableDirective(
Node);
1139void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1141 Indent() <<
"#pragma omp target teams loop";
1142 PrintOMPExecutableDirective(
Node);
1145void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1147 Indent() <<
"#pragma omp parallel loop";
1148 PrintOMPExecutableDirective(
Node);
1151void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1153 Indent() <<
"#pragma omp target parallel loop";
1154 PrintOMPExecutableDirective(
Node);
1161 if (!S->clauses().empty()) {
1164 Printer.VisitClauseList(S->clauses());
1168 Indent() <<
"#pragma acc " << S->getDirectiveKind();
1169 PrintOpenACCClauseList(S);
1173 PrintOpenACCConstruct(S);
1174 PrintStmt(S->getStructuredBlock());
1178 PrintOpenACCConstruct(S);
1179 PrintStmt(S->getLoop());
1183 PrintOpenACCConstruct(S);
1184 PrintStmt(S->getLoop());
1188 PrintOpenACCConstruct(S);
1189 PrintStmt(S->getStructuredBlock());
1192 PrintOpenACCConstruct(S);
1193 PrintStmt(S->getStructuredBlock());
1196 PrintOpenACCConstruct(S);
1199 PrintOpenACCConstruct(S);
1202 PrintOpenACCConstruct(S);
1205 PrintOpenACCConstruct(S);
1209 Indent() <<
"#pragma acc wait";
1210 if (!S->getLParenLoc().isInvalid()) {
1212 if (S->hasDevNumExpr()) {
1214 S->getDevNumExpr()->printPretty(OS,
nullptr, Policy);
1218 if (S->hasQueuesTag())
1221 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](
const Expr *
E) {
1222 E->printPretty(OS, nullptr, Policy);
1228 PrintOpenACCClauseList(S);
1237 OS <<
Node->getBuiltinStr() <<
"()";
1241 llvm::report_fatal_error(
"Not implemented");
1245 PrintExpr(
Node->getSubExpr());
1249 if (
const auto *OCED = dyn_cast<OMPCapturedExprDecl>(
Node->getDecl())) {
1250 OCED->getInit()->IgnoreImpCasts()->printPretty(OS,
nullptr, Policy);
1253 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
Node->getDecl())) {
1254 TPOD->printAsExpr(OS, Policy);
1259 if (
Node->hasTemplateKeyword())
1262 isa<ParmVarDecl, NonTypeTemplateParmDecl>(
Node->getDecl()) &&
1263 Node->getDecl()->getIdentifier())
1264 OS <<
Node->getDecl()->getIdentifier()->deuglifiedName();
1266 Node->getNameInfo().printName(OS, Policy);
1267 if (
Node->hasExplicitTemplateArgs()) {
1269 if (!
Node->hadMultipleCandidates())
1270 if (
auto *TD = dyn_cast<TemplateDecl>(
Node->getDecl()))
1271 TPL = TD->getTemplateParameters();
1276void StmtPrinter::VisitDependentScopeDeclRefExpr(
1280 if (
Node->hasTemplateKeyword())
1282 OS <<
Node->getNameInfo();
1283 if (
Node->hasExplicitTemplateArgs())
1288 if (
Node->getQualifier())
1289 Node->getQualifier()->
print(OS, Policy);
1290 if (
Node->hasTemplateKeyword())
1292 OS <<
Node->getNameInfo();
1293 if (
Node->hasExplicitTemplateArgs())
1298 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
1299 if (
const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1300 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1301 DRE->getBeginLoc().isInvalid())
1309 if (
Node->getBase()) {
1312 PrintExpr(
Node->getBase());
1313 OS << (
Node->isArrow() ?
"->" :
".");
1316 OS << *
Node->getDecl();
1320 if (
Node->isSuperReceiver())
1322 else if (
Node->isObjectReceiver() &&
Node->getBase()) {
1323 PrintExpr(
Node->getBase());
1325 }
else if (
Node->isClassReceiver() &&
Node->getClassReceiver()) {
1326 OS <<
Node->getClassReceiver()->getName() <<
".";
1329 if (
Node->isImplicitProperty()) {
1330 if (
const auto *Getter =
Node->getImplicitPropertyGetter())
1331 Getter->getSelector().
print(OS);
1334 Node->getImplicitPropertySetter()->getSelector());
1336 OS <<
Node->getExplicitProperty()->getName();
1340 PrintExpr(
Node->getBaseExpr());
1342 PrintExpr(
Node->getKeyExpr());
1346void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1348 OS <<
"__builtin_sycl_unique_stable_name(";
1349 Node->getTypeSourceInfo()->getType().
print(OS, Policy);
1385 bool isSigned =
Node->getType()->isSignedIntegerType();
1388 if (isa<BitIntType>(
Node->getType())) {
1389 OS << (isSigned ?
"wb" :
"uwb");
1395 default: llvm_unreachable(
"Unexpected type for integer literal!");
1396 case BuiltinType::Char_S:
1397 case BuiltinType::Char_U: OS <<
"i8";
break;
1398 case BuiltinType::UChar: OS <<
"Ui8";
break;
1399 case BuiltinType::SChar: OS <<
"i8";
break;
1400 case BuiltinType::Short: OS <<
"i16";
break;
1401 case BuiltinType::UShort: OS <<
"Ui16";
break;
1402 case BuiltinType::Int:
break;
1403 case BuiltinType::UInt: OS <<
'U';
break;
1404 case BuiltinType::Long: OS <<
'L';
break;
1405 case BuiltinType::ULong: OS <<
"UL";
break;
1406 case BuiltinType::LongLong: OS <<
"LL";
break;
1407 case BuiltinType::ULongLong: OS <<
"ULL";
break;
1408 case BuiltinType::Int128:
1410 case BuiltinType::UInt128:
1412 case BuiltinType::WChar_S:
1413 case BuiltinType::WChar_U:
1421 OS <<
Node->getValueAsString(10);
1424 default: llvm_unreachable(
"Unexpected type for fixed point literal!");
1425 case BuiltinType::ShortFract: OS <<
"hr";
break;
1426 case BuiltinType::ShortAccum: OS <<
"hk";
break;
1427 case BuiltinType::UShortFract: OS <<
"uhr";
break;
1428 case BuiltinType::UShortAccum: OS <<
"uhk";
break;
1429 case BuiltinType::Fract: OS <<
"r";
break;
1430 case BuiltinType::Accum: OS <<
"k";
break;
1431 case BuiltinType::UFract: OS <<
"ur";
break;
1432 case BuiltinType::UAccum: OS <<
"uk";
break;
1433 case BuiltinType::LongFract: OS <<
"lr";
break;
1434 case BuiltinType::LongAccum: OS <<
"lk";
break;
1435 case BuiltinType::ULongFract: OS <<
"ulr";
break;
1436 case BuiltinType::ULongAccum: OS <<
"ulk";
break;
1443 Node->getValue().toString(Str);
1445 if (Str.find_first_not_of(
"-0123456789") == StringRef::npos)
1453 default: llvm_unreachable(
"Unexpected type for float literal!");
1454 case BuiltinType::Half:
break;
1455 case BuiltinType::Ibm128:
break;
1456 case BuiltinType::Double:
break;
1457 case BuiltinType::Float16: OS <<
"F16";
break;
1458 case BuiltinType::Float: OS <<
'F';
break;
1459 case BuiltinType::LongDouble: OS <<
'L';
break;
1460 case BuiltinType::Float128: OS <<
'Q';
break;
1471 PrintExpr(
Node->getSubExpr());
1481 PrintExpr(
Node->getSubExpr());
1486 if (!
Node->isPostfix()) {
1491 switch (
Node->getOpcode()) {
1500 if (isa<UnaryOperator>(
Node->getSubExpr()))
1505 PrintExpr(
Node->getSubExpr());
1507 if (
Node->isPostfix())
1512 OS <<
"__builtin_offsetof(";
1513 Node->getTypeSourceInfo()->getType().
print(OS, Policy);
1515 bool PrintedSomething =
false;
1516 for (
unsigned i = 0, n =
Node->getNumComponents(); i < n; ++i) {
1523 PrintedSomething =
true;
1536 if (PrintedSomething)
1539 PrintedSomething =
true;
1540 OS <<
Id->getName();
1545void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1548 if (
Node->getKind() == UETT_AlignOf) {
1550 Spelling =
"alignof";
1552 Spelling =
"_Alignof";
1554 Spelling =
"__alignof";
1559 if (
Node->isArgumentType()) {
1561 Node->getArgumentType().
print(OS, Policy);
1565 PrintExpr(
Node->getArgumentExpr());
1571 if (
Node->isExprPredicate())
1572 PrintExpr(
Node->getControllingExpr());
1574 Node->getControllingType()->getType().
print(OS, Policy);
1582 T.print(OS, Policy);
1584 PrintExpr(Assoc.getAssociationExpr());
1590 PrintExpr(
Node->getLHS());
1592 PrintExpr(
Node->getRHS());
1597 PrintExpr(
Node->getBase());
1599 PrintExpr(
Node->getRowIdx());
1602 PrintExpr(
Node->getColumnIdx());
1607 PrintExpr(
Node->getBase());
1609 if (
Node->getLowerBound())
1610 PrintExpr(
Node->getLowerBound());
1611 if (
Node->getColonLocFirst().isValid()) {
1613 if (
Node->getLength())
1614 PrintExpr(
Node->getLength());
1616 if (
Node->isOMPArraySection() &&
Node->getColonLocSecond().isValid()) {
1618 if (
Node->getStride())
1619 PrintExpr(
Node->getStride());
1632 PrintExpr(
Node->getBase());
1637 for (
unsigned I = 0,
E =
Node->numOfIterators(); I <
E; ++I) {
1638 auto *VD = cast<ValueDecl>(
Node->getIteratorDecl(I));
1639 VD->getType().print(OS, Policy);
1641 OS <<
" " << VD->getName() <<
" = ";
1642 PrintExpr(
Range.Begin);
1644 PrintExpr(
Range.End);
1647 PrintExpr(
Range.Step);
1656 for (
unsigned i = 0, e =
Call->getNumArgs(); i != e; ++i) {
1657 if (isa<CXXDefaultArgExpr>(
Call->getArg(i))) {
1663 PrintExpr(
Call->getArg(i));
1668 PrintExpr(
Call->getCallee());
1670 PrintCallArgs(
Call);
1675 if (
const auto *TE = dyn_cast<CXXThisExpr>(
E))
1676 return TE->isImplicit();
1682 PrintExpr(
Node->getBase());
1684 auto *ParentMember = dyn_cast<MemberExpr>(
Node->getBase());
1686 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1690 OS << (
Node->isArrow() ?
"->" :
".");
1693 if (
auto *FD = dyn_cast<FieldDecl>(
Node->getMemberDecl()))
1694 if (FD->isAnonymousStructOrUnion())
1699 if (
Node->hasTemplateKeyword())
1701 OS <<
Node->getMemberNameInfo();
1703 if (
auto *FD = dyn_cast<FunctionDecl>(
Node->getMemberDecl())) {
1704 if (!
Node->hadMultipleCandidates())
1705 if (
auto *FTD = FD->getPrimaryTemplate())
1706 TPL = FTD->getTemplateParameters();
1707 }
else if (
auto *VTSD =
1708 dyn_cast<VarTemplateSpecializationDecl>(
Node->getMemberDecl()))
1709 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1710 if (
Node->hasExplicitTemplateArgs())
1715 PrintExpr(
Node->getBase());
1716 OS << (
Node->isArrow() ?
"->isa" :
".isa");
1720 PrintExpr(
Node->getBase());
1722 OS <<
Node->getAccessor().getName();
1727 Node->getTypeAsWritten().
print(OS, Policy);
1729 PrintExpr(
Node->getSubExpr());
1736 PrintExpr(
Node->getInitializer());
1741 PrintExpr(
Node->getSubExpr());
1745 PrintExpr(
Node->getLHS());
1747 PrintExpr(
Node->getRHS());
1751 PrintExpr(
Node->getLHS());
1753 PrintExpr(
Node->getRHS());
1757 PrintExpr(
Node->getCond());
1759 PrintExpr(
Node->getLHS());
1761 PrintExpr(
Node->getRHS());
1768 PrintExpr(
Node->getCommon());
1770 PrintExpr(
Node->getFalseExpr());
1774 OS <<
"&&" <<
Node->getLabel()->getName();
1777void StmtPrinter::VisitStmtExpr(
StmtExpr *
E) {
1779 PrintRawCompoundStmt(
E->getSubStmt());
1784 OS <<
"__builtin_choose_expr(";
1785 PrintExpr(
Node->getCond());
1787 PrintExpr(
Node->getLHS());
1789 PrintExpr(
Node->getRHS());
1793void StmtPrinter::VisitGNUNullExpr(
GNUNullExpr *) {
1798 OS <<
"__builtin_shufflevector(";
1799 for (
unsigned i = 0, e =
Node->getNumSubExprs(); i != e; ++i) {
1801 PrintExpr(
Node->getExpr(i));
1807 OS <<
"__builtin_convertvector(";
1808 PrintExpr(
Node->getSrcExpr());
1815 if (
Node->getSyntacticForm()) {
1816 Visit(
Node->getSyntacticForm());
1821 for (
unsigned i = 0, e =
Node->getNumInits(); i != e; ++i) {
1823 if (
Node->getInit(i))
1824 PrintExpr(
Node->getInit(i));
1835 PrintExpr(
Node->getSubExpr());
1845 for (
unsigned i = 0, e =
Node->getNumExprs(); i != e; ++i) {
1847 PrintExpr(
Node->getExpr(i));
1853 bool NeedsEquals =
true;
1855 if (
D.isFieldDesignator()) {
1856 if (
D.getDotLoc().isInvalid()) {
1858 OS << II->getName() <<
":";
1859 NeedsEquals =
false;
1862 OS <<
"." <<
D.getFieldName()->getName();
1866 if (
D.isArrayDesignator()) {
1867 PrintExpr(
Node->getArrayIndex(
D));
1869 PrintExpr(
Node->getArrayRangeStart(
D));
1871 PrintExpr(
Node->getArrayRangeEnd(
D));
1881 PrintExpr(
Node->getInit());
1884void StmtPrinter::VisitDesignatedInitUpdateExpr(
1888 PrintExpr(
Node->getBase());
1891 OS <<
"/*updater*/";
1892 PrintExpr(
Node->getUpdater());
1897 OS <<
"/*no init*/";
1901 if (
Node->getType()->getAsCXXRecordDecl()) {
1902 OS <<
"/*implicit*/";
1906 OS <<
"/*implicit*/(";
1909 if (
Node->getType()->isRecordType())
1917 OS <<
"__builtin_va_arg(";
1918 PrintExpr(
Node->getSubExpr());
1925 PrintExpr(
Node->getSyntacticForm());
1929 const char *Name =
nullptr;
1930 switch (
Node->getOp()) {
1931#define BUILTIN(ID, TYPE, ATTRS)
1932#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1933 case AtomicExpr::AO ## ID: \
1936#include "clang/Basic/Builtins.inc"
1941 PrintExpr(
Node->getPtr());
1942 if (
Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1943 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1944 Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
1945 Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
1946 Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
1948 PrintExpr(
Node->getVal1());
1950 if (
Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1951 Node->isCmpXChg()) {
1953 PrintExpr(
Node->getVal2());
1955 if (
Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1956 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1958 PrintExpr(
Node->getWeak());
1960 if (
Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1961 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1963 PrintExpr(
Node->getOrder());
1965 if (
Node->isCmpXChg()) {
1967 PrintExpr(
Node->getOrderFail());
1975 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1976 if (
Node->getNumArgs() == 1) {
1978 PrintExpr(
Node->getArg(0));
1980 PrintExpr(
Node->getArg(0));
1983 }
else if (Kind == OO_Arrow) {
1984 PrintExpr(
Node->getArg(0));
1985 }
else if (Kind == OO_Call || Kind == OO_Subscript) {
1986 PrintExpr(
Node->getArg(0));
1987 OS << (
Kind == OO_Call ?
'(' :
'[');
1988 for (
unsigned ArgIdx = 1; ArgIdx <
Node->getNumArgs(); ++ArgIdx) {
1991 if (!isa<CXXDefaultArgExpr>(
Node->getArg(ArgIdx)))
1992 PrintExpr(
Node->getArg(ArgIdx));
1994 OS << (
Kind == OO_Call ?
')' :
']');
1995 }
else if (
Node->getNumArgs() == 1) {
1997 PrintExpr(
Node->getArg(0));
1998 }
else if (
Node->getNumArgs() == 2) {
1999 PrintExpr(
Node->getArg(0));
2001 PrintExpr(
Node->getArg(1));
2003 llvm_unreachable(
"unknown overloaded operator");
2010 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2011 PrintExpr(
Node->getImplicitObjectArgument());
2014 VisitCallExpr(cast<CallExpr>(
Node));
2018 PrintExpr(
Node->getCallee());
2020 PrintCallArgs(
Node->getConfig());
2022 PrintCallArgs(
Node);
2026void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2029 Node->getDecomposedForm();
2030 PrintExpr(
const_cast<Expr*
>(Decomposed.
LHS));
2032 PrintExpr(
const_cast<Expr*
>(Decomposed.
RHS));
2036 OS <<
Node->getCastName() <<
'<';
2037 Node->getTypeAsWritten().
print(OS, Policy);
2039 PrintExpr(
Node->getSubExpr());
2044 VisitCXXNamedCastExpr(
Node);
2048 VisitCXXNamedCastExpr(
Node);
2052 VisitCXXNamedCastExpr(
Node);
2056 VisitCXXNamedCastExpr(
Node);
2060 OS <<
"__builtin_bit_cast(";
2061 Node->getTypeInfoAsWritten()->getType().
print(OS, Policy);
2063 PrintExpr(
Node->getSubExpr());
2068 VisitCXXNamedCastExpr(
Node);
2073 if (
Node->isTypeOperand()) {
2074 Node->getTypeOperandSourceInfo()->getType().
print(OS, Policy);
2076 PrintExpr(
Node->getExprOperand());
2083 if (
Node->isTypeOperand()) {
2084 Node->getTypeOperandSourceInfo()->getType().
print(OS, Policy);
2086 PrintExpr(
Node->getExprOperand());
2092 PrintExpr(
Node->getBaseExpr());
2093 if (
Node->isArrow())
2098 Node->getQualifierLoc().getNestedNameSpecifier())
2100 OS <<
Node->getPropertyDecl()->getDeclName();
2104 PrintExpr(
Node->getBase());
2106 PrintExpr(
Node->getIdx());
2111 switch (
Node->getLiteralOperatorKind()) {
2113 OS << cast<StringLiteral>(
Node->getArg(0)->IgnoreImpCasts())->getString();
2116 const auto *DRE = cast<DeclRefExpr>(
Node->getCallee()->IgnoreImpCasts());
2118 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2123 if (!DRE->hadMultipleCandidates())
2124 if (
const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2125 TPL = TD->getTemplateParameters();
2126 OS <<
"operator\"\"" <<
Node->getUDSuffix()->getName();
2134 char C = (char)
P.getAsIntegral().getZExtValue();
2141 const auto *
Int = cast<IntegerLiteral>(
Node->getCookedLiteral());
2147 auto *
Float = cast<FloatingLiteral>(
Node->getCookedLiteral());
2153 PrintExpr(
Node->getCookedLiteral());
2156 OS <<
Node->getUDSuffix()->getName();
2160 OS << (
Node->getValue() ?
"true" :
"false");
2172 if (!
Node->getSubExpr())
2176 PrintExpr(
Node->getSubExpr());
2189 auto TargetType =
Node->getType();
2190 auto *
Auto = TargetType->getContainedDeducedType();
2191 bool Bare =
Auto &&
Auto->isDeduced();
2196 TargetType.print(OS, Policy);
2201 if (!
Node->isListInitialization())
2203 PrintExpr(
Node->getSubExpr());
2204 if (!
Node->isListInitialization())
2209 PrintExpr(
Node->getSubExpr());
2214 if (
Node->isStdInitListInitialization())
2216 else if (
Node->isListInitialization())
2221 ArgEnd =
Node->arg_end();
2222 Arg != ArgEnd; ++Arg) {
2223 if ((*Arg)->isDefaultArgument())
2225 if (Arg !=
Node->arg_begin())
2229 if (
Node->isStdInitListInitialization())
2231 else if (
Node->isListInitialization())
2239 bool NeedComma =
false;
2240 switch (
Node->getCaptureDefault()) {
2255 CEnd =
Node->explicit_capture_end();
2258 if (
C->capturesVLAType())
2265 switch (
C->getCaptureKind()) {
2277 OS <<
C->getCapturedVar()->getName();
2281 OS <<
C->getCapturedVar()->getName();
2285 llvm_unreachable(
"VLA type in explicit captures.");
2288 if (
C->isPackExpansion())
2291 if (
Node->isInitCapture(
C)) {
2293 auto *
D = cast<VarDecl>(
C->getCapturedVar());
2295 llvm::StringRef
Pre;
2296 llvm::StringRef
Post;
2298 !isa<ParenListExpr>(
D->getInit())) {
2306 PrintExpr(
D->getInit());
2312 if (!
Node->getExplicitTemplateParameters().empty()) {
2313 Node->getTemplateParameterList()->
print(
2314 OS,
Node->getLambdaClass()->getASTContext(),
2318 if (
Node->hasExplicitParameters()) {
2328 std::string ParamStr =
2330 ?
P->getIdentifier()->deuglifiedName().str()
2331 :
P->getNameAsString();
2332 P->getOriginalType().print(OS, Policy, ParamStr);
2341 if (
Node->isMutable())
2350 if (
Node->hasExplicitResultType()) {
2352 Proto->getReturnType().print(OS, Policy);
2361 PrintRawCompoundStmt(
Node->getCompoundStmtBody());
2366 TSInfo->getType().print(OS, Policy);
2373 if (
E->isGlobalNew())
2376 unsigned NumPlace =
E->getNumPlacementArgs();
2377 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(
E->getPlacementArg(0))) {
2379 PrintExpr(
E->getPlacementArg(0));
2380 for (
unsigned i = 1; i < NumPlace; ++i) {
2381 if (isa<CXXDefaultArgExpr>(
E->getPlacementArg(i)))
2384 PrintExpr(
E->getPlacementArg(i));
2388 if (
E->isParenTypeId())
2392 llvm::raw_string_ostream
s(TypeS);
2394 if (std::optional<Expr *> Size =
E->getArraySize())
2395 (*Size)->printPretty(
s, Helper, Policy);
2398 E->getAllocatedType().print(OS, Policy, TypeS);
2399 if (
E->isParenTypeId())
2403 if (InitStyle != CXXNewInitializationStyle::None) {
2404 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2405 !isa<ParenListExpr>(
E->getInitializer());
2408 PrintExpr(
E->getInitializer());
2415 if (
E->isGlobalDelete())
2418 if (
E->isArrayForm())
2420 PrintExpr(
E->getArgument());
2424 PrintExpr(
E->getBase());
2429 if (
E->getQualifier())
2430 E->getQualifier()->print(OS, Policy);
2434 OS << II->getName();
2436 E->getDestroyedType().print(OS, Policy);
2440 if (
E->isListInitialization() && !
E->isStdInitListInitialization())
2443 for (
unsigned i = 0, e =
E->getNumArgs(); i != e; ++i) {
2444 if (isa<CXXDefaultArgExpr>(
E->getArg(i))) {
2450 PrintExpr(
E->getArg(i));
2453 if (
E->isListInitialization() && !
E->isStdInitListInitialization())
2459 OS <<
"<forwarded>";
2463 PrintExpr(
E->getSubExpr());
2468 PrintExpr(
E->getSubExpr());
2471void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2473 Node->getTypeAsWritten().
print(OS, Policy);
2474 if (!
Node->isListInitialization())
2476 for (
auto Arg =
Node->arg_begin(), ArgEnd =
Node->arg_end(); Arg != ArgEnd;
2478 if (Arg !=
Node->arg_begin())
2482 if (!
Node->isListInitialization())
2486void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2488 if (!
Node->isImplicitAccess()) {
2489 PrintExpr(
Node->getBase());
2490 OS << (
Node->isArrow() ?
"->" :
".");
2494 if (
Node->hasTemplateKeyword())
2496 OS <<
Node->getMemberNameInfo();
2497 if (
Node->hasExplicitTemplateArgs())
2502 if (!
Node->isImplicitAccess()) {
2503 PrintExpr(
Node->getBase());
2504 OS << (
Node->isArrow() ?
"->" :
".");
2508 if (
Node->hasTemplateKeyword())
2510 OS <<
Node->getMemberNameInfo();
2511 if (
Node->hasExplicitTemplateArgs())
2517 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I) {
2527 E->getQueriedType().print(OS, Policy);
2533 PrintExpr(
E->getQueriedExpression());
2539 PrintExpr(
E->getOperand());
2544 PrintExpr(
E->getPattern());
2549 OS <<
"sizeof...(" << *
E->getPack() <<
")";
2553 PrintExpr(
E->getPackIdExpression());
2555 PrintExpr(
E->getIndexExpr());
2559void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2561 OS << *
Node->getParameterPack();
2564void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2566 Visit(
Node->getReplacement());
2570 OS << *
E->getParameterPack();
2574 PrintExpr(
Node->getSubExpr());
2580 PrintExpr(
E->getLHS());
2586 PrintExpr(
E->getRHS());
2593 llvm::interleaveComma(
Node->getInitExprs(), OS,
2594 [&](
Expr *
E) { PrintExpr(E); });
2602 if (
E->getTemplateKWLoc().isValid())
2604 OS <<
E->getFoundDecl()->getName();
2607 E->getNamedConcept()->getTemplateParameters());
2612 auto LocalParameters =
E->getLocalParameters();
2613 if (!LocalParameters.empty()) {
2616 PrintRawDecl(LocalParam);
2617 if (LocalParam != LocalParameters.back())
2624 auto Requirements =
E->getRequirements();
2626 if (
auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2627 if (TypeReq->isSubstitutionFailure())
2628 OS <<
"<<error-type>>";
2630 TypeReq->getType()->getType().print(OS, Policy);
2631 }
else if (
auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2632 if (ExprReq->isCompound())
2634 if (ExprReq->isExprSubstitutionFailure())
2635 OS <<
"<<error-expression>>";
2637 PrintExpr(ExprReq->getExpr());
2638 if (ExprReq->isCompound()) {
2640 if (ExprReq->getNoexceptLoc().isValid())
2642 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2643 if (!RetReq.isEmpty()) {
2645 if (RetReq.isSubstitutionFailure())
2646 OS <<
"<<error-type>>";
2647 else if (RetReq.isTypeConstraint())
2648 RetReq.getTypeConstraint()->print(OS, Policy);
2652 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2654 if (NestedReq->hasInvalidConstraint())
2655 OS <<
"<<error-expression>>";
2657 PrintExpr(NestedReq->getConstraintExpr());
2667 Visit(S->getBody());
2672 if (S->getOperand()) {
2674 Visit(S->getOperand());
2679void StmtPrinter::VisitCoawaitExpr(
CoawaitExpr *S) {
2681 PrintExpr(S->getOperand());
2686 PrintExpr(S->getOperand());
2689void StmtPrinter::VisitCoyieldExpr(
CoyieldExpr *S) {
2691 PrintExpr(S->getOperand());
2698 VisitStringLiteral(
Node->getString());
2703 Visit(
E->getSubExpr());
2709 for (
auto I = Ch.begin(),
E = Ch.end(); I !=
E; ++I) {
2710 if (I != Ch.begin())
2719 for (
unsigned I = 0, N =
E->getNumElements(); I != N; ++I) {
2726 Visit(Element.Value);
2727 if (Element.isPackExpansion())
2735 Node->getEncodedType().
print(OS, Policy);
2746 OS <<
"@protocol(" << *
Node->getProtocol() <<
')';
2771 for (
unsigned i = 0, e = Mess->
getNumArgs(); i != e; ++i) {
2773 if (i > 0) OS <<
' ';
2781 PrintExpr(Mess->
getArg(i));
2788 OS << (
Node->getValue() ?
"__objc_yes" :
"__objc_no");
2793 PrintExpr(
E->getSubExpr());
2798 OS <<
'(' <<
E->getBridgeKindName();
2801 PrintExpr(
E->getSubExpr());
2810 if (isa<FunctionNoProtoType>(AFT)) {
2812 }
else if (!BD->
param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2817 std::string ParamStr = (*AI)->getNameAsString();
2818 (*AI)->getType().print(OS, Policy, ParamStr);
2821 const auto *FT = cast<FunctionProtoType>(AFT);
2822 if (FT->isVariadic()) {
2832 PrintExpr(
Node->getSourceExpr());
2837 llvm_unreachable(
"Cannot print TypoExpr nodes");
2841 OS <<
"<recovery-expr>(";
2842 const char *Sep =
"";
2843 for (
Expr *
E :
Node->subExpressions()) {
2852 OS <<
"__builtin_astype(";
2853 PrintExpr(
Node->getSrcExpr());
2860 PrintExpr(
Node->getArgLValue());
2873 StringRef NL,
const ASTContext *Context)
const {
2874 StmtPrinter
P(Out, Helper, Policy, Indentation, NL, Context);
2875 P.Visit(
const_cast<Stmt *
>(
this));
2880 unsigned Indentation, StringRef NL,
2882 StmtPrinter
P(Out, Helper, Policy, Indentation, NL, Context);
2883 P.PrintControlledStmt(
const_cast<Stmt *
>(
this));
2889 llvm::raw_string_ostream TempOut(Buf);
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines enumerations for expression traits intrinsics.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines several types used to describe C++ lambda expressions that are shared between the parser and ...
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
Defines an enumeration for C++ overloaded operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
const LangOptions & getLangOpts() const
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Attr - This represents one attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const
Represents an attribute applied to a statement.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
A builtin binary operation expression such as "x + y" or "x <= y".
StringRef getOpcodeStr() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
param_iterator param_end()
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
param_iterator param_begin()
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
Represents a C++2a __builtin_bit_cast(T, v) expression.
This class is used for builtin types like 'int'.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a call to a CUDA kernel function.
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
CXXCatchStmt - This represents a C++ catch block.
A C++ const_cast expression (C++ [expr.const.cast]).
Represents a call to a C++ constructor.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ member access expression where the actual member referenced could not be resolved be...
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Represents a folding of a pack over an operator.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
Abstract class common to all of the C++ "named"/"keyword" casts.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
A call to an overloaded operator written using operator syntax.
Represents a list-initialization with parenthesis.
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
A C++ static_cast expression (C++ [expr.static.cast]).
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents a C++ functional cast expression that builds a temporary object.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CXXTryStmt - A C++ try block, including all handlers.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
This captures a statement into a function.
CaseStmt - Represent a case statement.
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Represents a 'co_await' expression.
CompoundAssignOperator - For compound assignments (e.g.
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConditionalOperator - The ?: ternary operator.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents a 'co_return' statement in the C++ Coroutines TS.
Represents the body of a coroutine.
Represents a 'co_yield' expression.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Represents a 'co_await' expression while the type of the promise is dependent.
A qualified reference to a name whose declaration cannot yet be resolved.
Represents a single C99 designator.
Represents a C99 designated initializer expression.
DoStmt - This represents a 'do/while' stmt.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
Represents a reference to #emded data.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
ArrayRef< ParmVarDecl * > parameters() const
bool isVariadic() const
Whether this function is variadic.
Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...
Represents a prototype with parameter type info, e.g.
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
FunctionType - C99 6.7.5.3 - Function Declarators.
This represents a GCC inline-assembly statement extension.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
AssociationTy< false > Association
GotoStmt - This represents a direct goto.
This class represents temporary values used to represent inout and out arguments in HLSL.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IfStmt - This represents an if/then/else.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
IndirectGotoStmt - This represents an indirect goto.
Describes an C or C++ initializer list.
LabelStmt - Represents a label, which has a substatement.
Describes the capture of a variable or of this, or of a C++1y init-capture.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
llvm::RoundingMode RoundingMode
FPExceptionModeKind
Possible floating point exception behavior.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
This represents a Microsoft inline-assembly statement extension.
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
A member reference to an MSPropertyDecl.
MS property subscript expression.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
Represents a place-holder for an object not to be initialized by anything.
NullStmt - This is the null statement ";": C99 6.8.3p3.
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
This represents '#pragma omp atomic' directive.
This represents '#pragma omp barrier' directive.
This represents '#pragma omp cancel' directive.
This represents '#pragma omp cancellation point' directive.
Representation of an OpenMP canonical loop.
This represents '#pragma omp critical' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
This represents '#pragma omp depobj' directive.
This represents '#pragma omp dispatch' directive.
This represents '#pragma omp distribute' directive.
This represents '#pragma omp distribute parallel for' composite directive.
This represents '#pragma omp distribute parallel for simd' composite directive.
This represents '#pragma omp distribute simd' composite directive.
This represents '#pragma omp error' directive.
This is a basic class for representing single OpenMP executable directive.
This represents '#pragma omp flush' directive.
This represents '#pragma omp for' directive.
This represents '#pragma omp for simd' directive.
This represents '#pragma omp loop' directive.
Represents the '#pragma omp interchange' loop transformation directive.
This represents '#pragma omp interop' directive.
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
This represents '#pragma omp masked' directive.
This represents '#pragma omp masked taskloop' directive.
This represents '#pragma omp masked taskloop simd' directive.
This represents '#pragma omp master' directive.
This represents '#pragma omp master taskloop' directive.
This represents '#pragma omp master taskloop simd' directive.
This represents '#pragma omp ordered' directive.
This represents '#pragma omp parallel' directive.
This represents '#pragma omp parallel for' directive.
This represents '#pragma omp parallel for simd' directive.
This represents '#pragma omp parallel loop' directive.
This represents '#pragma omp parallel masked' directive.
This represents '#pragma omp parallel masked taskloop' directive.
This represents '#pragma omp parallel masked taskloop simd' directive.
This represents '#pragma omp parallel master' directive.
This represents '#pragma omp parallel master taskloop' directive.
This represents '#pragma omp parallel master taskloop simd' directive.
This represents '#pragma omp parallel sections' directive.
Represents the '#pragma omp reverse' loop transformation directive.
This represents '#pragma omp scan' directive.
This represents '#pragma omp scope' directive.
This represents '#pragma omp section' directive.
This represents '#pragma omp sections' directive.
This represents '#pragma omp simd' directive.
This represents '#pragma omp single' directive.
This represents '#pragma omp target data' directive.
This represents '#pragma omp target' directive.
This represents '#pragma omp target enter data' directive.
This represents '#pragma omp target exit data' directive.
This represents '#pragma omp target parallel' directive.
This represents '#pragma omp target parallel for' directive.
This represents '#pragma omp target parallel for simd' directive.
This represents '#pragma omp target parallel loop' directive.
This represents '#pragma omp target simd' directive.
This represents '#pragma omp target teams' directive.
This represents '#pragma omp target teams distribute' combined directive.
This represents '#pragma omp target teams distribute parallel for' combined directive.
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
This represents '#pragma omp target teams distribute simd' combined directive.
This represents '#pragma omp target teams loop' directive.
This represents '#pragma omp target update' directive.
This represents '#pragma omp task' directive.
This represents '#pragma omp taskloop' directive.
This represents '#pragma omp taskloop simd' directive.
This represents '#pragma omp taskgroup' directive.
This represents '#pragma omp taskwait' directive.
This represents '#pragma omp taskyield' directive.
This represents '#pragma omp teams' directive.
This represents '#pragma omp teams distribute' directive.
This represents '#pragma omp teams distribute parallel for' composite directive.
This represents '#pragma omp teams distribute parallel for simd' composite directive.
This represents '#pragma omp teams distribute simd' combined directive.
This represents '#pragma omp teams loop' directive.
This represents the '#pragma omp tile' loop transformation directive.
This represents the '#pragma omp unroll' loop transformation directive.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Represents Objective-C's @catch statement.
Represents Objective-C's @finally statement.
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
Represents Objective-C's @autoreleasepool Statement.
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCEncodeExpr, used for @encode in Objective-C.
Represents Objective-C's collection statement.
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Selector getSelector() const
@ SuperInstance
The receiver is the instance of the superclass object.
@ Instance
The receiver is an object instance.
@ SuperClass
The receiver is a superclass.
@ Class
The receiver is a class.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
@ Array
An index into an array.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
This is the base class for an OpenACC statement-level construct, other construct types are expected t...
This class represents a 'loop' construct.
Represents a C++11 pack expansion that produces a sequence of expressions.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
[C99 6.4.2.2] - A predefined identifier such as func.
StringRef getIdentKindName() const
virtual bool handledStmt(Stmt *E, raw_ostream &OS)=0
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Represents a __leave statement.
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
bool isUnarySelector() const
unsigned getNumArgs() const
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
llvm::iterator_range< child_iterator > child_range
void dumpPretty(const ASTContext &Context) const
dumpPretty/printPretty - These two methods do a "pretty print" of the AST back to its original source...
StringLiteral - This represents a string literal expression, e.g.
void outputString(raw_ostream &OS) const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
SwitchStmt - This represents a 'switch' stmt.
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Pack
The template argument is actually a parameter pack.
ArgKind getKind() const
Return the kind of stored template argument.
Stores a list of template parameters for a TemplateDecl and its derived classes.
A container of type source information.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
const T * castAs() const
Member-template castAs<specific type>.
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
@ 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 call to the builtin function __builtin_va_arg.
@ CInit
C-style initialization with assignment.
@ CallInit
Call-style initialization (C++98)
WhileStmt - This represents a 'while' stmt.
A static requirement that can be used in a requires-expression to check properties of types and expre...
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ LCK_ByCopy
Capturing by copy (a.k.a., by value)
@ LCK_ByRef
Capturing by reference.
@ LCK_VLAType
Capturing variable-length array type.
@ LCK_StarThis
Capturing the *this object by copy.
@ LCK_This
Capturing the *this object by reference.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
CXXNewInitializationStyle
Iterator range representation begin:end[:step].
An element in an Objective-C dictionary literal.
Describes how types, statements, expressions, and declarations should be printed.
unsigned Alignof
Whether we can use 'alignof' rather than '__alignof'.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned ConstantsAsWritten
Whether we should print the constant expressions as written in the sources.
unsigned IncludeNewlines
When true, include newlines after statements like "break", etc.
unsigned Indentation
The number of spaces to use to indent each line.
unsigned TerseOutput
Provide a 'terse' output.
unsigned UnderscoreAlignof
Whether we can use '_Alignof' rather than '__alignof'.
unsigned SuppressImplicitBase
When true, don't print the implicit 'self' or 'this' expressions.
Iterator for iterating over Stmt * arrays that contain only T *.