brintos

brintos / llvm-project-archived public Read only

0
0
Text · 82.7 KiB · ff8ca01 Raw
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