2975 lines · cpp
1//===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which10// pretty print the AST back out to C code.11//12//===----------------------------------------------------------------------===//13 14#include "clang/AST/ASTContext.h"15#include "clang/AST/Attr.h"16#include "clang/AST/Decl.h"17#include "clang/AST/DeclBase.h"18#include "clang/AST/DeclCXX.h"19#include "clang/AST/DeclObjC.h"20#include "clang/AST/DeclOpenACC.h"21#include "clang/AST/DeclOpenMP.h"22#include "clang/AST/DeclTemplate.h"23#include "clang/AST/Expr.h"24#include "clang/AST/ExprCXX.h"25#include "clang/AST/ExprObjC.h"26#include "clang/AST/ExprOpenMP.h"27#include "clang/AST/NestedNameSpecifier.h"28#include "clang/AST/OpenMPClause.h"29#include "clang/AST/PrettyPrinter.h"30#include "clang/AST/Stmt.h"31#include "clang/AST/StmtCXX.h"32#include "clang/AST/StmtObjC.h"33#include "clang/AST/StmtOpenMP.h"34#include "clang/AST/StmtSYCL.h"35#include "clang/AST/StmtVisitor.h"36#include "clang/AST/TemplateBase.h"37#include "clang/AST/Type.h"38#include "clang/Basic/ExpressionTraits.h"39#include "clang/Basic/IdentifierTable.h"40#include "clang/Basic/JsonSupport.h"41#include "clang/Basic/LLVM.h"42#include "clang/Basic/Lambda.h"43#include "clang/Basic/OpenMPKinds.h"44#include "clang/Basic/OperatorKinds.h"45#include "clang/Basic/SourceLocation.h"46#include "clang/Basic/TypeTraits.h"47#include "clang/Lex/Lexer.h"48#include "llvm/ADT/ArrayRef.h"49#include "llvm/ADT/STLExtras.h"50#include "llvm/ADT/StringExtras.h"51#include "llvm/ADT/StringRef.h"52#include "llvm/Support/Compiler.h"53#include "llvm/Support/ErrorHandling.h"54#include "llvm/Support/raw_ostream.h"55#include <cassert>56#include <optional>57#include <string>58 59using namespace clang;60 61//===----------------------------------------------------------------------===//62// StmtPrinter Visitor63//===----------------------------------------------------------------------===//64 65namespace {66 67 class StmtPrinter : public StmtVisitor<StmtPrinter> {68 raw_ostream &OS;69 unsigned IndentLevel;70 PrinterHelper* Helper;71 PrintingPolicy Policy;72 std::string NL;73 const ASTContext *Context;74 75 public:76 StmtPrinter(raw_ostream &os, PrinterHelper *helper,77 const PrintingPolicy &Policy, unsigned Indentation = 0,78 StringRef NL = "\n", const ASTContext *Context = nullptr)79 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),80 NL(NL), Context(Context) {}81 82 void PrintStmt(Stmt *S) { PrintStmt(S, Policy.Indentation); }83 84 void PrintStmt(Stmt *S, int SubIndent) {85 IndentLevel += SubIndent;86 if (isa_and_nonnull<Expr>(S)) {87 // If this is an expr used in a stmt context, indent and newline it.88 Indent();89 Visit(S);90 OS << ";" << NL;91 } else if (S) {92 Visit(S);93 } else {94 Indent() << "<<<NULL STATEMENT>>>" << NL;95 }96 IndentLevel -= SubIndent;97 }98 99 void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {100 // FIXME: Cope better with odd prefix widths.101 IndentLevel += (PrefixWidth + 1) / 2;102 if (auto *DS = dyn_cast<DeclStmt>(S))103 PrintRawDeclStmt(DS);104 else105 PrintExpr(cast<Expr>(S));106 OS << "; ";107 IndentLevel -= (PrefixWidth + 1) / 2;108 }109 110 void PrintControlledStmt(Stmt *S) {111 if (auto *CS = dyn_cast<CompoundStmt>(S)) {112 OS << " ";113 PrintRawCompoundStmt(CS);114 OS << NL;115 } else {116 OS << NL;117 PrintStmt(S);118 }119 }120 121 void PrintRawCompoundStmt(CompoundStmt *S);122 void PrintRawDecl(Decl *D);123 void PrintRawDeclStmt(const DeclStmt *S);124 void PrintRawIfStmt(IfStmt *If);125 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);126 void PrintCallArgs(CallExpr *E);127 void PrintRawSEHExceptHandler(SEHExceptStmt *S);128 void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);129 void PrintOMPExecutableDirective(OMPExecutableDirective *S,130 bool ForceNoStmt = false);131 void PrintFPPragmas(CompoundStmt *S);132 void PrintOpenACCClauseList(OpenACCConstructStmt *S);133 void PrintOpenACCConstruct(OpenACCConstructStmt *S);134 135 void PrintExpr(Expr *E) {136 if (E)137 Visit(E);138 else139 OS << "<null expr>";140 }141 142 raw_ostream &Indent(int Delta = 0) {143 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)144 OS << " ";145 return OS;146 }147 148 void Visit(Stmt* S) {149 if (Helper && Helper->handledStmt(S,OS))150 return;151 else StmtVisitor<StmtPrinter>::Visit(S);152 }153 154 [[maybe_unused]] void VisitStmt(Stmt *Node) {155 Indent() << "<<unknown stmt type>>" << NL;156 }157 158 [[maybe_unused]] void VisitExpr(Expr *Node) {159 OS << "<<unknown expr type>>";160 }161 162 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);163 164#define ABSTRACT_STMT(CLASS)165#define STMT(CLASS, PARENT) \166 void Visit##CLASS(CLASS *Node);167#include "clang/AST/StmtNodes.inc"168 };169 170} // namespace171 172//===----------------------------------------------------------------------===//173// Stmt printing methods.174//===----------------------------------------------------------------------===//175 176/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and177/// with no newline after the }.178void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {179 assert(Node && "Compound statement cannot be null");180 OS << "{" << NL;181 PrintFPPragmas(Node);182 for (auto *I : Node->body())183 PrintStmt(I);184 185 Indent() << "}";186}187 188void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {189 if (!S->hasStoredFPFeatures())190 return;191 FPOptionsOverride FPO = S->getStoredFPFeatures();192 bool FEnvAccess = false;193 if (FPO.hasAllowFEnvAccessOverride()) {194 FEnvAccess = FPO.getAllowFEnvAccessOverride();195 Indent() << "#pragma STDC FENV_ACCESS " << (FEnvAccess ? "ON" : "OFF")196 << NL;197 }198 if (FPO.hasSpecifiedExceptionModeOverride()) {199 LangOptions::FPExceptionModeKind EM =200 FPO.getSpecifiedExceptionModeOverride();201 if (!FEnvAccess || EM != LangOptions::FPE_Strict) {202 Indent() << "#pragma clang fp exceptions(";203 switch (FPO.getSpecifiedExceptionModeOverride()) {204 default:205 break;206 case LangOptions::FPE_Ignore:207 OS << "ignore";208 break;209 case LangOptions::FPE_MayTrap:210 OS << "maytrap";211 break;212 case LangOptions::FPE_Strict:213 OS << "strict";214 break;215 }216 OS << ")\n";217 }218 }219 if (FPO.hasConstRoundingModeOverride()) {220 LangOptions::RoundingMode RM = FPO.getConstRoundingModeOverride();221 Indent() << "#pragma STDC FENV_ROUND ";222 switch (RM) {223 case llvm::RoundingMode::TowardZero:224 OS << "FE_TOWARDZERO";225 break;226 case llvm::RoundingMode::NearestTiesToEven:227 OS << "FE_TONEAREST";228 break;229 case llvm::RoundingMode::TowardPositive:230 OS << "FE_UPWARD";231 break;232 case llvm::RoundingMode::TowardNegative:233 OS << "FE_DOWNWARD";234 break;235 case llvm::RoundingMode::NearestTiesToAway:236 OS << "FE_TONEARESTFROMZERO";237 break;238 case llvm::RoundingMode::Dynamic:239 OS << "FE_DYNAMIC";240 break;241 default:242 llvm_unreachable("Invalid rounding mode");243 }244 OS << NL;245 }246}247 248void StmtPrinter::PrintRawDecl(Decl *D) {249 D->print(OS, Policy, IndentLevel);250}251 252void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {253 SmallVector<Decl *, 2> Decls(S->decls());254 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);255}256 257void StmtPrinter::VisitNullStmt(NullStmt *Node) {258 Indent() << ";" << NL;259}260 261void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {262 Indent();263 PrintRawDeclStmt(Node);264 // Certain pragma declarations shouldn't have a semi-colon after them.265 if (!Node->isSingleDecl() ||266 !isa<OpenACCDeclareDecl, OpenACCRoutineDecl>(Node->getSingleDecl()))267 OS << ";";268 OS << NL;269}270 271void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {272 Indent();273 PrintRawCompoundStmt(Node);274 OS << "" << NL;275}276 277void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {278 Indent(-1) << "case ";279 PrintExpr(Node->getLHS());280 if (Node->getRHS()) {281 OS << " ... ";282 PrintExpr(Node->getRHS());283 }284 OS << ":" << NL;285 286 PrintStmt(Node->getSubStmt(), 0);287}288 289void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {290 Indent(-1) << "default:" << NL;291 PrintStmt(Node->getSubStmt(), 0);292}293 294void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {295 Indent(-1) << Node->getName() << ":" << NL;296 PrintStmt(Node->getSubStmt(), 0);297}298 299void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {300 ArrayRef<const Attr *> Attrs = Node->getAttrs();301 for (const auto *Attr : Attrs) {302 Attr->printPretty(OS, Policy);303 if (Attr != Attrs.back())304 OS << ' ';305 }306 307 PrintStmt(Node->getSubStmt(), 0);308}309 310void StmtPrinter::PrintRawIfStmt(IfStmt *If) {311 if (If->isConsteval()) {312 OS << "if ";313 if (If->isNegatedConsteval())314 OS << "!";315 OS << "consteval";316 OS << NL;317 PrintStmt(If->getThen());318 if (Stmt *Else = If->getElse()) {319 Indent();320 OS << "else";321 PrintStmt(Else);322 OS << NL;323 }324 return;325 }326 327 OS << "if (";328 if (If->getInit())329 PrintInitStmt(If->getInit(), 4);330 if (const DeclStmt *DS = If->getConditionVariableDeclStmt())331 PrintRawDeclStmt(DS);332 else333 PrintExpr(If->getCond());334 OS << ')';335 336 if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {337 OS << ' ';338 PrintRawCompoundStmt(CS);339 OS << (If->getElse() ? " " : NL);340 } else {341 OS << NL;342 PrintStmt(If->getThen());343 if (If->getElse()) Indent();344 }345 346 if (Stmt *Else = If->getElse()) {347 OS << "else";348 349 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {350 OS << ' ';351 PrintRawCompoundStmt(CS);352 OS << NL;353 } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {354 OS << ' ';355 PrintRawIfStmt(ElseIf);356 } else {357 OS << NL;358 PrintStmt(If->getElse());359 }360 }361}362 363void StmtPrinter::VisitIfStmt(IfStmt *If) {364 Indent();365 PrintRawIfStmt(If);366}367 368void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {369 Indent() << "switch (";370 if (Node->getInit())371 PrintInitStmt(Node->getInit(), 8);372 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())373 PrintRawDeclStmt(DS);374 else375 PrintExpr(Node->getCond());376 OS << ")";377 PrintControlledStmt(Node->getBody());378}379 380void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {381 Indent() << "while (";382 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())383 PrintRawDeclStmt(DS);384 else385 PrintExpr(Node->getCond());386 OS << ")" << NL;387 PrintStmt(Node->getBody());388}389 390void StmtPrinter::VisitDoStmt(DoStmt *Node) {391 Indent() << "do ";392 if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {393 PrintRawCompoundStmt(CS);394 OS << " ";395 } else {396 OS << NL;397 PrintStmt(Node->getBody());398 Indent();399 }400 401 OS << "while (";402 PrintExpr(Node->getCond());403 OS << ");" << NL;404}405 406void StmtPrinter::VisitForStmt(ForStmt *Node) {407 Indent() << "for (";408 if (Node->getInit())409 PrintInitStmt(Node->getInit(), 5);410 else411 OS << (Node->getCond() ? "; " : ";");412 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())413 PrintRawDeclStmt(DS);414 else if (Node->getCond())415 PrintExpr(Node->getCond());416 OS << ";";417 if (Node->getInc()) {418 OS << " ";419 PrintExpr(Node->getInc());420 }421 OS << ")";422 PrintControlledStmt(Node->getBody());423}424 425void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {426 Indent() << "for (";427 if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))428 PrintRawDeclStmt(DS);429 else430 PrintExpr(cast<Expr>(Node->getElement()));431 OS << " in ";432 PrintExpr(Node->getCollection());433 OS << ")";434 PrintControlledStmt(Node->getBody());435}436 437void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {438 Indent() << "for (";439 if (Node->getInit())440 PrintInitStmt(Node->getInit(), 5);441 PrintingPolicy SubPolicy(Policy);442 SubPolicy.SuppressInitializers = true;443 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);444 OS << " : ";445 PrintExpr(Node->getRangeInit());446 OS << ")";447 PrintControlledStmt(Node->getBody());448}449 450void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {451 Indent();452 if (Node->isIfExists())453 OS << "__if_exists (";454 else455 OS << "__if_not_exists (";456 457 Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);458 OS << Node->getNameInfo() << ") ";459 460 PrintRawCompoundStmt(Node->getSubStmt());461}462 463void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {464 Indent() << "goto " << Node->getLabel()->getName() << ";";465 if (Policy.IncludeNewlines) OS << NL;466}467 468void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {469 Indent() << "goto *";470 PrintExpr(Node->getTarget());471 OS << ";";472 if (Policy.IncludeNewlines) OS << NL;473}474 475void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {476 Indent();477 if (Node->hasLabelTarget())478 OS << "continue " << Node->getLabelDecl()->getIdentifier()->getName()479 << ';';480 else481 OS << "continue;";482 if (Policy.IncludeNewlines) OS << NL;483}484 485void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {486 Indent();487 if (Node->hasLabelTarget())488 OS << "break " << Node->getLabelDecl()->getIdentifier()->getName() << ';';489 else490 OS << "break;";491 if (Policy.IncludeNewlines) OS << NL;492}493 494void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {495 Indent() << "return";496 if (Node->getRetValue()) {497 OS << " ";498 PrintExpr(Node->getRetValue());499 }500 OS << ";";501 if (Policy.IncludeNewlines) OS << NL;502}503 504void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {505 Indent() << "asm ";506 507 if (Node->isVolatile())508 OS << "volatile ";509 510 if (Node->isAsmGoto())511 OS << "goto ";512 513 OS << "(";514 Visit(Node->getAsmStringExpr());515 516 // Outputs517 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||518 Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)519 OS << " : ";520 521 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {522 if (i != 0)523 OS << ", ";524 525 if (!Node->getOutputName(i).empty()) {526 OS << '[';527 OS << Node->getOutputName(i);528 OS << "] ";529 }530 531 Visit(Node->getOutputConstraintExpr(i));532 OS << " (";533 Visit(Node->getOutputExpr(i));534 OS << ")";535 }536 537 // Inputs538 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||539 Node->getNumLabels() != 0)540 OS << " : ";541 542 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {543 if (i != 0)544 OS << ", ";545 546 if (!Node->getInputName(i).empty()) {547 OS << '[';548 OS << Node->getInputName(i);549 OS << "] ";550 }551 552 Visit(Node->getInputConstraintExpr(i));553 OS << " (";554 Visit(Node->getInputExpr(i));555 OS << ")";556 }557 558 // Clobbers559 if (Node->getNumClobbers() != 0 || Node->getNumLabels())560 OS << " : ";561 562 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {563 if (i != 0)564 OS << ", ";565 566 Visit(Node->getClobberExpr(i));567 }568 569 // Labels570 if (Node->getNumLabels() != 0)571 OS << " : ";572 573 for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {574 if (i != 0)575 OS << ", ";576 OS << Node->getLabelName(i);577 }578 579 OS << ");";580 if (Policy.IncludeNewlines) OS << NL;581}582 583void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {584 // FIXME: Implement MS style inline asm statement printer.585 Indent() << "__asm ";586 if (Node->hasBraces())587 OS << "{" << NL;588 OS << Node->getAsmString() << NL;589 if (Node->hasBraces())590 Indent() << "}" << NL;591}592 593void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {594 PrintStmt(Node->getCapturedDecl()->getBody());595}596 597void StmtPrinter::VisitSYCLKernelCallStmt(SYCLKernelCallStmt *Node) {598 PrintStmt(Node->getOutlinedFunctionDecl()->getBody());599}600 601void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {602 Indent() << "@try";603 if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {604 PrintRawCompoundStmt(TS);605 OS << NL;606 }607 608 for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) {609 Indent() << "@catch(";610 if (Decl *DS = catchStmt->getCatchParamDecl())611 PrintRawDecl(DS);612 OS << ")";613 if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {614 PrintRawCompoundStmt(CS);615 OS << NL;616 }617 }618 619 if (ObjCAtFinallyStmt *FS = Node->getFinallyStmt()) {620 Indent() << "@finally";621 if (auto *CS = dyn_cast<CompoundStmt>(FS->getFinallyBody())) {622 PrintRawCompoundStmt(CS);623 OS << NL;624 }625 }626}627 628void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {629}630 631void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {632 Indent() << "@catch (...) { /* todo */ } " << NL;633}634 635void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {636 Indent() << "@throw";637 if (Node->getThrowExpr()) {638 OS << " ";639 PrintExpr(Node->getThrowExpr());640 }641 OS << ";" << NL;642}643 644void StmtPrinter::VisitObjCAvailabilityCheckExpr(645 ObjCAvailabilityCheckExpr *Node) {646 OS << "@available(...)";647}648 649void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {650 Indent() << "@synchronized (";651 PrintExpr(Node->getSynchExpr());652 OS << ")";653 PrintRawCompoundStmt(Node->getSynchBody());654 OS << NL;655}656 657void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {658 Indent() << "@autoreleasepool";659 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getSubStmt()));660 OS << NL;661}662 663void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {664 OS << "catch (";665 if (Decl *ExDecl = Node->getExceptionDecl())666 PrintRawDecl(ExDecl);667 else668 OS << "...";669 OS << ") ";670 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));671}672 673void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {674 Indent();675 PrintRawCXXCatchStmt(Node);676 OS << NL;677}678 679void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {680 Indent() << "try ";681 PrintRawCompoundStmt(Node->getTryBlock());682 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {683 OS << " ";684 PrintRawCXXCatchStmt(Node->getHandler(i));685 }686 OS << NL;687}688 689void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {690 Indent() << (Node->getIsCXXTry() ? "try " : "__try ");691 PrintRawCompoundStmt(Node->getTryBlock());692 SEHExceptStmt *E = Node->getExceptHandler();693 SEHFinallyStmt *F = Node->getFinallyHandler();694 if(E)695 PrintRawSEHExceptHandler(E);696 else {697 assert(F && "Must have a finally block...");698 PrintRawSEHFinallyStmt(F);699 }700 OS << NL;701}702 703void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {704 OS << "__finally ";705 PrintRawCompoundStmt(Node->getBlock());706 OS << NL;707}708 709void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {710 OS << "__except (";711 VisitExpr(Node->getFilterExpr());712 OS << ")" << NL;713 PrintRawCompoundStmt(Node->getBlock());714 OS << NL;715}716 717void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {718 Indent();719 PrintRawSEHExceptHandler(Node);720 OS << NL;721}722 723void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {724 Indent();725 PrintRawSEHFinallyStmt(Node);726 OS << NL;727}728 729void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {730 Indent() << "__leave;";731 if (Policy.IncludeNewlines) OS << NL;732}733 734//===----------------------------------------------------------------------===//735// OpenMP directives printing methods736//===----------------------------------------------------------------------===//737 738void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) {739 PrintStmt(Node->getLoopStmt());740}741 742void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,743 bool ForceNoStmt) {744 unsigned OpenMPVersion =745 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;746 OMPClausePrinter Printer(OS, Policy, OpenMPVersion);747 ArrayRef<OMPClause *> Clauses = S->clauses();748 for (auto *Clause : Clauses)749 if (Clause && !Clause->isImplicit()) {750 OS << ' ';751 Printer.Visit(Clause);752 }753 OS << NL;754 if (!ForceNoStmt && S->hasAssociatedStmt())755 PrintStmt(S->getRawStmt());756}757 758void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) {759 Indent() << "#pragma omp metadirective";760 PrintOMPExecutableDirective(Node);761}762 763void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {764 Indent() << "#pragma omp parallel";765 PrintOMPExecutableDirective(Node);766}767 768void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {769 Indent() << "#pragma omp simd";770 PrintOMPExecutableDirective(Node);771}772 773void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {774 Indent() << "#pragma omp tile";775 PrintOMPExecutableDirective(Node);776}777 778void StmtPrinter::VisitOMPStripeDirective(OMPStripeDirective *Node) {779 Indent() << "#pragma omp stripe";780 PrintOMPExecutableDirective(Node);781}782 783void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {784 Indent() << "#pragma omp unroll";785 PrintOMPExecutableDirective(Node);786}787 788void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) {789 Indent() << "#pragma omp reverse";790 PrintOMPExecutableDirective(Node);791}792 793void StmtPrinter::VisitOMPInterchangeDirective(OMPInterchangeDirective *Node) {794 Indent() << "#pragma omp interchange";795 PrintOMPExecutableDirective(Node);796}797 798void StmtPrinter::VisitOMPFuseDirective(OMPFuseDirective *Node) {799 Indent() << "#pragma omp fuse";800 PrintOMPExecutableDirective(Node);801}802 803void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {804 Indent() << "#pragma omp for";805 PrintOMPExecutableDirective(Node);806}807 808void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {809 Indent() << "#pragma omp for simd";810 PrintOMPExecutableDirective(Node);811}812 813void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {814 Indent() << "#pragma omp sections";815 PrintOMPExecutableDirective(Node);816}817 818void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {819 Indent() << "#pragma omp section";820 PrintOMPExecutableDirective(Node);821}822 823void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {824 Indent() << "#pragma omp scope";825 PrintOMPExecutableDirective(Node);826}827 828void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {829 Indent() << "#pragma omp single";830 PrintOMPExecutableDirective(Node);831}832 833void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {834 Indent() << "#pragma omp master";835 PrintOMPExecutableDirective(Node);836}837 838void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {839 Indent() << "#pragma omp critical";840 if (Node->getDirectiveName().getName()) {841 OS << " (";842 Node->getDirectiveName().printName(OS, Policy);843 OS << ")";844 }845 PrintOMPExecutableDirective(Node);846}847 848void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {849 Indent() << "#pragma omp parallel for";850 PrintOMPExecutableDirective(Node);851}852 853void StmtPrinter::VisitOMPParallelForSimdDirective(854 OMPParallelForSimdDirective *Node) {855 Indent() << "#pragma omp parallel for simd";856 PrintOMPExecutableDirective(Node);857}858 859void StmtPrinter::VisitOMPParallelMasterDirective(860 OMPParallelMasterDirective *Node) {861 Indent() << "#pragma omp parallel master";862 PrintOMPExecutableDirective(Node);863}864 865void StmtPrinter::VisitOMPParallelMaskedDirective(866 OMPParallelMaskedDirective *Node) {867 Indent() << "#pragma omp parallel masked";868 PrintOMPExecutableDirective(Node);869}870 871void StmtPrinter::VisitOMPParallelSectionsDirective(872 OMPParallelSectionsDirective *Node) {873 Indent() << "#pragma omp parallel sections";874 PrintOMPExecutableDirective(Node);875}876 877void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {878 Indent() << "#pragma omp task";879 PrintOMPExecutableDirective(Node);880}881 882void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {883 Indent() << "#pragma omp taskyield";884 PrintOMPExecutableDirective(Node);885}886 887void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {888 Indent() << "#pragma omp barrier";889 PrintOMPExecutableDirective(Node);890}891 892void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {893 Indent() << "#pragma omp taskwait";894 PrintOMPExecutableDirective(Node);895}896 897void StmtPrinter::VisitOMPAssumeDirective(OMPAssumeDirective *Node) {898 Indent() << "#pragma omp assume";899 PrintOMPExecutableDirective(Node);900}901 902void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {903 Indent() << "#pragma omp error";904 PrintOMPExecutableDirective(Node);905}906 907void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {908 Indent() << "#pragma omp taskgroup";909 PrintOMPExecutableDirective(Node);910}911 912void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {913 Indent() << "#pragma omp flush";914 PrintOMPExecutableDirective(Node);915}916 917void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {918 Indent() << "#pragma omp depobj";919 PrintOMPExecutableDirective(Node);920}921 922void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {923 Indent() << "#pragma omp scan";924 PrintOMPExecutableDirective(Node);925}926 927void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {928 Indent() << "#pragma omp ordered";929 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());930}931 932void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {933 Indent() << "#pragma omp atomic";934 PrintOMPExecutableDirective(Node);935}936 937void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {938 Indent() << "#pragma omp target";939 PrintOMPExecutableDirective(Node);940}941 942void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {943 Indent() << "#pragma omp target data";944 PrintOMPExecutableDirective(Node);945}946 947void StmtPrinter::VisitOMPTargetEnterDataDirective(948 OMPTargetEnterDataDirective *Node) {949 Indent() << "#pragma omp target enter data";950 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);951}952 953void StmtPrinter::VisitOMPTargetExitDataDirective(954 OMPTargetExitDataDirective *Node) {955 Indent() << "#pragma omp target exit data";956 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);957}958 959void StmtPrinter::VisitOMPTargetParallelDirective(960 OMPTargetParallelDirective *Node) {961 Indent() << "#pragma omp target parallel";962 PrintOMPExecutableDirective(Node);963}964 965void StmtPrinter::VisitOMPTargetParallelForDirective(966 OMPTargetParallelForDirective *Node) {967 Indent() << "#pragma omp target parallel for";968 PrintOMPExecutableDirective(Node);969}970 971void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {972 Indent() << "#pragma omp teams";973 PrintOMPExecutableDirective(Node);974}975 976void StmtPrinter::VisitOMPCancellationPointDirective(977 OMPCancellationPointDirective *Node) {978 unsigned OpenMPVersion =979 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;980 Indent() << "#pragma omp cancellation point "981 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);982 PrintOMPExecutableDirective(Node);983}984 985void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {986 unsigned OpenMPVersion =987 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;988 Indent() << "#pragma omp cancel "989 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);990 PrintOMPExecutableDirective(Node);991}992 993void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {994 Indent() << "#pragma omp taskloop";995 PrintOMPExecutableDirective(Node);996}997 998void StmtPrinter::VisitOMPTaskLoopSimdDirective(999 OMPTaskLoopSimdDirective *Node) {1000 Indent() << "#pragma omp taskloop simd";1001 PrintOMPExecutableDirective(Node);1002}1003 1004void StmtPrinter::VisitOMPMasterTaskLoopDirective(1005 OMPMasterTaskLoopDirective *Node) {1006 Indent() << "#pragma omp master taskloop";1007 PrintOMPExecutableDirective(Node);1008}1009 1010void StmtPrinter::VisitOMPMaskedTaskLoopDirective(1011 OMPMaskedTaskLoopDirective *Node) {1012 Indent() << "#pragma omp masked taskloop";1013 PrintOMPExecutableDirective(Node);1014}1015 1016void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(1017 OMPMasterTaskLoopSimdDirective *Node) {1018 Indent() << "#pragma omp master taskloop simd";1019 PrintOMPExecutableDirective(Node);1020}1021 1022void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(1023 OMPMaskedTaskLoopSimdDirective *Node) {1024 Indent() << "#pragma omp masked taskloop simd";1025 PrintOMPExecutableDirective(Node);1026}1027 1028void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(1029 OMPParallelMasterTaskLoopDirective *Node) {1030 Indent() << "#pragma omp parallel master taskloop";1031 PrintOMPExecutableDirective(Node);1032}1033 1034void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(1035 OMPParallelMaskedTaskLoopDirective *Node) {1036 Indent() << "#pragma omp parallel masked taskloop";1037 PrintOMPExecutableDirective(Node);1038}1039 1040void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(1041 OMPParallelMasterTaskLoopSimdDirective *Node) {1042 Indent() << "#pragma omp parallel master taskloop simd";1043 PrintOMPExecutableDirective(Node);1044}1045 1046void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(1047 OMPParallelMaskedTaskLoopSimdDirective *Node) {1048 Indent() << "#pragma omp parallel masked taskloop simd";1049 PrintOMPExecutableDirective(Node);1050}1051 1052void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {1053 Indent() << "#pragma omp distribute";1054 PrintOMPExecutableDirective(Node);1055}1056 1057void StmtPrinter::VisitOMPTargetUpdateDirective(1058 OMPTargetUpdateDirective *Node) {1059 Indent() << "#pragma omp target update";1060 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);1061}1062 1063void StmtPrinter::VisitOMPDistributeParallelForDirective(1064 OMPDistributeParallelForDirective *Node) {1065 Indent() << "#pragma omp distribute parallel for";1066 PrintOMPExecutableDirective(Node);1067}1068 1069void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(1070 OMPDistributeParallelForSimdDirective *Node) {1071 Indent() << "#pragma omp distribute parallel for simd";1072 PrintOMPExecutableDirective(Node);1073}1074 1075void StmtPrinter::VisitOMPDistributeSimdDirective(1076 OMPDistributeSimdDirective *Node) {1077 Indent() << "#pragma omp distribute simd";1078 PrintOMPExecutableDirective(Node);1079}1080 1081void StmtPrinter::VisitOMPTargetParallelForSimdDirective(1082 OMPTargetParallelForSimdDirective *Node) {1083 Indent() << "#pragma omp target parallel for simd";1084 PrintOMPExecutableDirective(Node);1085}1086 1087void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {1088 Indent() << "#pragma omp target simd";1089 PrintOMPExecutableDirective(Node);1090}1091 1092void StmtPrinter::VisitOMPTeamsDistributeDirective(1093 OMPTeamsDistributeDirective *Node) {1094 Indent() << "#pragma omp teams distribute";1095 PrintOMPExecutableDirective(Node);1096}1097 1098void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(1099 OMPTeamsDistributeSimdDirective *Node) {1100 Indent() << "#pragma omp teams distribute simd";1101 PrintOMPExecutableDirective(Node);1102}1103 1104void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(1105 OMPTeamsDistributeParallelForSimdDirective *Node) {1106 Indent() << "#pragma omp teams distribute parallel for simd";1107 PrintOMPExecutableDirective(Node);1108}1109 1110void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(1111 OMPTeamsDistributeParallelForDirective *Node) {1112 Indent() << "#pragma omp teams distribute parallel for";1113 PrintOMPExecutableDirective(Node);1114}1115 1116void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {1117 Indent() << "#pragma omp target teams";1118 PrintOMPExecutableDirective(Node);1119}1120 1121void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(1122 OMPTargetTeamsDistributeDirective *Node) {1123 Indent() << "#pragma omp target teams distribute";1124 PrintOMPExecutableDirective(Node);1125}1126 1127void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(1128 OMPTargetTeamsDistributeParallelForDirective *Node) {1129 Indent() << "#pragma omp target teams distribute parallel for";1130 PrintOMPExecutableDirective(Node);1131}1132 1133void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(1134 OMPTargetTeamsDistributeParallelForSimdDirective *Node) {1135 Indent() << "#pragma omp target teams distribute parallel for simd";1136 PrintOMPExecutableDirective(Node);1137}1138 1139void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(1140 OMPTargetTeamsDistributeSimdDirective *Node) {1141 Indent() << "#pragma omp target teams distribute simd";1142 PrintOMPExecutableDirective(Node);1143}1144 1145void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {1146 Indent() << "#pragma omp interop";1147 PrintOMPExecutableDirective(Node);1148}1149 1150void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {1151 Indent() << "#pragma omp dispatch";1152 PrintOMPExecutableDirective(Node);1153}1154 1155void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {1156 Indent() << "#pragma omp masked";1157 PrintOMPExecutableDirective(Node);1158}1159 1160void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {1161 Indent() << "#pragma omp loop";1162 PrintOMPExecutableDirective(Node);1163}1164 1165void StmtPrinter::VisitOMPTeamsGenericLoopDirective(1166 OMPTeamsGenericLoopDirective *Node) {1167 Indent() << "#pragma omp teams loop";1168 PrintOMPExecutableDirective(Node);1169}1170 1171void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(1172 OMPTargetTeamsGenericLoopDirective *Node) {1173 Indent() << "#pragma omp target teams loop";1174 PrintOMPExecutableDirective(Node);1175}1176 1177void StmtPrinter::VisitOMPParallelGenericLoopDirective(1178 OMPParallelGenericLoopDirective *Node) {1179 Indent() << "#pragma omp parallel loop";1180 PrintOMPExecutableDirective(Node);1181}1182 1183void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(1184 OMPTargetParallelGenericLoopDirective *Node) {1185 Indent() << "#pragma omp target parallel loop";1186 PrintOMPExecutableDirective(Node);1187}1188 1189//===----------------------------------------------------------------------===//1190// OpenACC construct printing methods1191//===----------------------------------------------------------------------===//1192void StmtPrinter::PrintOpenACCClauseList(OpenACCConstructStmt *S) {1193 if (!S->clauses().empty()) {1194 OS << ' ';1195 OpenACCClausePrinter Printer(OS, Policy);1196 Printer.VisitClauseList(S->clauses());1197 }1198}1199void StmtPrinter::PrintOpenACCConstruct(OpenACCConstructStmt *S) {1200 Indent() << "#pragma acc " << S->getDirectiveKind();1201 PrintOpenACCClauseList(S);1202 OS << '\n';1203}1204void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {1205 PrintOpenACCConstruct(S);1206 PrintStmt(S->getStructuredBlock());1207}1208 1209void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {1210 PrintOpenACCConstruct(S);1211 PrintStmt(S->getLoop());1212}1213 1214void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {1215 PrintOpenACCConstruct(S);1216 PrintStmt(S->getLoop());1217}1218 1219void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {1220 PrintOpenACCConstruct(S);1221 PrintStmt(S->getStructuredBlock());1222}1223void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {1224 PrintOpenACCConstruct(S);1225 PrintStmt(S->getStructuredBlock());1226}1227void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) {1228 PrintOpenACCConstruct(S);1229}1230void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {1231 PrintOpenACCConstruct(S);1232}1233void StmtPrinter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {1234 PrintOpenACCConstruct(S);1235}1236void StmtPrinter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {1237 PrintOpenACCConstruct(S);1238}1239void StmtPrinter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {1240 PrintOpenACCConstruct(S);1241}1242void StmtPrinter::VisitOpenACCUpdateConstruct(OpenACCUpdateConstruct *S) {1243 PrintOpenACCConstruct(S);1244}1245 1246void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {1247 Indent() << "#pragma acc wait";1248 if (!S->getLParenLoc().isInvalid()) {1249 OS << "(";1250 if (S->hasDevNumExpr()) {1251 OS << "devnum: ";1252 S->getDevNumExpr()->printPretty(OS, nullptr, Policy);1253 OS << " : ";1254 }1255 1256 if (S->hasQueuesTag())1257 OS << "queues: ";1258 1259 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](const Expr *E) {1260 E->printPretty(OS, nullptr, Policy);1261 });1262 1263 OS << ")";1264 }1265 1266 PrintOpenACCClauseList(S);1267 OS << '\n';1268}1269 1270void StmtPrinter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) {1271 Indent() << "#pragma acc atomic";1272 1273 if (S->getAtomicKind() != OpenACCAtomicKind::None)1274 OS << " " << S->getAtomicKind();1275 1276 PrintOpenACCClauseList(S);1277 OS << '\n';1278 PrintStmt(S->getAssociatedStmt());1279}1280 1281void StmtPrinter::VisitOpenACCCacheConstruct(OpenACCCacheConstruct *S) {1282 Indent() << "#pragma acc cache(";1283 if (S->hasReadOnly())1284 OS << "readonly: ";1285 1286 llvm::interleaveComma(S->getVarList(), OS, [&](const Expr *E) {1287 E->printPretty(OS, nullptr, Policy);1288 });1289 1290 OS << ")\n";1291}1292 1293//===----------------------------------------------------------------------===//1294// Expr printing methods.1295//===----------------------------------------------------------------------===//1296 1297void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {1298 OS << Node->getBuiltinStr() << "()";1299}1300 1301void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {1302 // FIXME: Embed parameters are not reflected in the AST, so there is no way to1303 // print them yet.1304 OS << "#embed ";1305 OS << Node->getFileName();1306 OS << NL;1307}1308 1309void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {1310 PrintExpr(Node->getSubExpr());1311}1312 1313void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {1314 ValueDecl *VD = Node->getDecl();1315 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(VD)) {1316 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);1317 return;1318 }1319 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(VD)) {1320 TPOD->printAsExpr(OS, Policy);1321 return;1322 }1323 Node->getQualifier().print(OS, Policy);1324 if (Node->hasTemplateKeyword())1325 OS << "template ";1326 1327 bool ForceAnonymous =1328 Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm;1329 DeclarationNameInfo NameInfo = Node->getNameInfo();1330 if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();1331 !ForceAnonymous &&1332 (ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier)) {1333 if (Policy.CleanUglifiedParameters &&1334 isa<ParmVarDecl, NonTypeTemplateParmDecl>(VD) && ID)1335 OS << ID->deuglifiedName();1336 else1337 NameInfo.printName(OS, Policy);1338 } else {1339 switch (VD->getKind()) {1340 case Decl::NonTypeTemplateParm: {1341 auto *TD = cast<NonTypeTemplateParmDecl>(VD);1342 OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << "";1343 break;1344 }1345 case Decl::ParmVar: {1346 auto *PD = cast<ParmVarDecl>(VD);1347 OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'1348 << PD->getFunctionScopeIndex();1349 break;1350 }1351 case Decl::Decomposition:1352 OS << "decomposition";1353 for (const auto &I : cast<DecompositionDecl>(VD)->bindings())1354 OS << '-' << I->getName();1355 break;1356 default:1357 OS << "unhandled-anonymous-" << VD->getDeclKindName();1358 break;1359 }1360 }1361 if (Node->hasExplicitTemplateArgs()) {1362 const TemplateParameterList *TPL = nullptr;1363 if (!Node->hadMultipleCandidates())1364 if (auto *TD = dyn_cast<TemplateDecl>(VD))1365 TPL = TD->getTemplateParameters();1366 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);1367 }1368}1369 1370void StmtPrinter::VisitDependentScopeDeclRefExpr(1371 DependentScopeDeclRefExpr *Node) {1372 Node->getQualifier().print(OS, Policy);1373 if (Node->hasTemplateKeyword())1374 OS << "template ";1375 OS << Node->getNameInfo();1376 if (Node->hasExplicitTemplateArgs())1377 printTemplateArgumentList(OS, Node->template_arguments(), Policy);1378}1379 1380void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {1381 Node->getQualifier().print(OS, Policy);1382 if (Node->hasTemplateKeyword())1383 OS << "template ";1384 OS << Node->getNameInfo();1385 if (Node->hasExplicitTemplateArgs())1386 printTemplateArgumentList(OS, Node->template_arguments(), Policy);1387}1388 1389static bool isImplicitSelf(const Expr *E) {1390 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {1391 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {1392 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&1393 DRE->getBeginLoc().isInvalid())1394 return true;1395 }1396 }1397 return false;1398}1399 1400void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {1401 if (Node->getBase()) {1402 if (!Policy.SuppressImplicitBase ||1403 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {1404 PrintExpr(Node->getBase());1405 OS << (Node->isArrow() ? "->" : ".");1406 }1407 }1408 OS << *Node->getDecl();1409}1410 1411void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {1412 if (Node->isSuperReceiver())1413 OS << "super.";1414 else if (Node->isObjectReceiver() && Node->getBase()) {1415 PrintExpr(Node->getBase());1416 OS << ".";1417 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {1418 OS << Node->getClassReceiver()->getName() << ".";1419 }1420 1421 if (Node->isImplicitProperty()) {1422 if (const auto *Getter = Node->getImplicitPropertyGetter())1423 Getter->getSelector().print(OS);1424 else1425 OS << SelectorTable::getPropertyNameFromSetterSelector(1426 Node->getImplicitPropertySetter()->getSelector());1427 } else1428 OS << Node->getExplicitProperty()->getName();1429}1430 1431void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {1432 PrintExpr(Node->getBaseExpr());1433 OS << "[";1434 PrintExpr(Node->getKeyExpr());1435 OS << "]";1436}1437 1438void StmtPrinter::VisitSYCLUniqueStableNameExpr(1439 SYCLUniqueStableNameExpr *Node) {1440 OS << "__builtin_sycl_unique_stable_name(";1441 Node->getTypeSourceInfo()->getType().print(OS, Policy);1442 OS << ")";1443}1444 1445void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {1446 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());1447}1448 1449void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {1450 OS << '*';1451}1452 1453void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {1454 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);1455}1456 1457/// Prints the given expression using the original source text. Returns true on1458/// success, false otherwise.1459static bool printExprAsWritten(raw_ostream &OS, Expr *E,1460 const ASTContext *Context) {1461 if (!Context)1462 return false;1463 bool Invalid = false;1464 StringRef Source = Lexer::getSourceText(1465 CharSourceRange::getTokenRange(E->getSourceRange()),1466 Context->getSourceManager(), Context->getLangOpts(), &Invalid);1467 if (!Invalid) {1468 OS << Source;1469 return true;1470 }1471 return false;1472}1473 1474void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {1475 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))1476 return;1477 bool isSigned = Node->getType()->isSignedIntegerType();1478 OS << toString(Node->getValue(), 10, isSigned);1479 1480 if (isa<BitIntType>(Node->getType())) {1481 OS << (isSigned ? "wb" : "uwb");1482 return;1483 }1484 1485 // Emit suffixes. Integer literals are always a builtin integer type.1486 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {1487 default: llvm_unreachable("Unexpected type for integer literal!");1488 case BuiltinType::Char_S:1489 case BuiltinType::Char_U: OS << "i8"; break;1490 case BuiltinType::UChar: OS << "Ui8"; break;1491 case BuiltinType::SChar: OS << "i8"; break;1492 case BuiltinType::Short: OS << "i16"; break;1493 case BuiltinType::UShort: OS << "Ui16"; break;1494 case BuiltinType::Int: break; // no suffix.1495 case BuiltinType::UInt: OS << 'U'; break;1496 case BuiltinType::Long: OS << 'L'; break;1497 case BuiltinType::ULong: OS << "UL"; break;1498 case BuiltinType::LongLong: OS << "LL"; break;1499 case BuiltinType::ULongLong: OS << "ULL"; break;1500 case BuiltinType::Int128:1501 break; // no suffix.1502 case BuiltinType::UInt128:1503 break; // no suffix.1504 case BuiltinType::WChar_S:1505 case BuiltinType::WChar_U:1506 break; // no suffix1507 }1508}1509 1510void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {1511 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))1512 return;1513 OS << Node->getValueAsString(/*Radix=*/10);1514 1515 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {1516 default: llvm_unreachable("Unexpected type for fixed point literal!");1517 case BuiltinType::ShortFract: OS << "hr"; break;1518 case BuiltinType::ShortAccum: OS << "hk"; break;1519 case BuiltinType::UShortFract: OS << "uhr"; break;1520 case BuiltinType::UShortAccum: OS << "uhk"; break;1521 case BuiltinType::Fract: OS << "r"; break;1522 case BuiltinType::Accum: OS << "k"; break;1523 case BuiltinType::UFract: OS << "ur"; break;1524 case BuiltinType::UAccum: OS << "uk"; break;1525 case BuiltinType::LongFract: OS << "lr"; break;1526 case BuiltinType::LongAccum: OS << "lk"; break;1527 case BuiltinType::ULongFract: OS << "ulr"; break;1528 case BuiltinType::ULongAccum: OS << "ulk"; break;1529 }1530}1531 1532static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,1533 bool PrintSuffix) {1534 SmallString<16> Str;1535 Node->getValue().toString(Str);1536 OS << Str;1537 if (Str.find_first_not_of("-0123456789") == StringRef::npos)1538 OS << '.'; // Trailing dot in order to separate from ints.1539 1540 if (!PrintSuffix)1541 return;1542 1543 // Emit suffixes. Float literals are always a builtin float type.1544 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {1545 default: llvm_unreachable("Unexpected type for float literal!");1546 case BuiltinType::Half: break; // FIXME: suffix?1547 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal1548 case BuiltinType::Double: break; // no suffix.1549 case BuiltinType::Float16: OS << "F16"; break;1550 case BuiltinType::Float: OS << 'F'; break;1551 case BuiltinType::LongDouble: OS << 'L'; break;1552 case BuiltinType::Float128: OS << 'Q'; break;1553 }1554}1555 1556void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {1557 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))1558 return;1559 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);1560}1561 1562void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {1563 PrintExpr(Node->getSubExpr());1564 OS << "i";1565}1566 1567void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {1568 Str->outputString(OS);1569}1570 1571void StmtPrinter::VisitParenExpr(ParenExpr *Node) {1572 OS << "(";1573 PrintExpr(Node->getSubExpr());1574 OS << ")";1575}1576 1577void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {1578 if (!Node->isPostfix()) {1579 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());1580 1581 // Print a space if this is an "identifier operator" like __real, or if1582 // it might be concatenated incorrectly like '+'.1583 switch (Node->getOpcode()) {1584 default: break;1585 case UO_Real:1586 case UO_Imag:1587 case UO_Extension:1588 OS << ' ';1589 break;1590 case UO_Plus:1591 case UO_Minus:1592 if (isa<UnaryOperator>(Node->getSubExpr()))1593 OS << ' ';1594 break;1595 }1596 }1597 PrintExpr(Node->getSubExpr());1598 1599 if (Node->isPostfix())1600 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());1601}1602 1603void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {1604 OS << "__builtin_offsetof(";1605 Node->getTypeSourceInfo()->getType().print(OS, Policy);1606 OS << ", ";1607 bool PrintedSomething = false;1608 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {1609 OffsetOfNode ON = Node->getComponent(i);1610 if (ON.getKind() == OffsetOfNode::Array) {1611 // Array node1612 OS << "[";1613 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));1614 OS << "]";1615 PrintedSomething = true;1616 continue;1617 }1618 1619 // Skip implicit base indirections.1620 if (ON.getKind() == OffsetOfNode::Base)1621 continue;1622 1623 // Field or identifier node.1624 const IdentifierInfo *Id = ON.getFieldName();1625 if (!Id)1626 continue;1627 1628 if (PrintedSomething)1629 OS << ".";1630 else1631 PrintedSomething = true;1632 OS << Id->getName();1633 }1634 OS << ")";1635}1636 1637void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(1638 UnaryExprOrTypeTraitExpr *Node) {1639 const char *Spelling = getTraitSpelling(Node->getKind());1640 if (Node->getKind() == UETT_AlignOf) {1641 if (Policy.Alignof)1642 Spelling = "alignof";1643 else if (Policy.UnderscoreAlignof)1644 Spelling = "_Alignof";1645 else1646 Spelling = "__alignof";1647 }1648 1649 OS << Spelling;1650 1651 if (Node->isArgumentType()) {1652 OS << '(';1653 Node->getArgumentType().print(OS, Policy);1654 OS << ')';1655 } else {1656 OS << " ";1657 PrintExpr(Node->getArgumentExpr());1658 }1659}1660 1661void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {1662 OS << "_Generic(";1663 if (Node->isExprPredicate())1664 PrintExpr(Node->getControllingExpr());1665 else1666 Node->getControllingType()->getType().print(OS, Policy);1667 1668 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {1669 OS << ", ";1670 QualType T = Assoc.getType();1671 if (T.isNull())1672 OS << "default";1673 else1674 T.print(OS, Policy);1675 OS << ": ";1676 PrintExpr(Assoc.getAssociationExpr());1677 }1678 OS << ")";1679}1680 1681void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {1682 PrintExpr(Node->getLHS());1683 OS << "[";1684 PrintExpr(Node->getRHS());1685 OS << "]";1686}1687 1688void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {1689 PrintExpr(Node->getBase());1690 OS << "[";1691 PrintExpr(Node->getRowIdx());1692 OS << "]";1693 OS << "[";1694 PrintExpr(Node->getColumnIdx());1695 OS << "]";1696}1697 1698void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {1699 PrintExpr(Node->getBase());1700 OS << "[";1701 if (Node->getLowerBound())1702 PrintExpr(Node->getLowerBound());1703 if (Node->getColonLocFirst().isValid()) {1704 OS << ":";1705 if (Node->getLength())1706 PrintExpr(Node->getLength());1707 }1708 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {1709 OS << ":";1710 if (Node->getStride())1711 PrintExpr(Node->getStride());1712 }1713 OS << "]";1714}1715 1716void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {1717 OS << "(";1718 for (Expr *E : Node->getDimensions()) {1719 OS << "[";1720 PrintExpr(E);1721 OS << "]";1722 }1723 OS << ")";1724 PrintExpr(Node->getBase());1725}1726 1727void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {1728 OS << "iterator(";1729 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {1730 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));1731 VD->getType().print(OS, Policy);1732 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);1733 OS << " " << VD->getName() << " = ";1734 PrintExpr(Range.Begin);1735 OS << ":";1736 PrintExpr(Range.End);1737 if (Range.Step) {1738 OS << ":";1739 PrintExpr(Range.Step);1740 }1741 if (I < E - 1)1742 OS << ", ";1743 }1744 OS << ")";1745}1746 1747void StmtPrinter::PrintCallArgs(CallExpr *Call) {1748 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {1749 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {1750 // Don't print any defaulted arguments1751 break;1752 }1753 1754 if (i) OS << ", ";1755 PrintExpr(Call->getArg(i));1756 }1757}1758 1759void StmtPrinter::VisitCallExpr(CallExpr *Call) {1760 PrintExpr(Call->getCallee());1761 OS << "(";1762 PrintCallArgs(Call);1763 OS << ")";1764}1765 1766static bool isImplicitThis(const Expr *E) {1767 if (const auto *TE = dyn_cast<CXXThisExpr>(E))1768 return TE->isImplicit();1769 return false;1770}1771 1772void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {1773 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {1774 PrintExpr(Node->getBase());1775 1776 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());1777 FieldDecl *ParentDecl =1778 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())1779 : nullptr;1780 1781 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())1782 OS << (Node->isArrow() ? "->" : ".");1783 }1784 1785 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))1786 if (FD->isAnonymousStructOrUnion())1787 return;1788 1789 Node->getQualifier().print(OS, Policy);1790 if (Node->hasTemplateKeyword())1791 OS << "template ";1792 OS << Node->getMemberNameInfo();1793 const TemplateParameterList *TPL = nullptr;1794 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {1795 if (!Node->hadMultipleCandidates())1796 if (auto *FTD = FD->getPrimaryTemplate())1797 TPL = FTD->getTemplateParameters();1798 } else if (auto *VTSD =1799 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))1800 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();1801 if (Node->hasExplicitTemplateArgs())1802 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);1803}1804 1805void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {1806 PrintExpr(Node->getBase());1807 OS << (Node->isArrow() ? "->isa" : ".isa");1808}1809 1810void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {1811 PrintExpr(Node->getBase());1812 OS << ".";1813 OS << Node->getAccessor().getName();1814}1815 1816void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {1817 OS << '(';1818 Node->getTypeAsWritten().print(OS, Policy);1819 OS << ')';1820 PrintExpr(Node->getSubExpr());1821}1822 1823void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {1824 OS << '(';1825 Node->getType().print(OS, Policy);1826 OS << ')';1827 PrintExpr(Node->getInitializer());1828}1829 1830void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {1831 // No need to print anything, simply forward to the subexpression.1832 PrintExpr(Node->getSubExpr());1833}1834 1835void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {1836 PrintExpr(Node->getLHS());1837 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";1838 PrintExpr(Node->getRHS());1839}1840 1841void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {1842 PrintExpr(Node->getLHS());1843 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";1844 PrintExpr(Node->getRHS());1845}1846 1847void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {1848 PrintExpr(Node->getCond());1849 OS << " ? ";1850 PrintExpr(Node->getLHS());1851 OS << " : ";1852 PrintExpr(Node->getRHS());1853}1854 1855// GNU extensions.1856 1857void1858StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {1859 PrintExpr(Node->getCommon());1860 OS << " ?: ";1861 PrintExpr(Node->getFalseExpr());1862}1863 1864void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {1865 OS << "&&" << Node->getLabel()->getName();1866}1867 1868void StmtPrinter::VisitStmtExpr(StmtExpr *E) {1869 OS << "(";1870 PrintRawCompoundStmt(E->getSubStmt());1871 OS << ")";1872}1873 1874void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {1875 OS << "__builtin_choose_expr(";1876 PrintExpr(Node->getCond());1877 OS << ", ";1878 PrintExpr(Node->getLHS());1879 OS << ", ";1880 PrintExpr(Node->getRHS());1881 OS << ")";1882}1883 1884void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {1885 OS << "__null";1886}1887 1888void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {1889 OS << "__builtin_shufflevector(";1890 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {1891 if (i) OS << ", ";1892 PrintExpr(Node->getExpr(i));1893 }1894 OS << ")";1895}1896 1897void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {1898 OS << "__builtin_convertvector(";1899 PrintExpr(Node->getSrcExpr());1900 OS << ", ";1901 Node->getType().print(OS, Policy);1902 OS << ")";1903}1904 1905void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {1906 if (Node->getSyntacticForm()) {1907 Visit(Node->getSyntacticForm());1908 return;1909 }1910 1911 OS << "{";1912 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {1913 if (i) OS << ", ";1914 if (Node->getInit(i))1915 PrintExpr(Node->getInit(i));1916 else1917 OS << "{}";1918 }1919 OS << "}";1920}1921 1922void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {1923 // There's no way to express this expression in any of our supported1924 // languages, so just emit something terse and (hopefully) clear.1925 OS << "{";1926 PrintExpr(Node->getSubExpr());1927 OS << "}";1928}1929 1930void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {1931 OS << "*";1932}1933 1934void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {1935 OS << "(";1936 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {1937 if (i) OS << ", ";1938 PrintExpr(Node->getExpr(i));1939 }1940 OS << ")";1941}1942 1943void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {1944 bool NeedsEquals = true;1945 for (const DesignatedInitExpr::Designator &D : Node->designators()) {1946 if (D.isFieldDesignator()) {1947 if (D.getDotLoc().isInvalid()) {1948 if (const IdentifierInfo *II = D.getFieldName()) {1949 OS << II->getName() << ":";1950 NeedsEquals = false;1951 }1952 } else {1953 OS << "." << D.getFieldName()->getName();1954 }1955 } else {1956 OS << "[";1957 if (D.isArrayDesignator()) {1958 PrintExpr(Node->getArrayIndex(D));1959 } else {1960 PrintExpr(Node->getArrayRangeStart(D));1961 OS << " ... ";1962 PrintExpr(Node->getArrayRangeEnd(D));1963 }1964 OS << "]";1965 }1966 }1967 1968 if (NeedsEquals)1969 OS << " = ";1970 else1971 OS << " ";1972 PrintExpr(Node->getInit());1973}1974 1975void StmtPrinter::VisitDesignatedInitUpdateExpr(1976 DesignatedInitUpdateExpr *Node) {1977 OS << "{";1978 OS << "/*base*/";1979 PrintExpr(Node->getBase());1980 OS << ", ";1981 1982 OS << "/*updater*/";1983 PrintExpr(Node->getUpdater());1984 OS << "}";1985}1986 1987void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {1988 OS << "/*no init*/";1989}1990 1991void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {1992 if (Node->getType()->getAsCXXRecordDecl()) {1993 OS << "/*implicit*/";1994 Node->getType().print(OS, Policy);1995 OS << "()";1996 } else {1997 OS << "/*implicit*/(";1998 Node->getType().print(OS, Policy);1999 OS << ')';2000 if (Node->getType()->isRecordType())2001 OS << "{}";2002 else2003 OS << 0;2004 }2005}2006 2007void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {2008 OS << "__builtin_va_arg(";2009 PrintExpr(Node->getSubExpr());2010 OS << ", ";2011 Node->getType().print(OS, Policy);2012 OS << ")";2013}2014 2015void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {2016 PrintExpr(Node->getSyntacticForm());2017}2018 2019void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {2020 const char *Name = nullptr;2021 switch (Node->getOp()) {2022#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \2023 case AtomicExpr::AO ## ID: \2024 Name = #ID "("; \2025 break;2026#include "clang/Basic/Builtins.inc"2027 }2028 OS << Name;2029 2030 // AtomicExpr stores its subexpressions in a permuted order.2031 PrintExpr(Node->getPtr());2032 if (Node->hasVal1Operand()) {2033 OS << ", ";2034 PrintExpr(Node->getVal1());2035 }2036 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||2037 Node->isCmpXChg()) {2038 OS << ", ";2039 PrintExpr(Node->getVal2());2040 }2041 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||2042 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {2043 OS << ", ";2044 PrintExpr(Node->getWeak());2045 }2046 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&2047 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {2048 OS << ", ";2049 PrintExpr(Node->getOrder());2050 }2051 if (Node->isCmpXChg()) {2052 OS << ", ";2053 PrintExpr(Node->getOrderFail());2054 }2055 OS << ")";2056}2057 2058// C++2059void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {2060 OverloadedOperatorKind Kind = Node->getOperator();2061 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {2062 if (Node->getNumArgs() == 1) {2063 OS << getOperatorSpelling(Kind) << ' ';2064 PrintExpr(Node->getArg(0));2065 } else {2066 PrintExpr(Node->getArg(0));2067 OS << ' ' << getOperatorSpelling(Kind);2068 }2069 } else if (Kind == OO_Arrow) {2070 PrintExpr(Node->getArg(0));2071 } else if (Kind == OO_Call || Kind == OO_Subscript) {2072 PrintExpr(Node->getArg(0));2073 OS << (Kind == OO_Call ? '(' : '[');2074 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {2075 if (ArgIdx > 1)2076 OS << ", ";2077 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))2078 PrintExpr(Node->getArg(ArgIdx));2079 }2080 OS << (Kind == OO_Call ? ')' : ']');2081 } else if (Node->getNumArgs() == 1) {2082 OS << getOperatorSpelling(Kind) << ' ';2083 PrintExpr(Node->getArg(0));2084 } else if (Node->getNumArgs() == 2) {2085 PrintExpr(Node->getArg(0));2086 OS << ' ' << getOperatorSpelling(Kind) << ' ';2087 PrintExpr(Node->getArg(1));2088 } else {2089 llvm_unreachable("unknown overloaded operator");2090 }2091}2092 2093void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {2094 // If we have a conversion operator call only print the argument.2095 CXXMethodDecl *MD = Node->getMethodDecl();2096 if (isa_and_nonnull<CXXConversionDecl>(MD)) {2097 PrintExpr(Node->getImplicitObjectArgument());2098 return;2099 }2100 VisitCallExpr(cast<CallExpr>(Node));2101}2102 2103void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {2104 PrintExpr(Node->getCallee());2105 OS << "<<<";2106 PrintCallArgs(Node->getConfig());2107 OS << ">>>(";2108 PrintCallArgs(Node);2109 OS << ")";2110}2111 2112void StmtPrinter::VisitCXXRewrittenBinaryOperator(2113 CXXRewrittenBinaryOperator *Node) {2114 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =2115 Node->getDecomposedForm();2116 PrintExpr(const_cast<Expr*>(Decomposed.LHS));2117 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';2118 PrintExpr(const_cast<Expr*>(Decomposed.RHS));2119}2120 2121void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {2122 OS << Node->getCastName() << '<';2123 Node->getTypeAsWritten().print(OS, Policy);2124 OS << ">(";2125 PrintExpr(Node->getSubExpr());2126 OS << ")";2127}2128 2129void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {2130 VisitCXXNamedCastExpr(Node);2131}2132 2133void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {2134 VisitCXXNamedCastExpr(Node);2135}2136 2137void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {2138 VisitCXXNamedCastExpr(Node);2139}2140 2141void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {2142 VisitCXXNamedCastExpr(Node);2143}2144 2145void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {2146 OS << "__builtin_bit_cast(";2147 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);2148 OS << ", ";2149 PrintExpr(Node->getSubExpr());2150 OS << ")";2151}2152 2153void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {2154 VisitCXXNamedCastExpr(Node);2155}2156 2157void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {2158 OS << "typeid(";2159 if (Node->isTypeOperand()) {2160 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);2161 } else {2162 PrintExpr(Node->getExprOperand());2163 }2164 OS << ")";2165}2166 2167void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {2168 OS << "__uuidof(";2169 if (Node->isTypeOperand()) {2170 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);2171 } else {2172 PrintExpr(Node->getExprOperand());2173 }2174 OS << ")";2175}2176 2177void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {2178 PrintExpr(Node->getBaseExpr());2179 if (Node->isArrow())2180 OS << "->";2181 else2182 OS << ".";2183 Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);2184 OS << Node->getPropertyDecl()->getDeclName();2185}2186 2187void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {2188 PrintExpr(Node->getBase());2189 OS << "[";2190 PrintExpr(Node->getIdx());2191 OS << "]";2192}2193 2194void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {2195 switch (Node->getLiteralOperatorKind()) {2196 case UserDefinedLiteral::LOK_Raw:2197 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();2198 break;2199 case UserDefinedLiteral::LOK_Template: {2200 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());2201 const TemplateArgumentList *Args =2202 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();2203 assert(Args);2204 2205 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {2206 const TemplateParameterList *TPL = nullptr;2207 if (!DRE->hadMultipleCandidates())2208 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))2209 TPL = TD->getTemplateParameters();2210 OS << "operator\"\"" << Node->getUDSuffix()->getName();2211 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);2212 OS << "()";2213 return;2214 }2215 2216 const TemplateArgument &Pack = Args->get(0);2217 for (const auto &P : Pack.pack_elements()) {2218 char C = (char)P.getAsIntegral().getZExtValue();2219 OS << C;2220 }2221 break;2222 }2223 case UserDefinedLiteral::LOK_Integer: {2224 // Print integer literal without suffix.2225 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());2226 OS << toString(Int->getValue(), 10, /*isSigned*/false);2227 break;2228 }2229 case UserDefinedLiteral::LOK_Floating: {2230 // Print floating literal without suffix.2231 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());2232 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);2233 break;2234 }2235 case UserDefinedLiteral::LOK_String:2236 case UserDefinedLiteral::LOK_Character:2237 PrintExpr(Node->getCookedLiteral());2238 break;2239 }2240 OS << Node->getUDSuffix()->getName();2241}2242 2243void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {2244 OS << (Node->getValue() ? "true" : "false");2245}2246 2247void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {2248 OS << "nullptr";2249}2250 2251void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {2252 OS << "this";2253}2254 2255void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {2256 if (!Node->getSubExpr())2257 OS << "throw";2258 else {2259 OS << "throw ";2260 PrintExpr(Node->getSubExpr());2261 }2262}2263 2264void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {2265 // Nothing to print: we picked up the default argument.2266}2267 2268void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {2269 // Nothing to print: we picked up the default initializer.2270}2271 2272void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {2273 auto TargetType = Node->getType();2274 auto *Auto = TargetType->getContainedDeducedType();2275 bool Bare = Auto && Auto->isDeduced();2276 2277 // Parenthesize deduced casts.2278 if (Bare)2279 OS << '(';2280 TargetType.print(OS, Policy);2281 if (Bare)2282 OS << ')';2283 2284 // No extra braces surrounding the inner construct.2285 if (!Node->isListInitialization())2286 OS << '(';2287 PrintExpr(Node->getSubExpr());2288 if (!Node->isListInitialization())2289 OS << ')';2290}2291 2292void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {2293 PrintExpr(Node->getSubExpr());2294}2295 2296void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {2297 Node->getType().print(OS, Policy);2298 if (Node->isStdInitListInitialization())2299 /* Nothing to do; braces are part of creating the std::initializer_list. */;2300 else if (Node->isListInitialization())2301 OS << "{";2302 else2303 OS << "(";2304 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),2305 ArgEnd = Node->arg_end();2306 Arg != ArgEnd; ++Arg) {2307 if ((*Arg)->isDefaultArgument())2308 break;2309 if (Arg != Node->arg_begin())2310 OS << ", ";2311 PrintExpr(*Arg);2312 }2313 if (Node->isStdInitListInitialization())2314 /* See above. */;2315 else if (Node->isListInitialization())2316 OS << "}";2317 else2318 OS << ")";2319}2320 2321void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {2322 OS << '[';2323 bool NeedComma = false;2324 switch (Node->getCaptureDefault()) {2325 case LCD_None:2326 break;2327 2328 case LCD_ByCopy:2329 OS << '=';2330 NeedComma = true;2331 break;2332 2333 case LCD_ByRef:2334 OS << '&';2335 NeedComma = true;2336 break;2337 }2338 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),2339 CEnd = Node->explicit_capture_end();2340 C != CEnd;2341 ++C) {2342 if (C->capturesVLAType())2343 continue;2344 2345 if (NeedComma)2346 OS << ", ";2347 NeedComma = true;2348 2349 switch (C->getCaptureKind()) {2350 case LCK_This:2351 OS << "this";2352 break;2353 2354 case LCK_StarThis:2355 OS << "*this";2356 break;2357 2358 case LCK_ByRef:2359 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))2360 OS << '&';2361 OS << C->getCapturedVar()->getName();2362 break;2363 2364 case LCK_ByCopy:2365 OS << C->getCapturedVar()->getName();2366 break;2367 2368 case LCK_VLAType:2369 llvm_unreachable("VLA type in explicit captures.");2370 }2371 2372 if (C->isPackExpansion())2373 OS << "...";2374 2375 if (Node->isInitCapture(C)) {2376 // Init captures are always VarDecl.2377 auto *D = cast<VarDecl>(C->getCapturedVar());2378 2379 llvm::StringRef Pre;2380 llvm::StringRef Post;2381 if (D->getInitStyle() == VarDecl::CallInit &&2382 !isa<ParenListExpr>(D->getInit())) {2383 Pre = "(";2384 Post = ")";2385 } else if (D->getInitStyle() == VarDecl::CInit) {2386 Pre = " = ";2387 }2388 2389 OS << Pre;2390 PrintExpr(D->getInit());2391 OS << Post;2392 }2393 }2394 OS << ']';2395 2396 if (!Node->getExplicitTemplateParameters().empty()) {2397 Node->getTemplateParameterList()->print(2398 OS, Node->getLambdaClass()->getASTContext(),2399 /*OmitTemplateKW*/true);2400 }2401 2402 if (Node->hasExplicitParameters()) {2403 OS << '(';2404 CXXMethodDecl *Method = Node->getCallOperator();2405 NeedComma = false;2406 for (const auto *P : Method->parameters()) {2407 if (NeedComma) {2408 OS << ", ";2409 } else {2410 NeedComma = true;2411 }2412 std::string ParamStr =2413 (Policy.CleanUglifiedParameters && P->getIdentifier())2414 ? P->getIdentifier()->deuglifiedName().str()2415 : P->getNameAsString();2416 P->getOriginalType().print(OS, Policy, ParamStr);2417 }2418 if (Method->isVariadic()) {2419 if (NeedComma)2420 OS << ", ";2421 OS << "...";2422 }2423 OS << ')';2424 2425 if (Node->isMutable())2426 OS << " mutable";2427 2428 auto *Proto = Method->getType()->castAs<FunctionProtoType>();2429 Proto->printExceptionSpecification(OS, Policy);2430 2431 // FIXME: Attributes2432 2433 // Print the trailing return type if it was specified in the source.2434 if (Node->hasExplicitResultType()) {2435 OS << " -> ";2436 Proto->getReturnType().print(OS, Policy);2437 }2438 }2439 2440 // Print the body.2441 OS << ' ';2442 if (Policy.TerseOutput)2443 OS << "{}";2444 else2445 PrintRawCompoundStmt(Node->getCompoundStmtBody());2446}2447 2448void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {2449 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())2450 TSInfo->getType().print(OS, Policy);2451 else2452 Node->getType().print(OS, Policy);2453 OS << "()";2454}2455 2456void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {2457 if (E->isGlobalNew())2458 OS << "::";2459 OS << "new ";2460 unsigned NumPlace = E->getNumPlacementArgs();2461 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {2462 OS << "(";2463 PrintExpr(E->getPlacementArg(0));2464 for (unsigned i = 1; i < NumPlace; ++i) {2465 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))2466 break;2467 OS << ", ";2468 PrintExpr(E->getPlacementArg(i));2469 }2470 OS << ") ";2471 }2472 if (E->isParenTypeId())2473 OS << "(";2474 std::string TypeS;2475 if (E->isArray()) {2476 llvm::raw_string_ostream s(TypeS);2477 s << '[';2478 if (std::optional<Expr *> Size = E->getArraySize())2479 (*Size)->printPretty(s, Helper, Policy);2480 s << ']';2481 }2482 E->getAllocatedType().print(OS, Policy, TypeS);2483 if (E->isParenTypeId())2484 OS << ")";2485 2486 CXXNewInitializationStyle InitStyle = E->getInitializationStyle();2487 if (InitStyle != CXXNewInitializationStyle::None) {2488 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&2489 !isa<ParenListExpr>(E->getInitializer());2490 if (Bare)2491 OS << "(";2492 PrintExpr(E->getInitializer());2493 if (Bare)2494 OS << ")";2495 }2496}2497 2498void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {2499 if (E->isGlobalDelete())2500 OS << "::";2501 OS << "delete ";2502 if (E->isArrayForm())2503 OS << "[] ";2504 PrintExpr(E->getArgument());2505}2506 2507void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {2508 PrintExpr(E->getBase());2509 if (E->isArrow())2510 OS << "->";2511 else2512 OS << '.';2513 E->getQualifier().print(OS, Policy);2514 OS << "~";2515 2516 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())2517 OS << II->getName();2518 else2519 E->getDestroyedType().print(OS, Policy);2520}2521 2522void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {2523 if (E->isListInitialization() && !E->isStdInitListInitialization())2524 OS << "{";2525 2526 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {2527 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {2528 // Don't print any defaulted arguments2529 break;2530 }2531 2532 if (i) OS << ", ";2533 PrintExpr(E->getArg(i));2534 }2535 2536 if (E->isListInitialization() && !E->isStdInitListInitialization())2537 OS << "}";2538}2539 2540void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {2541 // Parens are printed by the surrounding context.2542 OS << "<forwarded>";2543}2544 2545void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {2546 PrintExpr(E->getSubExpr());2547}2548 2549void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {2550 // Just forward to the subexpression.2551 PrintExpr(E->getSubExpr());2552}2553 2554void StmtPrinter::VisitCXXUnresolvedConstructExpr(2555 CXXUnresolvedConstructExpr *Node) {2556 Node->getTypeAsWritten().print(OS, Policy);2557 if (!Node->isListInitialization())2558 OS << '(';2559 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;2560 ++Arg) {2561 if (Arg != Node->arg_begin())2562 OS << ", ";2563 PrintExpr(*Arg);2564 }2565 if (!Node->isListInitialization())2566 OS << ')';2567}2568 2569void StmtPrinter::VisitCXXDependentScopeMemberExpr(2570 CXXDependentScopeMemberExpr *Node) {2571 if (!Node->isImplicitAccess()) {2572 PrintExpr(Node->getBase());2573 OS << (Node->isArrow() ? "->" : ".");2574 }2575 Node->getQualifier().print(OS, Policy);2576 if (Node->hasTemplateKeyword())2577 OS << "template ";2578 OS << Node->getMemberNameInfo();2579 if (Node->hasExplicitTemplateArgs())2580 printTemplateArgumentList(OS, Node->template_arguments(), Policy);2581}2582 2583void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {2584 if (!Node->isImplicitAccess()) {2585 PrintExpr(Node->getBase());2586 OS << (Node->isArrow() ? "->" : ".");2587 }2588 Node->getQualifier().print(OS, Policy);2589 if (Node->hasTemplateKeyword())2590 OS << "template ";2591 OS << Node->getMemberNameInfo();2592 if (Node->hasExplicitTemplateArgs())2593 printTemplateArgumentList(OS, Node->template_arguments(), Policy);2594}2595 2596void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {2597 OS << getTraitSpelling(E->getTrait()) << "(";2598 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {2599 if (I > 0)2600 OS << ", ";2601 E->getArg(I)->getType().print(OS, Policy);2602 }2603 OS << ")";2604}2605 2606void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {2607 OS << getTraitSpelling(E->getTrait()) << '(';2608 E->getQueriedType().print(OS, Policy);2609 OS << ')';2610}2611 2612void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {2613 OS << getTraitSpelling(E->getTrait()) << '(';2614 PrintExpr(E->getQueriedExpression());2615 OS << ')';2616}2617 2618void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {2619 OS << "noexcept(";2620 PrintExpr(E->getOperand());2621 OS << ")";2622}2623 2624void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {2625 PrintExpr(E->getPattern());2626 OS << "...";2627}2628 2629void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {2630 OS << "sizeof...(" << *E->getPack() << ")";2631}2632 2633void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {2634 PrintExpr(E->getPackIdExpression());2635 OS << "...[";2636 PrintExpr(E->getIndexExpr());2637 OS << "]";2638}2639 2640void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(2641 SubstNonTypeTemplateParmPackExpr *Node) {2642 OS << *Node->getParameterPack();2643}2644 2645void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(2646 SubstNonTypeTemplateParmExpr *Node) {2647 Visit(Node->getReplacement());2648}2649 2650void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {2651 OS << *E->getParameterPack();2652}2653 2654void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){2655 PrintExpr(Node->getSubExpr());2656}2657 2658void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {2659 OS << "(";2660 if (E->getLHS()) {2661 PrintExpr(E->getLHS());2662 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";2663 }2664 OS << "...";2665 if (E->getRHS()) {2666 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";2667 PrintExpr(E->getRHS());2668 }2669 OS << ")";2670}2671 2672void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {2673 llvm::interleaveComma(Node->getUserSpecifiedInitExprs(), OS,2674 [&](Expr *E) { PrintExpr(E); });2675}2676 2677void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {2678 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();2679 NNS.getNestedNameSpecifier().print(OS, Policy);2680 if (E->getTemplateKWLoc().isValid())2681 OS << "template ";2682 OS << E->getFoundDecl()->getName();2683 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),2684 Policy,2685 E->getNamedConcept()->getTemplateParameters());2686}2687 2688void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {2689 OS << "requires ";2690 auto LocalParameters = E->getLocalParameters();2691 if (!LocalParameters.empty()) {2692 OS << "(";2693 for (ParmVarDecl *LocalParam : LocalParameters) {2694 PrintRawDecl(LocalParam);2695 if (LocalParam != LocalParameters.back())2696 OS << ", ";2697 }2698 2699 OS << ") ";2700 }2701 OS << "{ ";2702 auto Requirements = E->getRequirements();2703 for (concepts::Requirement *Req : Requirements) {2704 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {2705 if (TypeReq->isSubstitutionFailure())2706 OS << "<<error-type>>";2707 else2708 TypeReq->getType()->getType().print(OS, Policy);2709 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {2710 if (ExprReq->isCompound())2711 OS << "{ ";2712 if (ExprReq->isExprSubstitutionFailure())2713 OS << "<<error-expression>>";2714 else2715 PrintExpr(ExprReq->getExpr());2716 if (ExprReq->isCompound()) {2717 OS << " }";2718 if (ExprReq->getNoexceptLoc().isValid())2719 OS << " noexcept";2720 const auto &RetReq = ExprReq->getReturnTypeRequirement();2721 if (!RetReq.isEmpty()) {2722 OS << " -> ";2723 if (RetReq.isSubstitutionFailure())2724 OS << "<<error-type>>";2725 else if (RetReq.isTypeConstraint())2726 RetReq.getTypeConstraint()->print(OS, Policy);2727 }2728 }2729 } else {2730 auto *NestedReq = cast<concepts::NestedRequirement>(Req);2731 OS << "requires ";2732 if (NestedReq->hasInvalidConstraint())2733 OS << "<<error-expression>>";2734 else2735 PrintExpr(NestedReq->getConstraintExpr());2736 }2737 OS << "; ";2738 }2739 OS << "}";2740}2741 2742// C++ Coroutines2743 2744void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {2745 Visit(S->getBody());2746}2747 2748void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {2749 OS << "co_return";2750 if (S->getOperand()) {2751 OS << " ";2752 Visit(S->getOperand());2753 }2754 OS << ";";2755}2756 2757void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {2758 OS << "co_await ";2759 PrintExpr(S->getOperand());2760}2761 2762void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {2763 OS << "co_await ";2764 PrintExpr(S->getOperand());2765}2766 2767void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {2768 OS << "co_yield ";2769 PrintExpr(S->getOperand());2770}2771 2772// Obj-C2773 2774void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {2775 OS << "@";2776 VisitStringLiteral(Node->getString());2777}2778 2779void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {2780 OS << "@";2781 Visit(E->getSubExpr());2782}2783 2784void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {2785 OS << "@[ ";2786 ObjCArrayLiteral::child_range Ch = E->children();2787 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {2788 if (I != Ch.begin())2789 OS << ", ";2790 Visit(*I);2791 }2792 OS << " ]";2793}2794 2795void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {2796 OS << "@{ ";2797 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {2798 if (I > 0)2799 OS << ", ";2800 2801 ObjCDictionaryElement Element = E->getKeyValueElement(I);2802 Visit(Element.Key);2803 OS << " : ";2804 Visit(Element.Value);2805 if (Element.isPackExpansion())2806 OS << "...";2807 }2808 OS << " }";2809}2810 2811void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {2812 OS << "@encode(";2813 Node->getEncodedType().print(OS, Policy);2814 OS << ')';2815}2816 2817void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {2818 OS << "@selector(";2819 Node->getSelector().print(OS);2820 OS << ')';2821}2822 2823void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {2824 OS << "@protocol(" << *Node->getProtocol() << ')';2825}2826 2827void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {2828 OS << "[";2829 switch (Mess->getReceiverKind()) {2830 case ObjCMessageExpr::Instance:2831 PrintExpr(Mess->getInstanceReceiver());2832 break;2833 2834 case ObjCMessageExpr::Class:2835 Mess->getClassReceiver().print(OS, Policy);2836 break;2837 2838 case ObjCMessageExpr::SuperInstance:2839 case ObjCMessageExpr::SuperClass:2840 OS << "Super";2841 break;2842 }2843 2844 OS << ' ';2845 Selector selector = Mess->getSelector();2846 if (selector.isUnarySelector()) {2847 OS << selector.getNameForSlot(0);2848 } else {2849 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {2850 if (i < selector.getNumArgs()) {2851 if (i > 0) OS << ' ';2852 if (selector.getIdentifierInfoForSlot(i))2853 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';2854 else2855 OS << ":";2856 }2857 else OS << ", "; // Handle variadic methods.2858 2859 PrintExpr(Mess->getArg(i));2860 }2861 }2862 OS << "]";2863}2864 2865void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {2866 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");2867}2868 2869void2870StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {2871 PrintExpr(E->getSubExpr());2872}2873 2874void2875StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {2876 OS << '(' << E->getBridgeKindName();2877 E->getType().print(OS, Policy);2878 OS << ')';2879 PrintExpr(E->getSubExpr());2880}2881 2882void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {2883 BlockDecl *BD = Node->getBlockDecl();2884 OS << "^";2885 2886 const FunctionType *AFT = Node->getFunctionType();2887 2888 if (isa<FunctionNoProtoType>(AFT)) {2889 OS << "()";2890 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {2891 OS << '(';2892 for (BlockDecl::param_iterator AI = BD->param_begin(),2893 E = BD->param_end(); AI != E; ++AI) {2894 if (AI != BD->param_begin()) OS << ", ";2895 std::string ParamStr = (*AI)->getNameAsString();2896 (*AI)->getType().print(OS, Policy, ParamStr);2897 }2898 2899 const auto *FT = cast<FunctionProtoType>(AFT);2900 if (FT->isVariadic()) {2901 if (!BD->param_empty()) OS << ", ";2902 OS << "...";2903 }2904 OS << ')';2905 }2906 OS << "{ }";2907}2908 2909void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {2910 PrintExpr(Node->getSourceExpr());2911}2912 2913void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {2914 OS << "<recovery-expr>(";2915 const char *Sep = "";2916 for (Expr *E : Node->subExpressions()) {2917 OS << Sep;2918 PrintExpr(E);2919 Sep = ", ";2920 }2921 OS << ')';2922}2923 2924void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {2925 OS << "__builtin_astype(";2926 PrintExpr(Node->getSrcExpr());2927 OS << ", ";2928 Node->getType().print(OS, Policy);2929 OS << ")";2930}2931 2932void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {2933 PrintExpr(Node->getArgLValue());2934}2935 2936//===----------------------------------------------------------------------===//2937// Stmt method implementations2938//===----------------------------------------------------------------------===//2939 2940void Stmt::dumpPretty(const ASTContext &Context) const {2941 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));2942}2943 2944void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,2945 const PrintingPolicy &Policy, unsigned Indentation,2946 StringRef NL, const ASTContext *Context) const {2947 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);2948 P.Visit(const_cast<Stmt *>(this));2949}2950 2951void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,2952 const PrintingPolicy &Policy,2953 unsigned Indentation, StringRef NL,2954 const ASTContext *Context) const {2955 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);2956 P.PrintControlledStmt(const_cast<Stmt *>(this));2957}2958 2959void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,2960 const PrintingPolicy &Policy, bool AddQuotes) const {2961 std::string Buf;2962 llvm::raw_string_ostream TempOut(Buf);2963 2964 printPretty(TempOut, Helper, Policy);2965 2966 Out << JsonFormat(TempOut.str(), AddQuotes);2967}2968 2969//===----------------------------------------------------------------------===//2970// PrinterHelper2971//===----------------------------------------------------------------------===//2972 2973// Implement virtual destructor.2974PrinterHelper::~PrinterHelper() = default;2975