1341825Sdim//===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===// 2193326Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193326Sed// 7193326Sed//===----------------------------------------------------------------------===// 8193326Sed// 9193326Sed// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which 10193326Sed// pretty print the AST back out to C code. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14239462Sdim#include "clang/AST/ASTContext.h" 15249423Sdim#include "clang/AST/Attr.h" 16341825Sdim#include "clang/AST/Decl.h" 17341825Sdim#include "clang/AST/DeclBase.h" 18193326Sed#include "clang/AST/DeclCXX.h" 19193326Sed#include "clang/AST/DeclObjC.h" 20309124Sdim#include "clang/AST/DeclOpenMP.h" 21218893Sdim#include "clang/AST/DeclTemplate.h" 22207619Srdivacky#include "clang/AST/Expr.h" 23218893Sdim#include "clang/AST/ExprCXX.h" 24341825Sdim#include "clang/AST/ExprObjC.h" 25296417Sdim#include "clang/AST/ExprOpenMP.h" 26341825Sdim#include "clang/AST/NestedNameSpecifier.h" 27341825Sdim#include "clang/AST/OpenMPClause.h" 28249423Sdim#include "clang/AST/PrettyPrinter.h" 29341825Sdim#include "clang/AST/Stmt.h" 30341825Sdim#include "clang/AST/StmtCXX.h" 31341825Sdim#include "clang/AST/StmtObjC.h" 32341825Sdim#include "clang/AST/StmtOpenMP.h" 33249423Sdim#include "clang/AST/StmtVisitor.h" 34341825Sdim#include "clang/AST/TemplateBase.h" 35341825Sdim#include "clang/AST/Type.h" 36249423Sdim#include "clang/Basic/CharInfo.h" 37341825Sdim#include "clang/Basic/ExpressionTraits.h" 38341825Sdim#include "clang/Basic/IdentifierTable.h" 39353358Sdim#include "clang/Basic/JsonSupport.h" 40341825Sdim#include "clang/Basic/LLVM.h" 41341825Sdim#include "clang/Basic/Lambda.h" 42341825Sdim#include "clang/Basic/OpenMPKinds.h" 43341825Sdim#include "clang/Basic/OperatorKinds.h" 44341825Sdim#include "clang/Basic/SourceLocation.h" 45341825Sdim#include "clang/Basic/TypeTraits.h" 46327952Sdim#include "clang/Lex/Lexer.h" 47341825Sdim#include "llvm/ADT/ArrayRef.h" 48234353Sdim#include "llvm/ADT/SmallString.h" 49341825Sdim#include "llvm/ADT/SmallVector.h" 50341825Sdim#include "llvm/ADT/StringRef.h" 51341825Sdim#include "llvm/Support/Casting.h" 52341825Sdim#include "llvm/Support/Compiler.h" 53341825Sdim#include "llvm/Support/ErrorHandling.h" 54249423Sdim#include "llvm/Support/Format.h" 55341825Sdim#include "llvm/Support/raw_ostream.h" 56341825Sdim#include <cassert> 57341825Sdim#include <string> 58341825Sdim 59193326Sedusing namespace clang; 60193326Sed 61193326Sed//===----------------------------------------------------------------------===// 62193326Sed// StmtPrinter Visitor 63193326Sed//===----------------------------------------------------------------------===// 64193326Sed 65341825Sdimnamespace { 66341825Sdim 67199990Srdivacky class StmtPrinter : public StmtVisitor<StmtPrinter> { 68226633Sdim raw_ostream &OS; 69193326Sed unsigned IndentLevel; 70341825Sdim PrinterHelper* Helper; 71193326Sed PrintingPolicy Policy; 72344779Sdim std::string NL; 73327952Sdim const ASTContext *Context; 74193326Sed 75193326Sed public: 76327952Sdim StmtPrinter(raw_ostream &os, PrinterHelper *helper, 77327952Sdim const PrintingPolicy &Policy, unsigned Indentation = 0, 78344779Sdim StringRef NL = "\n", 79327952Sdim const ASTContext *Context = nullptr) 80327952Sdim : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy), 81344779Sdim NL(NL), Context(Context) {} 82198092Srdivacky 83193326Sed void PrintStmt(Stmt *S) { 84193326Sed PrintStmt(S, Policy.Indentation); 85193326Sed } 86193326Sed 87193326Sed void PrintStmt(Stmt *S, int SubIndent) { 88193326Sed IndentLevel += SubIndent; 89193326Sed if (S && isa<Expr>(S)) { 90193326Sed // If this is an expr used in a stmt context, indent and newline it. 91193326Sed Indent(); 92193326Sed Visit(S); 93344779Sdim OS << ";" << NL; 94193326Sed } else if (S) { 95193326Sed Visit(S); 96193326Sed } else { 97344779Sdim Indent() << "<<<NULL STATEMENT>>>" << NL; 98193326Sed } 99193326Sed IndentLevel -= SubIndent; 100193326Sed } 101193326Sed 102344779Sdim void PrintInitStmt(Stmt *S, unsigned PrefixWidth) { 103344779Sdim // FIXME: Cope better with odd prefix widths. 104344779Sdim IndentLevel += (PrefixWidth + 1) / 2; 105344779Sdim if (auto *DS = dyn_cast<DeclStmt>(S)) 106344779Sdim PrintRawDeclStmt(DS); 107344779Sdim else 108344779Sdim PrintExpr(cast<Expr>(S)); 109344779Sdim OS << "; "; 110344779Sdim IndentLevel -= (PrefixWidth + 1) / 2; 111344779Sdim } 112344779Sdim 113344779Sdim void PrintControlledStmt(Stmt *S) { 114344779Sdim if (auto *CS = dyn_cast<CompoundStmt>(S)) { 115344779Sdim OS << " "; 116344779Sdim PrintRawCompoundStmt(CS); 117344779Sdim OS << NL; 118344779Sdim } else { 119344779Sdim OS << NL; 120344779Sdim PrintStmt(S); 121344779Sdim } 122344779Sdim } 123344779Sdim 124193326Sed void PrintRawCompoundStmt(CompoundStmt *S); 125193326Sed void PrintRawDecl(Decl *D); 126243830Sdim void PrintRawDeclStmt(const DeclStmt *S); 127193326Sed void PrintRawIfStmt(IfStmt *If); 128193326Sed void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 129218893Sdim void PrintCallArgs(CallExpr *E); 130221345Sdim void PrintRawSEHExceptHandler(SEHExceptStmt *S); 131221345Sdim void PrintRawSEHFinallyStmt(SEHFinallyStmt *S); 132327952Sdim void PrintOMPExecutableDirective(OMPExecutableDirective *S, 133327952Sdim bool ForceNoStmt = false); 134198092Srdivacky 135193326Sed void PrintExpr(Expr *E) { 136193326Sed if (E) 137193326Sed Visit(E); 138193326Sed else 139193326Sed OS << "<null expr>"; 140193326Sed } 141198092Srdivacky 142226633Sdim raw_ostream &Indent(int Delta = 0) { 143193326Sed for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 144193326Sed OS << " "; 145193326Sed return OS; 146193326Sed } 147198092Srdivacky 148198092Srdivacky void Visit(Stmt* S) { 149193326Sed if (Helper && Helper->handledStmt(S,OS)) 150193326Sed return; 151193326Sed else StmtVisitor<StmtPrinter>::Visit(S); 152193326Sed } 153276479Sdim 154218893Sdim void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 155344779Sdim Indent() << "<<unknown stmt type>>" << NL; 156212904Sdim } 157341825Sdim 158218893Sdim void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 159212904Sdim OS << "<<unknown expr type>>"; 160212904Sdim } 161341825Sdim 162212904Sdim void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 163198092Srdivacky 164212904Sdim#define ABSTRACT_STMT(CLASS) 165193326Sed#define STMT(CLASS, PARENT) \ 166193326Sed void Visit##CLASS(CLASS *Node); 167208600Srdivacky#include "clang/AST/StmtNodes.inc" 168193326Sed }; 169193326Sed 170341825Sdim} // namespace 171341825Sdim 172193326Sed//===----------------------------------------------------------------------===// 173193326Sed// Stmt printing methods. 174193326Sed//===----------------------------------------------------------------------===// 175193326Sed 176193326Sed/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 177193326Sed/// with no newline after the }. 178193326Sedvoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 179344779Sdim OS << "{" << NL; 180276479Sdim for (auto *I : Node->body()) 181276479Sdim PrintStmt(I); 182198092Srdivacky 183193326Sed Indent() << "}"; 184193326Sed} 185193326Sed 186193326Sedvoid StmtPrinter::PrintRawDecl(Decl *D) { 187195341Sed D->print(OS, Policy, IndentLevel); 188193326Sed} 189193326Sed 190243830Sdimvoid StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) { 191341825Sdim SmallVector<Decl *, 2> Decls(S->decls()); 192195341Sed Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 193193326Sed} 194193326Sed 195193326Sedvoid StmtPrinter::VisitNullStmt(NullStmt *Node) { 196344779Sdim Indent() << ";" << NL; 197193326Sed} 198193326Sed 199193326Sedvoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 200193326Sed Indent(); 201193326Sed PrintRawDeclStmt(Node); 202344779Sdim OS << ";" << NL; 203193326Sed} 204193326Sed 205193326Sedvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 206193326Sed Indent(); 207193326Sed PrintRawCompoundStmt(Node); 208344779Sdim OS << "" << NL; 209193326Sed} 210193326Sed 211193326Sedvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 212193326Sed Indent(-1) << "case "; 213193326Sed PrintExpr(Node->getLHS()); 214193326Sed if (Node->getRHS()) { 215193326Sed OS << " ... "; 216193326Sed PrintExpr(Node->getRHS()); 217193326Sed } 218344779Sdim OS << ":" << NL; 219198092Srdivacky 220193326Sed PrintStmt(Node->getSubStmt(), 0); 221193326Sed} 222193326Sed 223193326Sedvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 224344779Sdim Indent(-1) << "default:" << NL; 225193326Sed PrintStmt(Node->getSubStmt(), 0); 226193326Sed} 227193326Sed 228193326Sedvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 229344779Sdim Indent(-1) << Node->getName() << ":" << NL; 230193326Sed PrintStmt(Node->getSubStmt(), 0); 231193326Sed} 232193326Sed 233234982Sdimvoid StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { 234276479Sdim for (const auto *Attr : Node->getAttrs()) { 235276479Sdim Attr->printPretty(OS, Policy); 236234982Sdim } 237276479Sdim 238234982Sdim PrintStmt(Node->getSubStmt(), 0); 239234982Sdim} 240234982Sdim 241193326Sedvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) { 242193326Sed OS << "if ("; 243344779Sdim if (If->getInit()) 244344779Sdim PrintInitStmt(If->getInit(), 4); 245243830Sdim if (const DeclStmt *DS = If->getConditionVariableDeclStmt()) 246243830Sdim PrintRawDeclStmt(DS); 247243830Sdim else 248243830Sdim PrintExpr(If->getCond()); 249193326Sed OS << ')'; 250198092Srdivacky 251341825Sdim if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) { 252193326Sed OS << ' '; 253193326Sed PrintRawCompoundStmt(CS); 254344779Sdim OS << (If->getElse() ? " " : NL); 255193326Sed } else { 256344779Sdim OS << NL; 257193326Sed PrintStmt(If->getThen()); 258193326Sed if (If->getElse()) Indent(); 259193326Sed } 260198092Srdivacky 261193326Sed if (Stmt *Else = If->getElse()) { 262193326Sed OS << "else"; 263198092Srdivacky 264341825Sdim if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 265193326Sed OS << ' '; 266193326Sed PrintRawCompoundStmt(CS); 267344779Sdim OS << NL; 268341825Sdim } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) { 269193326Sed OS << ' '; 270193326Sed PrintRawIfStmt(ElseIf); 271193326Sed } else { 272344779Sdim OS << NL; 273193326Sed PrintStmt(If->getElse()); 274193326Sed } 275193326Sed } 276193326Sed} 277193326Sed 278193326Sedvoid StmtPrinter::VisitIfStmt(IfStmt *If) { 279193326Sed Indent(); 280193326Sed PrintRawIfStmt(If); 281193326Sed} 282193326Sed 283193326Sedvoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 284193326Sed Indent() << "switch ("; 285344779Sdim if (Node->getInit()) 286344779Sdim PrintInitStmt(Node->getInit(), 8); 287243830Sdim if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 288243830Sdim PrintRawDeclStmt(DS); 289243830Sdim else 290243830Sdim PrintExpr(Node->getCond()); 291193326Sed OS << ")"; 292344779Sdim PrintControlledStmt(Node->getBody()); 293193326Sed} 294193326Sed 295193326Sedvoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 296193326Sed Indent() << "while ("; 297243830Sdim if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 298243830Sdim PrintRawDeclStmt(DS); 299243830Sdim else 300243830Sdim PrintExpr(Node->getCond()); 301344779Sdim OS << ")" << NL; 302193326Sed PrintStmt(Node->getBody()); 303193326Sed} 304193326Sed 305193326Sedvoid StmtPrinter::VisitDoStmt(DoStmt *Node) { 306193326Sed Indent() << "do "; 307341825Sdim if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 308193326Sed PrintRawCompoundStmt(CS); 309193326Sed OS << " "; 310193326Sed } else { 311344779Sdim OS << NL; 312193326Sed PrintStmt(Node->getBody()); 313193326Sed Indent(); 314193326Sed } 315198092Srdivacky 316193326Sed OS << "while ("; 317193326Sed PrintExpr(Node->getCond()); 318344779Sdim OS << ");" << NL; 319193326Sed} 320193326Sed 321193326Sedvoid StmtPrinter::VisitForStmt(ForStmt *Node) { 322193326Sed Indent() << "for ("; 323344779Sdim if (Node->getInit()) 324344779Sdim PrintInitStmt(Node->getInit(), 5); 325344779Sdim else 326344779Sdim OS << (Node->getCond() ? "; " : ";"); 327344779Sdim if (Node->getCond()) 328193326Sed PrintExpr(Node->getCond()); 329193326Sed OS << ";"; 330193326Sed if (Node->getInc()) { 331193326Sed OS << " "; 332193326Sed PrintExpr(Node->getInc()); 333193326Sed } 334344779Sdim OS << ")"; 335344779Sdim PrintControlledStmt(Node->getBody()); 336193326Sed} 337193326Sed 338193326Sedvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 339193326Sed Indent() << "for ("; 340341825Sdim if (auto *DS = dyn_cast<DeclStmt>(Node->getElement())) 341193326Sed PrintRawDeclStmt(DS); 342193326Sed else 343193326Sed PrintExpr(cast<Expr>(Node->getElement())); 344193326Sed OS << " in "; 345193326Sed PrintExpr(Node->getCollection()); 346344779Sdim OS << ")"; 347344779Sdim PrintControlledStmt(Node->getBody()); 348193326Sed} 349193326Sed 350221345Sdimvoid StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { 351221345Sdim Indent() << "for ("; 352344779Sdim if (Node->getInit()) 353344779Sdim PrintInitStmt(Node->getInit(), 5); 354221345Sdim PrintingPolicy SubPolicy(Policy); 355221345Sdim SubPolicy.SuppressInitializers = true; 356221345Sdim Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel); 357221345Sdim OS << " : "; 358221345Sdim PrintExpr(Node->getRangeInit()); 359344779Sdim OS << ")"; 360344779Sdim PrintControlledStmt(Node->getBody()); 361221345Sdim} 362221345Sdim 363234353Sdimvoid StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) { 364234353Sdim Indent(); 365234353Sdim if (Node->isIfExists()) 366234353Sdim OS << "__if_exists ("; 367234353Sdim else 368234353Sdim OS << "__if_not_exists ("; 369341825Sdim 370234353Sdim if (NestedNameSpecifier *Qualifier 371234353Sdim = Node->getQualifierLoc().getNestedNameSpecifier()) 372234353Sdim Qualifier->print(OS, Policy); 373341825Sdim 374234353Sdim OS << Node->getNameInfo() << ") "; 375341825Sdim 376234353Sdim PrintRawCompoundStmt(Node->getSubStmt()); 377234353Sdim} 378234353Sdim 379193326Sedvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 380276479Sdim Indent() << "goto " << Node->getLabel()->getName() << ";"; 381344779Sdim if (Policy.IncludeNewlines) OS << NL; 382193326Sed} 383193326Sed 384193326Sedvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 385193326Sed Indent() << "goto *"; 386193326Sed PrintExpr(Node->getTarget()); 387276479Sdim OS << ";"; 388344779Sdim if (Policy.IncludeNewlines) OS << NL; 389193326Sed} 390193326Sed 391193326Sedvoid StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 392276479Sdim Indent() << "continue;"; 393344779Sdim if (Policy.IncludeNewlines) OS << NL; 394193326Sed} 395193326Sed 396193326Sedvoid StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 397276479Sdim Indent() << "break;"; 398344779Sdim if (Policy.IncludeNewlines) OS << NL; 399193326Sed} 400193326Sed 401193326Sedvoid StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 402193326Sed Indent() << "return"; 403193326Sed if (Node->getRetValue()) { 404193326Sed OS << " "; 405193326Sed PrintExpr(Node->getRetValue()); 406193326Sed } 407276479Sdim OS << ";"; 408344779Sdim if (Policy.IncludeNewlines) OS << NL; 409193326Sed} 410193326Sed 411243830Sdimvoid StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { 412193326Sed Indent() << "asm "; 413198092Srdivacky 414193326Sed if (Node->isVolatile()) 415193326Sed OS << "volatile "; 416198092Srdivacky 417353358Sdim if (Node->isAsmGoto()) 418353358Sdim OS << "goto "; 419353358Sdim 420193326Sed OS << "("; 421193326Sed VisitStringLiteral(Node->getAsmString()); 422198092Srdivacky 423193326Sed // Outputs 424193326Sed if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 425353358Sdim Node->getNumClobbers() != 0 || Node->getNumLabels() != 0) 426193326Sed OS << " : "; 427198092Srdivacky 428193326Sed for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 429193326Sed if (i != 0) 430193326Sed OS << ", "; 431198092Srdivacky 432193326Sed if (!Node->getOutputName(i).empty()) { 433193326Sed OS << '['; 434193326Sed OS << Node->getOutputName(i); 435193326Sed OS << "] "; 436193326Sed } 437198092Srdivacky 438193326Sed VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 439288943Sdim OS << " ("; 440193326Sed Visit(Node->getOutputExpr(i)); 441288943Sdim OS << ")"; 442193326Sed } 443198092Srdivacky 444193326Sed // Inputs 445353358Sdim if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 || 446353358Sdim Node->getNumLabels() != 0) 447193326Sed OS << " : "; 448198092Srdivacky 449193326Sed for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 450193326Sed if (i != 0) 451193326Sed OS << ", "; 452198092Srdivacky 453193326Sed if (!Node->getInputName(i).empty()) { 454193326Sed OS << '['; 455193326Sed OS << Node->getInputName(i); 456193326Sed OS << "] "; 457193326Sed } 458198092Srdivacky 459193326Sed VisitStringLiteral(Node->getInputConstraintLiteral(i)); 460288943Sdim OS << " ("; 461193326Sed Visit(Node->getInputExpr(i)); 462288943Sdim OS << ")"; 463193326Sed } 464198092Srdivacky 465193326Sed // Clobbers 466353358Sdim if (Node->getNumClobbers() != 0 || Node->getNumLabels()) 467193326Sed OS << " : "; 468198092Srdivacky 469193326Sed for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 470193326Sed if (i != 0) 471193326Sed OS << ", "; 472198092Srdivacky 473243830Sdim VisitStringLiteral(Node->getClobberStringLiteral(i)); 474193326Sed } 475198092Srdivacky 476353358Sdim // Labels 477353358Sdim if (Node->getNumLabels() != 0) 478353358Sdim OS << " : "; 479353358Sdim 480353358Sdim for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) { 481353358Sdim if (i != 0) 482353358Sdim OS << ", "; 483353358Sdim OS << Node->getLabelName(i); 484353358Sdim } 485353358Sdim 486276479Sdim OS << ");"; 487344779Sdim if (Policy.IncludeNewlines) OS << NL; 488193326Sed} 489193326Sed 490239462Sdimvoid StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) { 491239462Sdim // FIXME: Implement MS style inline asm statement printer. 492239462Sdim Indent() << "__asm "; 493239462Sdim if (Node->hasBraces()) 494344779Sdim OS << "{" << NL; 495344779Sdim OS << Node->getAsmString() << NL; 496239462Sdim if (Node->hasBraces()) 497344779Sdim Indent() << "}" << NL; 498239462Sdim} 499239462Sdim 500251662Sdimvoid StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) { 501251662Sdim PrintStmt(Node->getCapturedDecl()->getBody()); 502251662Sdim} 503251662Sdim 504193326Sedvoid StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 505193326Sed Indent() << "@try"; 506341825Sdim if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 507193326Sed PrintRawCompoundStmt(TS); 508344779Sdim OS << NL; 509193326Sed } 510198092Srdivacky 511207619Srdivacky for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { 512207619Srdivacky ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); 513193326Sed Indent() << "@catch("; 514193326Sed if (catchStmt->getCatchParamDecl()) { 515193326Sed if (Decl *DS = catchStmt->getCatchParamDecl()) 516193326Sed PrintRawDecl(DS); 517193326Sed } 518193326Sed OS << ")"; 519341825Sdim if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 520198092Srdivacky PrintRawCompoundStmt(CS); 521344779Sdim OS << NL; 522198092Srdivacky } 523193326Sed } 524198092Srdivacky 525341825Sdim if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) { 526193326Sed Indent() << "@finally"; 527193326Sed PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 528344779Sdim OS << NL; 529198092Srdivacky } 530193326Sed} 531193326Sed 532193326Sedvoid StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 533193326Sed} 534193326Sed 535193326Sedvoid StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 536344779Sdim Indent() << "@catch (...) { /* todo */ } " << NL; 537193326Sed} 538193326Sed 539193326Sedvoid StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 540193326Sed Indent() << "@throw"; 541193326Sed if (Node->getThrowExpr()) { 542193326Sed OS << " "; 543193326Sed PrintExpr(Node->getThrowExpr()); 544193326Sed } 545344779Sdim OS << ";" << NL; 546193326Sed} 547193326Sed 548309124Sdimvoid StmtPrinter::VisitObjCAvailabilityCheckExpr( 549309124Sdim ObjCAvailabilityCheckExpr *Node) { 550309124Sdim OS << "@available(...)"; 551309124Sdim} 552309124Sdim 553193326Sedvoid StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 554193326Sed Indent() << "@synchronized ("; 555193326Sed PrintExpr(Node->getSynchExpr()); 556193326Sed OS << ")"; 557193326Sed PrintRawCompoundStmt(Node->getSynchBody()); 558344779Sdim OS << NL; 559193326Sed} 560193326Sed 561224145Sdimvoid StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) { 562224145Sdim Indent() << "@autoreleasepool"; 563224145Sdim PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt())); 564344779Sdim OS << NL; 565224145Sdim} 566224145Sdim 567193326Sedvoid StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 568193326Sed OS << "catch ("; 569193326Sed if (Decl *ExDecl = Node->getExceptionDecl()) 570193326Sed PrintRawDecl(ExDecl); 571193326Sed else 572193326Sed OS << "..."; 573193326Sed OS << ") "; 574193326Sed PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 575193326Sed} 576193326Sed 577193326Sedvoid StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 578193326Sed Indent(); 579193326Sed PrintRawCXXCatchStmt(Node); 580344779Sdim OS << NL; 581193326Sed} 582193326Sed 583193326Sedvoid StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 584193326Sed Indent() << "try "; 585193326Sed PrintRawCompoundStmt(Node->getTryBlock()); 586198092Srdivacky for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 587193326Sed OS << " "; 588193326Sed PrintRawCXXCatchStmt(Node->getHandler(i)); 589193326Sed } 590344779Sdim OS << NL; 591193326Sed} 592193326Sed 593221345Sdimvoid StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) { 594221345Sdim Indent() << (Node->getIsCXXTry() ? "try " : "__try "); 595221345Sdim PrintRawCompoundStmt(Node->getTryBlock()); 596221345Sdim SEHExceptStmt *E = Node->getExceptHandler(); 597221345Sdim SEHFinallyStmt *F = Node->getFinallyHandler(); 598221345Sdim if(E) 599221345Sdim PrintRawSEHExceptHandler(E); 600221345Sdim else { 601221345Sdim assert(F && "Must have a finally block..."); 602221345Sdim PrintRawSEHFinallyStmt(F); 603221345Sdim } 604344779Sdim OS << NL; 605221345Sdim} 606221345Sdim 607221345Sdimvoid StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) { 608221345Sdim OS << "__finally "; 609221345Sdim PrintRawCompoundStmt(Node->getBlock()); 610344779Sdim OS << NL; 611221345Sdim} 612221345Sdim 613221345Sdimvoid StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) { 614221345Sdim OS << "__except ("; 615221345Sdim VisitExpr(Node->getFilterExpr()); 616344779Sdim OS << ")" << NL; 617221345Sdim PrintRawCompoundStmt(Node->getBlock()); 618344779Sdim OS << NL; 619221345Sdim} 620221345Sdim 621221345Sdimvoid StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) { 622221345Sdim Indent(); 623221345Sdim PrintRawSEHExceptHandler(Node); 624344779Sdim OS << NL; 625221345Sdim} 626221345Sdim 627221345Sdimvoid StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { 628221345Sdim Indent(); 629221345Sdim PrintRawSEHFinallyStmt(Node); 630344779Sdim OS << NL; 631221345Sdim} 632221345Sdim 633276479Sdimvoid StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) { 634276479Sdim Indent() << "__leave;"; 635344779Sdim if (Policy.IncludeNewlines) OS << NL; 636276479Sdim} 637276479Sdim 638193326Sed//===----------------------------------------------------------------------===// 639261991Sdim// OpenMP directives printing methods 640261991Sdim//===----------------------------------------------------------------------===// 641261991Sdim 642327952Sdimvoid StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, 643327952Sdim bool ForceNoStmt) { 644276479Sdim OMPClausePrinter Printer(OS, Policy); 645276479Sdim ArrayRef<OMPClause *> Clauses = S->clauses(); 646341825Sdim for (auto *Clause : Clauses) 647341825Sdim if (Clause && !Clause->isImplicit()) { 648261991Sdim OS << ' '; 649341825Sdim Printer.Visit(Clause); 650261991Sdim } 651344779Sdim OS << NL; 652341825Sdim if (!ForceNoStmt && S->hasAssociatedStmt()) 653341825Sdim PrintStmt(S->getInnermostCapturedStmt()->getCapturedStmt()); 654261991Sdim} 655276479Sdim 656276479Sdimvoid StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) { 657341825Sdim Indent() << "#pragma omp parallel"; 658276479Sdim PrintOMPExecutableDirective(Node); 659276479Sdim} 660276479Sdim 661276479Sdimvoid StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) { 662341825Sdim Indent() << "#pragma omp simd"; 663276479Sdim PrintOMPExecutableDirective(Node); 664276479Sdim} 665276479Sdim 666276479Sdimvoid StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) { 667341825Sdim Indent() << "#pragma omp for"; 668276479Sdim PrintOMPExecutableDirective(Node); 669276479Sdim} 670276479Sdim 671280031Sdimvoid StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) { 672341825Sdim Indent() << "#pragma omp for simd"; 673280031Sdim PrintOMPExecutableDirective(Node); 674280031Sdim} 675280031Sdim 676276479Sdimvoid StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) { 677341825Sdim Indent() << "#pragma omp sections"; 678276479Sdim PrintOMPExecutableDirective(Node); 679276479Sdim} 680276479Sdim 681276479Sdimvoid StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) { 682276479Sdim Indent() << "#pragma omp section"; 683276479Sdim PrintOMPExecutableDirective(Node); 684276479Sdim} 685276479Sdim 686276479Sdimvoid StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) { 687341825Sdim Indent() << "#pragma omp single"; 688276479Sdim PrintOMPExecutableDirective(Node); 689276479Sdim} 690276479Sdim 691276479Sdimvoid StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) { 692276479Sdim Indent() << "#pragma omp master"; 693276479Sdim PrintOMPExecutableDirective(Node); 694276479Sdim} 695276479Sdim 696276479Sdimvoid StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) { 697276479Sdim Indent() << "#pragma omp critical"; 698276479Sdim if (Node->getDirectiveName().getName()) { 699276479Sdim OS << " ("; 700360784Sdim Node->getDirectiveName().printName(OS, Policy); 701276479Sdim OS << ")"; 702276479Sdim } 703276479Sdim PrintOMPExecutableDirective(Node); 704276479Sdim} 705276479Sdim 706276479Sdimvoid StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { 707341825Sdim Indent() << "#pragma omp parallel for"; 708276479Sdim PrintOMPExecutableDirective(Node); 709276479Sdim} 710276479Sdim 711280031Sdimvoid StmtPrinter::VisitOMPParallelForSimdDirective( 712280031Sdim OMPParallelForSimdDirective *Node) { 713341825Sdim Indent() << "#pragma omp parallel for simd"; 714280031Sdim PrintOMPExecutableDirective(Node); 715280031Sdim} 716280031Sdim 717360784Sdimvoid StmtPrinter::VisitOMPParallelMasterDirective( 718360784Sdim OMPParallelMasterDirective *Node) { 719360784Sdim Indent() << "#pragma omp parallel master"; 720360784Sdim PrintOMPExecutableDirective(Node); 721360784Sdim} 722360784Sdim 723276479Sdimvoid StmtPrinter::VisitOMPParallelSectionsDirective( 724276479Sdim OMPParallelSectionsDirective *Node) { 725341825Sdim Indent() << "#pragma omp parallel sections"; 726276479Sdim PrintOMPExecutableDirective(Node); 727276479Sdim} 728276479Sdim 729276479Sdimvoid StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) { 730341825Sdim Indent() << "#pragma omp task"; 731276479Sdim PrintOMPExecutableDirective(Node); 732276479Sdim} 733276479Sdim 734276479Sdimvoid StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) { 735276479Sdim Indent() << "#pragma omp taskyield"; 736276479Sdim PrintOMPExecutableDirective(Node); 737276479Sdim} 738276479Sdim 739276479Sdimvoid StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) { 740276479Sdim Indent() << "#pragma omp barrier"; 741276479Sdim PrintOMPExecutableDirective(Node); 742276479Sdim} 743276479Sdim 744276479Sdimvoid StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { 745276479Sdim Indent() << "#pragma omp taskwait"; 746276479Sdim PrintOMPExecutableDirective(Node); 747276479Sdim} 748276479Sdim 749288943Sdimvoid StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { 750341825Sdim Indent() << "#pragma omp taskgroup"; 751288943Sdim PrintOMPExecutableDirective(Node); 752288943Sdim} 753288943Sdim 754276479Sdimvoid StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) { 755341825Sdim Indent() << "#pragma omp flush"; 756276479Sdim PrintOMPExecutableDirective(Node); 757276479Sdim} 758276479Sdim 759280031Sdimvoid StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { 760341825Sdim Indent() << "#pragma omp ordered"; 761341825Sdim PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>()); 762280031Sdim} 763280031Sdim 764280031Sdimvoid StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) { 765341825Sdim Indent() << "#pragma omp atomic"; 766280031Sdim PrintOMPExecutableDirective(Node); 767280031Sdim} 768280031Sdim 769280031Sdimvoid StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) { 770341825Sdim Indent() << "#pragma omp target"; 771280031Sdim PrintOMPExecutableDirective(Node); 772280031Sdim} 773280031Sdim 774296417Sdimvoid StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) { 775341825Sdim Indent() << "#pragma omp target data"; 776296417Sdim PrintOMPExecutableDirective(Node); 777296417Sdim} 778296417Sdim 779309124Sdimvoid StmtPrinter::VisitOMPTargetEnterDataDirective( 780309124Sdim OMPTargetEnterDataDirective *Node) { 781341825Sdim Indent() << "#pragma omp target enter data"; 782327952Sdim PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 783309124Sdim} 784309124Sdim 785309124Sdimvoid StmtPrinter::VisitOMPTargetExitDataDirective( 786309124Sdim OMPTargetExitDataDirective *Node) { 787341825Sdim Indent() << "#pragma omp target exit data"; 788327952Sdim PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 789309124Sdim} 790309124Sdim 791309124Sdimvoid StmtPrinter::VisitOMPTargetParallelDirective( 792309124Sdim OMPTargetParallelDirective *Node) { 793341825Sdim Indent() << "#pragma omp target parallel"; 794309124Sdim PrintOMPExecutableDirective(Node); 795309124Sdim} 796309124Sdim 797309124Sdimvoid StmtPrinter::VisitOMPTargetParallelForDirective( 798309124Sdim OMPTargetParallelForDirective *Node) { 799341825Sdim Indent() << "#pragma omp target parallel for"; 800309124Sdim PrintOMPExecutableDirective(Node); 801309124Sdim} 802309124Sdim 803280031Sdimvoid StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { 804341825Sdim Indent() << "#pragma omp teams"; 805280031Sdim PrintOMPExecutableDirective(Node); 806280031Sdim} 807280031Sdim 808288943Sdimvoid StmtPrinter::VisitOMPCancellationPointDirective( 809288943Sdim OMPCancellationPointDirective *Node) { 810288943Sdim Indent() << "#pragma omp cancellation point " 811288943Sdim << getOpenMPDirectiveName(Node->getCancelRegion()); 812288943Sdim PrintOMPExecutableDirective(Node); 813288943Sdim} 814288943Sdim 815288943Sdimvoid StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { 816288943Sdim Indent() << "#pragma omp cancel " 817341825Sdim << getOpenMPDirectiveName(Node->getCancelRegion()); 818288943Sdim PrintOMPExecutableDirective(Node); 819288943Sdim} 820296417Sdim 821296417Sdimvoid StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) { 822341825Sdim Indent() << "#pragma omp taskloop"; 823296417Sdim PrintOMPExecutableDirective(Node); 824296417Sdim} 825296417Sdim 826296417Sdimvoid StmtPrinter::VisitOMPTaskLoopSimdDirective( 827296417Sdim OMPTaskLoopSimdDirective *Node) { 828341825Sdim Indent() << "#pragma omp taskloop simd"; 829296417Sdim PrintOMPExecutableDirective(Node); 830296417Sdim} 831296417Sdim 832360784Sdimvoid StmtPrinter::VisitOMPMasterTaskLoopDirective( 833360784Sdim OMPMasterTaskLoopDirective *Node) { 834360784Sdim Indent() << "#pragma omp master taskloop"; 835360784Sdim PrintOMPExecutableDirective(Node); 836360784Sdim} 837360784Sdim 838360784Sdimvoid StmtPrinter::VisitOMPMasterTaskLoopSimdDirective( 839360784Sdim OMPMasterTaskLoopSimdDirective *Node) { 840360784Sdim Indent() << "#pragma omp master taskloop simd"; 841360784Sdim PrintOMPExecutableDirective(Node); 842360784Sdim} 843360784Sdim 844360784Sdimvoid StmtPrinter::VisitOMPParallelMasterTaskLoopDirective( 845360784Sdim OMPParallelMasterTaskLoopDirective *Node) { 846360784Sdim Indent() << "#pragma omp parallel master taskloop"; 847360784Sdim PrintOMPExecutableDirective(Node); 848360784Sdim} 849360784Sdim 850360784Sdimvoid StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective( 851360784Sdim OMPParallelMasterTaskLoopSimdDirective *Node) { 852360784Sdim Indent() << "#pragma omp parallel master taskloop simd"; 853360784Sdim PrintOMPExecutableDirective(Node); 854360784Sdim} 855360784Sdim 856296417Sdimvoid StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) { 857341825Sdim Indent() << "#pragma omp distribute"; 858296417Sdim PrintOMPExecutableDirective(Node); 859296417Sdim} 860296417Sdim 861309124Sdimvoid StmtPrinter::VisitOMPTargetUpdateDirective( 862309124Sdim OMPTargetUpdateDirective *Node) { 863341825Sdim Indent() << "#pragma omp target update"; 864327952Sdim PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 865309124Sdim} 866309124Sdim 867309124Sdimvoid StmtPrinter::VisitOMPDistributeParallelForDirective( 868309124Sdim OMPDistributeParallelForDirective *Node) { 869341825Sdim Indent() << "#pragma omp distribute parallel for"; 870309124Sdim PrintOMPExecutableDirective(Node); 871309124Sdim} 872309124Sdim 873309124Sdimvoid StmtPrinter::VisitOMPDistributeParallelForSimdDirective( 874309124Sdim OMPDistributeParallelForSimdDirective *Node) { 875341825Sdim Indent() << "#pragma omp distribute parallel for simd"; 876309124Sdim PrintOMPExecutableDirective(Node); 877309124Sdim} 878309124Sdim 879309124Sdimvoid StmtPrinter::VisitOMPDistributeSimdDirective( 880309124Sdim OMPDistributeSimdDirective *Node) { 881341825Sdim Indent() << "#pragma omp distribute simd"; 882309124Sdim PrintOMPExecutableDirective(Node); 883309124Sdim} 884309124Sdim 885309124Sdimvoid StmtPrinter::VisitOMPTargetParallelForSimdDirective( 886309124Sdim OMPTargetParallelForSimdDirective *Node) { 887341825Sdim Indent() << "#pragma omp target parallel for simd"; 888309124Sdim PrintOMPExecutableDirective(Node); 889309124Sdim} 890309124Sdim 891314564Sdimvoid StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) { 892341825Sdim Indent() << "#pragma omp target simd"; 893314564Sdim PrintOMPExecutableDirective(Node); 894314564Sdim} 895314564Sdim 896314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeDirective( 897314564Sdim OMPTeamsDistributeDirective *Node) { 898341825Sdim Indent() << "#pragma omp teams distribute"; 899314564Sdim PrintOMPExecutableDirective(Node); 900314564Sdim} 901314564Sdim 902314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeSimdDirective( 903314564Sdim OMPTeamsDistributeSimdDirective *Node) { 904341825Sdim Indent() << "#pragma omp teams distribute simd"; 905314564Sdim PrintOMPExecutableDirective(Node); 906314564Sdim} 907314564Sdim 908314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective( 909314564Sdim OMPTeamsDistributeParallelForSimdDirective *Node) { 910341825Sdim Indent() << "#pragma omp teams distribute parallel for simd"; 911314564Sdim PrintOMPExecutableDirective(Node); 912314564Sdim} 913314564Sdim 914314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeParallelForDirective( 915314564Sdim OMPTeamsDistributeParallelForDirective *Node) { 916341825Sdim Indent() << "#pragma omp teams distribute parallel for"; 917314564Sdim PrintOMPExecutableDirective(Node); 918314564Sdim} 919314564Sdim 920314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) { 921341825Sdim Indent() << "#pragma omp target teams"; 922314564Sdim PrintOMPExecutableDirective(Node); 923314564Sdim} 924314564Sdim 925314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeDirective( 926314564Sdim OMPTargetTeamsDistributeDirective *Node) { 927341825Sdim Indent() << "#pragma omp target teams distribute"; 928314564Sdim PrintOMPExecutableDirective(Node); 929314564Sdim} 930314564Sdim 931314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective( 932314564Sdim OMPTargetTeamsDistributeParallelForDirective *Node) { 933341825Sdim Indent() << "#pragma omp target teams distribute parallel for"; 934314564Sdim PrintOMPExecutableDirective(Node); 935314564Sdim} 936314564Sdim 937314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective( 938314564Sdim OMPTargetTeamsDistributeParallelForSimdDirective *Node) { 939341825Sdim Indent() << "#pragma omp target teams distribute parallel for simd"; 940314564Sdim PrintOMPExecutableDirective(Node); 941314564Sdim} 942314564Sdim 943314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective( 944314564Sdim OMPTargetTeamsDistributeSimdDirective *Node) { 945341825Sdim Indent() << "#pragma omp target teams distribute simd"; 946314564Sdim PrintOMPExecutableDirective(Node); 947314564Sdim} 948314564Sdim 949261991Sdim//===----------------------------------------------------------------------===// 950193326Sed// Expr printing methods. 951193326Sed//===----------------------------------------------------------------------===// 952193326Sed 953353358Sdimvoid StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) { 954353358Sdim OS << Node->getBuiltinStr() << "()"; 955353358Sdim} 956353358Sdim 957344779Sdimvoid StmtPrinter::VisitConstantExpr(ConstantExpr *Node) { 958344779Sdim PrintExpr(Node->getSubExpr()); 959344779Sdim} 960344779Sdim 961193326Sedvoid StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 962341825Sdim if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) { 963309124Sdim OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); 964309124Sdim return; 965309124Sdim } 966198893Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 967198893Srdivacky Qualifier->print(OS, Policy); 968234353Sdim if (Node->hasTemplateKeyword()) 969234353Sdim OS << "template "; 970212904Sdim OS << Node->getNameInfo(); 971212904Sdim if (Node->hasExplicitTemplateArgs()) 972327952Sdim printTemplateArgumentList(OS, Node->template_arguments(), Policy); 973193326Sed} 974193326Sed 975199990Srdivackyvoid StmtPrinter::VisitDependentScopeDeclRefExpr( 976199990Srdivacky DependentScopeDeclRefExpr *Node) { 977218893Sdim if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 978218893Sdim Qualifier->print(OS, Policy); 979234353Sdim if (Node->hasTemplateKeyword()) 980234353Sdim OS << "template "; 981212904Sdim OS << Node->getNameInfo(); 982199990Srdivacky if (Node->hasExplicitTemplateArgs()) 983327952Sdim printTemplateArgumentList(OS, Node->template_arguments(), Policy); 984193326Sed} 985193326Sed 986199990Srdivackyvoid StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 987195341Sed if (Node->getQualifier()) 988195341Sed Node->getQualifier()->print(OS, Policy); 989234353Sdim if (Node->hasTemplateKeyword()) 990234353Sdim OS << "template "; 991212904Sdim OS << Node->getNameInfo(); 992199990Srdivacky if (Node->hasExplicitTemplateArgs()) 993327952Sdim printTemplateArgumentList(OS, Node->template_arguments(), Policy); 994195341Sed} 995195341Sed 996327952Sdimstatic bool isImplicitSelf(const Expr *E) { 997327952Sdim if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 998341825Sdim if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) { 999327952Sdim if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf && 1000344779Sdim DRE->getBeginLoc().isInvalid()) 1001327952Sdim return true; 1002327952Sdim } 1003327952Sdim } 1004327952Sdim return false; 1005327952Sdim} 1006327952Sdim 1007193326Sedvoid StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 1008193326Sed if (Node->getBase()) { 1009327952Sdim if (!Policy.SuppressImplicitBase || 1010327952Sdim !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) { 1011327952Sdim PrintExpr(Node->getBase()); 1012327952Sdim OS << (Node->isArrow() ? "->" : "."); 1013327952Sdim } 1014193326Sed } 1015226633Sdim OS << *Node->getDecl(); 1016193326Sed} 1017193326Sed 1018193326Sedvoid StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 1019218893Sdim if (Node->isSuperReceiver()) 1020218893Sdim OS << "super."; 1021265925Sdim else if (Node->isObjectReceiver() && Node->getBase()) { 1022193326Sed PrintExpr(Node->getBase()); 1023193326Sed OS << "."; 1024265925Sdim } else if (Node->isClassReceiver() && Node->getClassReceiver()) { 1025265925Sdim OS << Node->getClassReceiver()->getName() << "."; 1026193326Sed } 1027193326Sed 1028341825Sdim if (Node->isImplicitProperty()) { 1029341825Sdim if (const auto *Getter = Node->getImplicitPropertyGetter()) 1030341825Sdim Getter->getSelector().print(OS); 1031341825Sdim else 1032341825Sdim OS << SelectorTable::getPropertyNameFromSetterSelector( 1033341825Sdim Node->getImplicitPropertySetter()->getSelector()); 1034341825Sdim } else 1035218893Sdim OS << Node->getExplicitProperty()->getName(); 1036193326Sed} 1037193326Sed 1038234353Sdimvoid StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) { 1039234353Sdim PrintExpr(Node->getBaseExpr()); 1040234353Sdim OS << "["; 1041234353Sdim PrintExpr(Node->getKeyExpr()); 1042234353Sdim OS << "]"; 1043234353Sdim} 1044234353Sdim 1045193326Sedvoid StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 1046344779Sdim OS << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 1047193326Sed} 1048193326Sed 1049193326Sedvoid StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 1050193326Sed unsigned value = Node->getValue(); 1051226633Sdim 1052226633Sdim switch (Node->getKind()) { 1053226633Sdim case CharacterLiteral::Ascii: break; // no prefix. 1054226633Sdim case CharacterLiteral::Wide: OS << 'L'; break; 1055296417Sdim case CharacterLiteral::UTF8: OS << "u8"; break; 1056226633Sdim case CharacterLiteral::UTF16: OS << 'u'; break; 1057226633Sdim case CharacterLiteral::UTF32: OS << 'U'; break; 1058226633Sdim } 1059226633Sdim 1060193326Sed switch (value) { 1061193326Sed case '\\': 1062193326Sed OS << "'\\\\'"; 1063193326Sed break; 1064193326Sed case '\'': 1065193326Sed OS << "'\\''"; 1066193326Sed break; 1067193326Sed case '\a': 1068193326Sed // TODO: K&R: the meaning of '\\a' is different in traditional C 1069193326Sed OS << "'\\a'"; 1070193326Sed break; 1071193326Sed case '\b': 1072193326Sed OS << "'\\b'"; 1073193326Sed break; 1074193326Sed // Nonstandard escape sequence. 1075193326Sed /*case '\e': 1076193326Sed OS << "'\\e'"; 1077193326Sed break;*/ 1078193326Sed case '\f': 1079193326Sed OS << "'\\f'"; 1080193326Sed break; 1081193326Sed case '\n': 1082193326Sed OS << "'\\n'"; 1083193326Sed break; 1084193326Sed case '\r': 1085193326Sed OS << "'\\r'"; 1086193326Sed break; 1087193326Sed case '\t': 1088193326Sed OS << "'\\t'"; 1089193326Sed break; 1090193326Sed case '\v': 1091193326Sed OS << "'\\v'"; 1092193326Sed break; 1093193326Sed default: 1094309124Sdim // A character literal might be sign-extended, which 1095309124Sdim // would result in an invalid \U escape sequence. 1096309124Sdim // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF' 1097309124Sdim // are not correctly handled. 1098309124Sdim if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii) 1099309124Sdim value &= 0xFFu; 1100249423Sdim if (value < 256 && isPrintable((unsigned char)value)) 1101193326Sed OS << "'" << (char)value << "'"; 1102249423Sdim else if (value < 256) 1103249423Sdim OS << "'\\x" << llvm::format("%02x", value) << "'"; 1104249423Sdim else if (value <= 0xFFFF) 1105249423Sdim OS << "'\\u" << llvm::format("%04x", value) << "'"; 1106249423Sdim else 1107249423Sdim OS << "'\\U" << llvm::format("%08x", value) << "'"; 1108193326Sed } 1109193326Sed} 1110193326Sed 1111327952Sdim/// Prints the given expression using the original source text. Returns true on 1112327952Sdim/// success, false otherwise. 1113327952Sdimstatic bool printExprAsWritten(raw_ostream &OS, Expr *E, 1114327952Sdim const ASTContext *Context) { 1115327952Sdim if (!Context) 1116327952Sdim return false; 1117327952Sdim bool Invalid = false; 1118327952Sdim StringRef Source = Lexer::getSourceText( 1119327952Sdim CharSourceRange::getTokenRange(E->getSourceRange()), 1120327952Sdim Context->getSourceManager(), Context->getLangOpts(), &Invalid); 1121327952Sdim if (!Invalid) { 1122327952Sdim OS << Source; 1123327952Sdim return true; 1124327952Sdim } 1125327952Sdim return false; 1126327952Sdim} 1127327952Sdim 1128193326Sedvoid StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 1129327952Sdim if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1130327952Sdim return; 1131193326Sed bool isSigned = Node->getType()->isSignedIntegerType(); 1132193326Sed OS << Node->getValue().toString(10, isSigned); 1133198092Srdivacky 1134193326Sed // Emit suffixes. Integer literals are always a builtin integer type. 1135360784Sdim switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 1136226633Sdim default: llvm_unreachable("Unexpected type for integer literal!"); 1137288943Sdim case BuiltinType::Char_S: 1138288943Sdim case BuiltinType::Char_U: OS << "i8"; break; 1139276479Sdim case BuiltinType::UChar: OS << "Ui8"; break; 1140276479Sdim case BuiltinType::Short: OS << "i16"; break; 1141276479Sdim case BuiltinType::UShort: OS << "Ui16"; break; 1142193326Sed case BuiltinType::Int: break; // no suffix. 1143193326Sed case BuiltinType::UInt: OS << 'U'; break; 1144193326Sed case BuiltinType::Long: OS << 'L'; break; 1145193326Sed case BuiltinType::ULong: OS << "UL"; break; 1146193326Sed case BuiltinType::LongLong: OS << "LL"; break; 1147193326Sed case BuiltinType::ULongLong: OS << "ULL"; break; 1148193326Sed } 1149193326Sed} 1150243830Sdim 1151341825Sdimvoid StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) { 1152341825Sdim if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1153341825Sdim return; 1154341825Sdim OS << Node->getValueAsString(/*Radix=*/10); 1155341825Sdim 1156360784Sdim switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 1157341825Sdim default: llvm_unreachable("Unexpected type for fixed point literal!"); 1158341825Sdim case BuiltinType::ShortFract: OS << "hr"; break; 1159341825Sdim case BuiltinType::ShortAccum: OS << "hk"; break; 1160341825Sdim case BuiltinType::UShortFract: OS << "uhr"; break; 1161341825Sdim case BuiltinType::UShortAccum: OS << "uhk"; break; 1162341825Sdim case BuiltinType::Fract: OS << "r"; break; 1163341825Sdim case BuiltinType::Accum: OS << "k"; break; 1164341825Sdim case BuiltinType::UFract: OS << "ur"; break; 1165341825Sdim case BuiltinType::UAccum: OS << "uk"; break; 1166341825Sdim case BuiltinType::LongFract: OS << "lr"; break; 1167341825Sdim case BuiltinType::LongAccum: OS << "lk"; break; 1168341825Sdim case BuiltinType::ULongFract: OS << "ulr"; break; 1169341825Sdim case BuiltinType::ULongAccum: OS << "ulk"; break; 1170341825Sdim } 1171341825Sdim} 1172341825Sdim 1173243830Sdimstatic void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, 1174243830Sdim bool PrintSuffix) { 1175234353Sdim SmallString<16> Str; 1176226633Sdim Node->getValue().toString(Str); 1177226633Sdim OS << Str; 1178243830Sdim if (Str.find_first_not_of("-0123456789") == StringRef::npos) 1179243830Sdim OS << '.'; // Trailing dot in order to separate from ints. 1180243830Sdim 1181243830Sdim if (!PrintSuffix) 1182243830Sdim return; 1183243830Sdim 1184243830Sdim // Emit suffixes. Float literals are always a builtin float type. 1185360784Sdim switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 1186243830Sdim default: llvm_unreachable("Unexpected type for float literal!"); 1187243830Sdim case BuiltinType::Half: break; // FIXME: suffix? 1188243830Sdim case BuiltinType::Double: break; // no suffix. 1189327952Sdim case BuiltinType::Float16: OS << "F16"; break; 1190243830Sdim case BuiltinType::Float: OS << 'F'; break; 1191243830Sdim case BuiltinType::LongDouble: OS << 'L'; break; 1192309124Sdim case BuiltinType::Float128: OS << 'Q'; break; 1193243830Sdim } 1194193326Sed} 1195193326Sed 1196243830Sdimvoid StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 1197327952Sdim if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1198327952Sdim return; 1199243830Sdim PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true); 1200243830Sdim} 1201243830Sdim 1202193326Sedvoid StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 1203193326Sed PrintExpr(Node->getSubExpr()); 1204193326Sed OS << "i"; 1205193326Sed} 1206193326Sed 1207193326Sedvoid StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 1208239462Sdim Str->outputString(OS); 1209193326Sed} 1210341825Sdim 1211193326Sedvoid StmtPrinter::VisitParenExpr(ParenExpr *Node) { 1212193326Sed OS << "("; 1213193326Sed PrintExpr(Node->getSubExpr()); 1214193326Sed OS << ")"; 1215193326Sed} 1216341825Sdim 1217193326Sedvoid StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 1218193326Sed if (!Node->isPostfix()) { 1219193326Sed OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 1220198092Srdivacky 1221194613Sed // Print a space if this is an "identifier operator" like __real, or if 1222194613Sed // it might be concatenated incorrectly like '+'. 1223193326Sed switch (Node->getOpcode()) { 1224193326Sed default: break; 1225212904Sdim case UO_Real: 1226212904Sdim case UO_Imag: 1227212904Sdim case UO_Extension: 1228193326Sed OS << ' '; 1229193326Sed break; 1230212904Sdim case UO_Plus: 1231212904Sdim case UO_Minus: 1232194613Sed if (isa<UnaryOperator>(Node->getSubExpr())) 1233194613Sed OS << ' '; 1234194613Sed break; 1235193326Sed } 1236193326Sed } 1237193326Sed PrintExpr(Node->getSubExpr()); 1238198092Srdivacky 1239193326Sed if (Node->isPostfix()) 1240193326Sed OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 1241193326Sed} 1242193326Sed 1243207619Srdivackyvoid StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 1244207619Srdivacky OS << "__builtin_offsetof("; 1245249423Sdim Node->getTypeSourceInfo()->getType().print(OS, Policy); 1246249423Sdim OS << ", "; 1247207619Srdivacky bool PrintedSomething = false; 1248207619Srdivacky for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 1249296417Sdim OffsetOfNode ON = Node->getComponent(i); 1250296417Sdim if (ON.getKind() == OffsetOfNode::Array) { 1251207619Srdivacky // Array node 1252207619Srdivacky OS << "["; 1253207619Srdivacky PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 1254207619Srdivacky OS << "]"; 1255207619Srdivacky PrintedSomething = true; 1256207619Srdivacky continue; 1257207619Srdivacky } 1258207619Srdivacky 1259207619Srdivacky // Skip implicit base indirections. 1260296417Sdim if (ON.getKind() == OffsetOfNode::Base) 1261207619Srdivacky continue; 1262207619Srdivacky 1263207619Srdivacky // Field or identifier node. 1264207619Srdivacky IdentifierInfo *Id = ON.getFieldName(); 1265207619Srdivacky if (!Id) 1266207619Srdivacky continue; 1267341825Sdim 1268207619Srdivacky if (PrintedSomething) 1269207619Srdivacky OS << "."; 1270207619Srdivacky else 1271207619Srdivacky PrintedSomething = true; 1272341825Sdim OS << Id->getName(); 1273207619Srdivacky } 1274207619Srdivacky OS << ")"; 1275207619Srdivacky} 1276207619Srdivacky 1277221345Sdimvoid StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ 1278221345Sdim switch(Node->getKind()) { 1279221345Sdim case UETT_SizeOf: 1280221345Sdim OS << "sizeof"; 1281221345Sdim break; 1282221345Sdim case UETT_AlignOf: 1283309124Sdim if (Policy.Alignof) 1284239462Sdim OS << "alignof"; 1285309124Sdim else if (Policy.UnderscoreAlignof) 1286239462Sdim OS << "_Alignof"; 1287239462Sdim else 1288239462Sdim OS << "__alignof"; 1289221345Sdim break; 1290344779Sdim case UETT_PreferredAlignOf: 1291344779Sdim OS << "__alignof"; 1292344779Sdim break; 1293221345Sdim case UETT_VecStep: 1294221345Sdim OS << "vec_step"; 1295221345Sdim break; 1296288943Sdim case UETT_OpenMPRequiredSimdAlign: 1297288943Sdim OS << "__builtin_omp_required_simd_align"; 1298288943Sdim break; 1299221345Sdim } 1300249423Sdim if (Node->isArgumentType()) { 1301249423Sdim OS << '('; 1302249423Sdim Node->getArgumentType().print(OS, Policy); 1303249423Sdim OS << ')'; 1304249423Sdim } else { 1305193326Sed OS << " "; 1306193326Sed PrintExpr(Node->getArgumentExpr()); 1307193326Sed } 1308193326Sed} 1309221345Sdim 1310221345Sdimvoid StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { 1311221345Sdim OS << "_Generic("; 1312221345Sdim PrintExpr(Node->getControllingExpr()); 1313360784Sdim for (const GenericSelectionExpr::Association Assoc : Node->associations()) { 1314221345Sdim OS << ", "; 1315353358Sdim QualType T = Assoc.getType(); 1316221345Sdim if (T.isNull()) 1317221345Sdim OS << "default"; 1318221345Sdim else 1319249423Sdim T.print(OS, Policy); 1320221345Sdim OS << ": "; 1321353358Sdim PrintExpr(Assoc.getAssociationExpr()); 1322221345Sdim } 1323221345Sdim OS << ")"; 1324221345Sdim} 1325221345Sdim 1326193326Sedvoid StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 1327193326Sed PrintExpr(Node->getLHS()); 1328193326Sed OS << "["; 1329193326Sed PrintExpr(Node->getRHS()); 1330193326Sed OS << "]"; 1331193326Sed} 1332193326Sed 1333296417Sdimvoid StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { 1334296417Sdim PrintExpr(Node->getBase()); 1335296417Sdim OS << "["; 1336296417Sdim if (Node->getLowerBound()) 1337296417Sdim PrintExpr(Node->getLowerBound()); 1338296417Sdim if (Node->getColonLoc().isValid()) { 1339296417Sdim OS << ":"; 1340296417Sdim if (Node->getLength()) 1341296417Sdim PrintExpr(Node->getLength()); 1342296417Sdim } 1343296417Sdim OS << "]"; 1344296417Sdim} 1345296417Sdim 1346218893Sdimvoid StmtPrinter::PrintCallArgs(CallExpr *Call) { 1347193326Sed for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 1348193326Sed if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 1349193326Sed // Don't print any defaulted arguments 1350193326Sed break; 1351193326Sed } 1352193326Sed 1353193326Sed if (i) OS << ", "; 1354193326Sed PrintExpr(Call->getArg(i)); 1355193326Sed } 1356218893Sdim} 1357218893Sdim 1358218893Sdimvoid StmtPrinter::VisitCallExpr(CallExpr *Call) { 1359218893Sdim PrintExpr(Call->getCallee()); 1360218893Sdim OS << "("; 1361218893Sdim PrintCallArgs(Call); 1362193326Sed OS << ")"; 1363193326Sed} 1364327952Sdim 1365327952Sdimstatic bool isImplicitThis(const Expr *E) { 1366327952Sdim if (const auto *TE = dyn_cast<CXXThisExpr>(E)) 1367327952Sdim return TE->isImplicit(); 1368327952Sdim return false; 1369327952Sdim} 1370327952Sdim 1371193326Sedvoid StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 1372327952Sdim if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) { 1373327952Sdim PrintExpr(Node->getBase()); 1374249423Sdim 1375341825Sdim auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase()); 1376327952Sdim FieldDecl *ParentDecl = 1377327952Sdim ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) 1378327952Sdim : nullptr; 1379249423Sdim 1380327952Sdim if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion()) 1381327952Sdim OS << (Node->isArrow() ? "->" : "."); 1382327952Sdim } 1383249423Sdim 1384341825Sdim if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 1385202379Srdivacky if (FD->isAnonymousStructOrUnion()) 1386202379Srdivacky return; 1387249423Sdim 1388198092Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1389198092Srdivacky Qualifier->print(OS, Policy); 1390234353Sdim if (Node->hasTemplateKeyword()) 1391234353Sdim OS << "template "; 1392212904Sdim OS << Node->getMemberNameInfo(); 1393212904Sdim if (Node->hasExplicitTemplateArgs()) 1394327952Sdim printTemplateArgumentList(OS, Node->template_arguments(), Policy); 1395193326Sed} 1396341825Sdim 1397198092Srdivackyvoid StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 1398198092Srdivacky PrintExpr(Node->getBase()); 1399198092Srdivacky OS << (Node->isArrow() ? "->isa" : ".isa"); 1400198092Srdivacky} 1401198092Srdivacky 1402193326Sedvoid StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 1403193326Sed PrintExpr(Node->getBase()); 1404193326Sed OS << "."; 1405193326Sed OS << Node->getAccessor().getName(); 1406193326Sed} 1407341825Sdim 1408193326Sedvoid StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 1409249423Sdim OS << '('; 1410249423Sdim Node->getTypeAsWritten().print(OS, Policy); 1411249423Sdim OS << ')'; 1412193326Sed PrintExpr(Node->getSubExpr()); 1413193326Sed} 1414341825Sdim 1415193326Sedvoid StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 1416249423Sdim OS << '('; 1417249423Sdim Node->getType().print(OS, Policy); 1418249423Sdim OS << ')'; 1419193326Sed PrintExpr(Node->getInitializer()); 1420193326Sed} 1421341825Sdim 1422193326Sedvoid StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 1423276479Sdim // No need to print anything, simply forward to the subexpression. 1424193326Sed PrintExpr(Node->getSubExpr()); 1425193326Sed} 1426341825Sdim 1427193326Sedvoid StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 1428193326Sed PrintExpr(Node->getLHS()); 1429193326Sed OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 1430193326Sed PrintExpr(Node->getRHS()); 1431193326Sed} 1432341825Sdim 1433193326Sedvoid StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 1434193326Sed PrintExpr(Node->getLHS()); 1435193326Sed OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 1436193326Sed PrintExpr(Node->getRHS()); 1437193326Sed} 1438341825Sdim 1439193326Sedvoid StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 1440193326Sed PrintExpr(Node->getCond()); 1441218893Sdim OS << " ? "; 1442218893Sdim PrintExpr(Node->getLHS()); 1443218893Sdim OS << " : "; 1444193326Sed PrintExpr(Node->getRHS()); 1445193326Sed} 1446193326Sed 1447193326Sed// GNU extensions. 1448193326Sed 1449218893Sdimvoid 1450218893SdimStmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 1451218893Sdim PrintExpr(Node->getCommon()); 1452218893Sdim OS << " ?: "; 1453218893Sdim PrintExpr(Node->getFalseExpr()); 1454218893Sdim} 1455341825Sdim 1456193326Sedvoid StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 1457193326Sed OS << "&&" << Node->getLabel()->getName(); 1458193326Sed} 1459193326Sed 1460193326Sedvoid StmtPrinter::VisitStmtExpr(StmtExpr *E) { 1461193326Sed OS << "("; 1462193326Sed PrintRawCompoundStmt(E->getSubStmt()); 1463193326Sed OS << ")"; 1464193326Sed} 1465193326Sed 1466193326Sedvoid StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 1467193326Sed OS << "__builtin_choose_expr("; 1468193326Sed PrintExpr(Node->getCond()); 1469193326Sed OS << ", "; 1470193326Sed PrintExpr(Node->getLHS()); 1471193326Sed OS << ", "; 1472193326Sed PrintExpr(Node->getRHS()); 1473193326Sed OS << ")"; 1474193326Sed} 1475193326Sed 1476193326Sedvoid StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 1477193326Sed OS << "__null"; 1478193326Sed} 1479193326Sed 1480193326Sedvoid StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 1481193326Sed OS << "__builtin_shufflevector("; 1482193326Sed for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 1483193326Sed if (i) OS << ", "; 1484193326Sed PrintExpr(Node->getExpr(i)); 1485193326Sed } 1486193326Sed OS << ")"; 1487193326Sed} 1488193326Sed 1489261991Sdimvoid StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) { 1490261991Sdim OS << "__builtin_convertvector("; 1491261991Sdim PrintExpr(Node->getSrcExpr()); 1492261991Sdim OS << ", "; 1493261991Sdim Node->getType().print(OS, Policy); 1494261991Sdim OS << ")"; 1495261991Sdim} 1496261991Sdim 1497193326Sedvoid StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 1498193326Sed if (Node->getSyntacticForm()) { 1499193326Sed Visit(Node->getSyntacticForm()); 1500193326Sed return; 1501193326Sed } 1502193326Sed 1503288943Sdim OS << "{"; 1504193326Sed for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 1505193326Sed if (i) OS << ", "; 1506193326Sed if (Node->getInit(i)) 1507193326Sed PrintExpr(Node->getInit(i)); 1508193326Sed else 1509288943Sdim OS << "{}"; 1510193326Sed } 1511288943Sdim OS << "}"; 1512193326Sed} 1513193326Sed 1514314564Sdimvoid StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) { 1515314564Sdim // There's no way to express this expression in any of our supported 1516314564Sdim // languages, so just emit something terse and (hopefully) clear. 1517314564Sdim OS << "{"; 1518314564Sdim PrintExpr(Node->getSubExpr()); 1519314564Sdim OS << "}"; 1520314564Sdim} 1521314564Sdim 1522314564Sdimvoid StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) { 1523314564Sdim OS << "*"; 1524314564Sdim} 1525314564Sdim 1526198092Srdivackyvoid StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 1527288943Sdim OS << "("; 1528198092Srdivacky for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 1529198092Srdivacky if (i) OS << ", "; 1530198092Srdivacky PrintExpr(Node->getExpr(i)); 1531198092Srdivacky } 1532288943Sdim OS << ")"; 1533198092Srdivacky} 1534198092Srdivacky 1535193326Sedvoid StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 1536288943Sdim bool NeedsEquals = true; 1537309124Sdim for (const DesignatedInitExpr::Designator &D : Node->designators()) { 1538309124Sdim if (D.isFieldDesignator()) { 1539309124Sdim if (D.getDotLoc().isInvalid()) { 1540309124Sdim if (IdentifierInfo *II = D.getFieldName()) { 1541276479Sdim OS << II->getName() << ":"; 1542288943Sdim NeedsEquals = false; 1543288943Sdim } 1544276479Sdim } else { 1545309124Sdim OS << "." << D.getFieldName()->getName(); 1546276479Sdim } 1547193326Sed } else { 1548193326Sed OS << "["; 1549309124Sdim if (D.isArrayDesignator()) { 1550309124Sdim PrintExpr(Node->getArrayIndex(D)); 1551193326Sed } else { 1552309124Sdim PrintExpr(Node->getArrayRangeStart(D)); 1553193326Sed OS << " ... "; 1554309124Sdim PrintExpr(Node->getArrayRangeEnd(D)); 1555193326Sed } 1556193326Sed OS << "]"; 1557193326Sed } 1558193326Sed } 1559193326Sed 1560288943Sdim if (NeedsEquals) 1561288943Sdim OS << " = "; 1562288943Sdim else 1563288943Sdim OS << " "; 1564193326Sed PrintExpr(Node->getInit()); 1565193326Sed} 1566193326Sed 1567288943Sdimvoid StmtPrinter::VisitDesignatedInitUpdateExpr( 1568288943Sdim DesignatedInitUpdateExpr *Node) { 1569288943Sdim OS << "{"; 1570288943Sdim OS << "/*base*/"; 1571288943Sdim PrintExpr(Node->getBase()); 1572288943Sdim OS << ", "; 1573288943Sdim 1574288943Sdim OS << "/*updater*/"; 1575288943Sdim PrintExpr(Node->getUpdater()); 1576288943Sdim OS << "}"; 1577288943Sdim} 1578288943Sdim 1579288943Sdimvoid StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) { 1580288943Sdim OS << "/*no init*/"; 1581288943Sdim} 1582288943Sdim 1583193326Sedvoid StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 1584309124Sdim if (Node->getType()->getAsCXXRecordDecl()) { 1585249423Sdim OS << "/*implicit*/"; 1586249423Sdim Node->getType().print(OS, Policy); 1587249423Sdim OS << "()"; 1588249423Sdim } else { 1589249423Sdim OS << "/*implicit*/("; 1590249423Sdim Node->getType().print(OS, Policy); 1591249423Sdim OS << ')'; 1592193326Sed if (Node->getType()->isRecordType()) 1593193326Sed OS << "{}"; 1594193326Sed else 1595193326Sed OS << 0; 1596193326Sed } 1597193326Sed} 1598193326Sed 1599193326Sedvoid StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 1600193326Sed OS << "__builtin_va_arg("; 1601193326Sed PrintExpr(Node->getSubExpr()); 1602193326Sed OS << ", "; 1603249423Sdim Node->getType().print(OS, Policy); 1604193326Sed OS << ")"; 1605193326Sed} 1606193326Sed 1607234353Sdimvoid StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { 1608234353Sdim PrintExpr(Node->getSyntacticForm()); 1609234353Sdim} 1610234353Sdim 1611226633Sdimvoid StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { 1612276479Sdim const char *Name = nullptr; 1613226633Sdim switch (Node->getOp()) { 1614234353Sdim#define BUILTIN(ID, TYPE, ATTRS) 1615234353Sdim#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 1616234353Sdim case AtomicExpr::AO ## ID: \ 1617234353Sdim Name = #ID "("; \ 1618234353Sdim break; 1619234353Sdim#include "clang/Basic/Builtins.def" 1620226633Sdim } 1621226633Sdim OS << Name; 1622234353Sdim 1623234353Sdim // AtomicExpr stores its subexpressions in a permuted order. 1624226633Sdim PrintExpr(Node->getPtr()); 1625234353Sdim if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && 1626327952Sdim Node->getOp() != AtomicExpr::AO__atomic_load_n && 1627327952Sdim Node->getOp() != AtomicExpr::AO__opencl_atomic_load) { 1628251662Sdim OS << ", "; 1629226633Sdim PrintExpr(Node->getVal1()); 1630226633Sdim } 1631234353Sdim if (Node->getOp() == AtomicExpr::AO__atomic_exchange || 1632234353Sdim Node->isCmpXChg()) { 1633251662Sdim OS << ", "; 1634226633Sdim PrintExpr(Node->getVal2()); 1635226633Sdim } 1636234353Sdim if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange || 1637234353Sdim Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) { 1638251662Sdim OS << ", "; 1639234353Sdim PrintExpr(Node->getWeak()); 1640251662Sdim } 1641327952Sdim if (Node->getOp() != AtomicExpr::AO__c11_atomic_init && 1642327952Sdim Node->getOp() != AtomicExpr::AO__opencl_atomic_init) { 1643234353Sdim OS << ", "; 1644251662Sdim PrintExpr(Node->getOrder()); 1645234353Sdim } 1646226633Sdim if (Node->isCmpXChg()) { 1647226633Sdim OS << ", "; 1648226633Sdim PrintExpr(Node->getOrderFail()); 1649226633Sdim } 1650226633Sdim OS << ")"; 1651226633Sdim} 1652226633Sdim 1653193326Sed// C++ 1654193326Sedvoid StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 1655193326Sed OverloadedOperatorKind Kind = Node->getOperator(); 1656193326Sed if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 1657193326Sed if (Node->getNumArgs() == 1) { 1658353358Sdim OS << getOperatorSpelling(Kind) << ' '; 1659193326Sed PrintExpr(Node->getArg(0)); 1660193326Sed } else { 1661193326Sed PrintExpr(Node->getArg(0)); 1662353358Sdim OS << ' ' << getOperatorSpelling(Kind); 1663193326Sed } 1664243830Sdim } else if (Kind == OO_Arrow) { 1665243830Sdim PrintExpr(Node->getArg(0)); 1666193326Sed } else if (Kind == OO_Call) { 1667193326Sed PrintExpr(Node->getArg(0)); 1668193326Sed OS << '('; 1669193326Sed for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 1670193326Sed if (ArgIdx > 1) 1671193326Sed OS << ", "; 1672193326Sed if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 1673193326Sed PrintExpr(Node->getArg(ArgIdx)); 1674193326Sed } 1675193326Sed OS << ')'; 1676193326Sed } else if (Kind == OO_Subscript) { 1677193326Sed PrintExpr(Node->getArg(0)); 1678193326Sed OS << '['; 1679193326Sed PrintExpr(Node->getArg(1)); 1680193326Sed OS << ']'; 1681193326Sed } else if (Node->getNumArgs() == 1) { 1682353358Sdim OS << getOperatorSpelling(Kind) << ' '; 1683193326Sed PrintExpr(Node->getArg(0)); 1684193326Sed } else if (Node->getNumArgs() == 2) { 1685193326Sed PrintExpr(Node->getArg(0)); 1686353358Sdim OS << ' ' << getOperatorSpelling(Kind) << ' '; 1687193326Sed PrintExpr(Node->getArg(1)); 1688193326Sed } else { 1689226633Sdim llvm_unreachable("unknown overloaded operator"); 1690193326Sed } 1691193326Sed} 1692193326Sed 1693193326Sedvoid StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 1694276479Sdim // If we have a conversion operator call only print the argument. 1695276479Sdim CXXMethodDecl *MD = Node->getMethodDecl(); 1696276479Sdim if (MD && isa<CXXConversionDecl>(MD)) { 1697276479Sdim PrintExpr(Node->getImplicitObjectArgument()); 1698276479Sdim return; 1699276479Sdim } 1700193326Sed VisitCallExpr(cast<CallExpr>(Node)); 1701193326Sed} 1702193326Sed 1703218893Sdimvoid StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 1704218893Sdim PrintExpr(Node->getCallee()); 1705218893Sdim OS << "<<<"; 1706218893Sdim PrintCallArgs(Node->getConfig()); 1707218893Sdim OS << ">>>("; 1708218893Sdim PrintCallArgs(Node); 1709218893Sdim OS << ")"; 1710218893Sdim} 1711218893Sdim 1712360784Sdimvoid StmtPrinter::VisitCXXRewrittenBinaryOperator( 1713360784Sdim CXXRewrittenBinaryOperator *Node) { 1714360784Sdim CXXRewrittenBinaryOperator::DecomposedForm Decomposed = 1715360784Sdim Node->getDecomposedForm(); 1716360784Sdim PrintExpr(const_cast<Expr*>(Decomposed.LHS)); 1717360784Sdim OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' '; 1718360784Sdim PrintExpr(const_cast<Expr*>(Decomposed.RHS)); 1719360784Sdim} 1720360784Sdim 1721193326Sedvoid StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 1722193326Sed OS << Node->getCastName() << '<'; 1723249423Sdim Node->getTypeAsWritten().print(OS, Policy); 1724249423Sdim OS << ">("; 1725193326Sed PrintExpr(Node->getSubExpr()); 1726193326Sed OS << ")"; 1727193326Sed} 1728193326Sed 1729193326Sedvoid StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 1730193326Sed VisitCXXNamedCastExpr(Node); 1731193326Sed} 1732193326Sed 1733193326Sedvoid StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 1734193326Sed VisitCXXNamedCastExpr(Node); 1735193326Sed} 1736193326Sed 1737193326Sedvoid StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 1738193326Sed VisitCXXNamedCastExpr(Node); 1739193326Sed} 1740193326Sed 1741193326Sedvoid StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 1742193326Sed VisitCXXNamedCastExpr(Node); 1743193326Sed} 1744193326Sed 1745353358Sdimvoid StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) { 1746353358Sdim OS << "__builtin_bit_cast("; 1747353358Sdim Node->getTypeInfoAsWritten()->getType().print(OS, Policy); 1748353358Sdim OS << ", "; 1749353358Sdim PrintExpr(Node->getSubExpr()); 1750353358Sdim OS << ")"; 1751353358Sdim} 1752353358Sdim 1753193326Sedvoid StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 1754193326Sed OS << "typeid("; 1755193326Sed if (Node->isTypeOperand()) { 1756261991Sdim Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 1757193326Sed } else { 1758193326Sed PrintExpr(Node->getExprOperand()); 1759193326Sed } 1760193326Sed OS << ")"; 1761193326Sed} 1762193326Sed 1763218893Sdimvoid StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 1764218893Sdim OS << "__uuidof("; 1765218893Sdim if (Node->isTypeOperand()) { 1766261991Sdim Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 1767218893Sdim } else { 1768218893Sdim PrintExpr(Node->getExprOperand()); 1769218893Sdim } 1770218893Sdim OS << ")"; 1771218893Sdim} 1772218893Sdim 1773251662Sdimvoid StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) { 1774251662Sdim PrintExpr(Node->getBaseExpr()); 1775251662Sdim if (Node->isArrow()) 1776251662Sdim OS << "->"; 1777251662Sdim else 1778251662Sdim OS << "."; 1779251662Sdim if (NestedNameSpecifier *Qualifier = 1780251662Sdim Node->getQualifierLoc().getNestedNameSpecifier()) 1781251662Sdim Qualifier->print(OS, Policy); 1782251662Sdim OS << Node->getPropertyDecl()->getDeclName(); 1783251662Sdim} 1784251662Sdim 1785296417Sdimvoid StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) { 1786296417Sdim PrintExpr(Node->getBase()); 1787296417Sdim OS << "["; 1788296417Sdim PrintExpr(Node->getIdx()); 1789296417Sdim OS << "]"; 1790296417Sdim} 1791296417Sdim 1792234353Sdimvoid StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { 1793234353Sdim switch (Node->getLiteralOperatorKind()) { 1794234353Sdim case UserDefinedLiteral::LOK_Raw: 1795234353Sdim OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString(); 1796234353Sdim break; 1797234353Sdim case UserDefinedLiteral::LOK_Template: { 1798341825Sdim const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts()); 1799234353Sdim const TemplateArgumentList *Args = 1800234353Sdim cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs(); 1801234353Sdim assert(Args); 1802288943Sdim 1803288943Sdim if (Args->size() != 1) { 1804296417Sdim OS << "operator\"\"" << Node->getUDSuffix()->getName(); 1805327952Sdim printTemplateArgumentList(OS, Args->asArray(), Policy); 1806288943Sdim OS << "()"; 1807288943Sdim return; 1808288943Sdim } 1809288943Sdim 1810234353Sdim const TemplateArgument &Pack = Args->get(0); 1811276479Sdim for (const auto &P : Pack.pack_elements()) { 1812276479Sdim char C = (char)P.getAsIntegral().getZExtValue(); 1813234353Sdim OS << C; 1814234353Sdim } 1815234353Sdim break; 1816234353Sdim } 1817234353Sdim case UserDefinedLiteral::LOK_Integer: { 1818234353Sdim // Print integer literal without suffix. 1819341825Sdim const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral()); 1820234353Sdim OS << Int->getValue().toString(10, /*isSigned*/false); 1821234353Sdim break; 1822234353Sdim } 1823243830Sdim case UserDefinedLiteral::LOK_Floating: { 1824243830Sdim // Print floating literal without suffix. 1825341825Sdim auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral()); 1826243830Sdim PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false); 1827243830Sdim break; 1828243830Sdim } 1829234353Sdim case UserDefinedLiteral::LOK_String: 1830234353Sdim case UserDefinedLiteral::LOK_Character: 1831234353Sdim PrintExpr(Node->getCookedLiteral()); 1832234353Sdim break; 1833234353Sdim } 1834234353Sdim OS << Node->getUDSuffix()->getName(); 1835234353Sdim} 1836234353Sdim 1837193326Sedvoid StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1838193326Sed OS << (Node->getValue() ? "true" : "false"); 1839193326Sed} 1840193326Sed 1841193326Sedvoid StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1842193326Sed OS << "nullptr"; 1843193326Sed} 1844193326Sed 1845193326Sedvoid StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1846193326Sed OS << "this"; 1847193326Sed} 1848193326Sed 1849193326Sedvoid StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1850276479Sdim if (!Node->getSubExpr()) 1851193326Sed OS << "throw"; 1852193326Sed else { 1853193326Sed OS << "throw "; 1854193326Sed PrintExpr(Node->getSubExpr()); 1855193326Sed } 1856193326Sed} 1857193326Sed 1858193326Sedvoid StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1859251662Sdim // Nothing to print: we picked up the default argument. 1860193326Sed} 1861193326Sed 1862251662Sdimvoid StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) { 1863251662Sdim // Nothing to print: we picked up the default initializer. 1864251662Sdim} 1865251662Sdim 1866193326Sedvoid StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1867249423Sdim Node->getType().print(OS, Policy); 1868288943Sdim // If there are no parens, this is list-initialization, and the braces are 1869288943Sdim // part of the syntax of the inner construct. 1870288943Sdim if (Node->getLParenLoc().isValid()) 1871288943Sdim OS << "("; 1872193326Sed PrintExpr(Node->getSubExpr()); 1873288943Sdim if (Node->getLParenLoc().isValid()) 1874288943Sdim OS << ")"; 1875193326Sed} 1876193326Sed 1877193326Sedvoid StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1878193326Sed PrintExpr(Node->getSubExpr()); 1879193326Sed} 1880193326Sed 1881193326Sedvoid StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1882249423Sdim Node->getType().print(OS, Policy); 1883288943Sdim if (Node->isStdInitListInitialization()) 1884288943Sdim /* Nothing to do; braces are part of creating the std::initializer_list. */; 1885288943Sdim else if (Node->isListInitialization()) 1886288943Sdim OS << "{"; 1887288943Sdim else 1888288943Sdim OS << "("; 1889193326Sed for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1890198092Srdivacky ArgEnd = Node->arg_end(); 1891193326Sed Arg != ArgEnd; ++Arg) { 1892296417Sdim if ((*Arg)->isDefaultArgument()) 1893261991Sdim break; 1894193326Sed if (Arg != Node->arg_begin()) 1895193326Sed OS << ", "; 1896193326Sed PrintExpr(*Arg); 1897193326Sed } 1898288943Sdim if (Node->isStdInitListInitialization()) 1899288943Sdim /* See above. */; 1900288943Sdim else if (Node->isListInitialization()) 1901288943Sdim OS << "}"; 1902288943Sdim else 1903288943Sdim OS << ")"; 1904193326Sed} 1905193326Sed 1906234353Sdimvoid StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { 1907234353Sdim OS << '['; 1908234353Sdim bool NeedComma = false; 1909234353Sdim switch (Node->getCaptureDefault()) { 1910234353Sdim case LCD_None: 1911234353Sdim break; 1912234353Sdim 1913234353Sdim case LCD_ByCopy: 1914234353Sdim OS << '='; 1915234353Sdim NeedComma = true; 1916234353Sdim break; 1917234353Sdim 1918234353Sdim case LCD_ByRef: 1919234353Sdim OS << '&'; 1920234353Sdim NeedComma = true; 1921234353Sdim break; 1922234353Sdim } 1923234353Sdim for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(), 1924234353Sdim CEnd = Node->explicit_capture_end(); 1925234353Sdim C != CEnd; 1926234353Sdim ++C) { 1927327952Sdim if (C->capturesVLAType()) 1928327952Sdim continue; 1929327952Sdim 1930234353Sdim if (NeedComma) 1931234353Sdim OS << ", "; 1932234353Sdim NeedComma = true; 1933234353Sdim 1934234353Sdim switch (C->getCaptureKind()) { 1935234353Sdim case LCK_This: 1936234353Sdim OS << "this"; 1937234353Sdim break; 1938341825Sdim 1939309124Sdim case LCK_StarThis: 1940309124Sdim OS << "*this"; 1941309124Sdim break; 1942341825Sdim 1943234353Sdim case LCK_ByRef: 1944288943Sdim if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C)) 1945234353Sdim OS << '&'; 1946234353Sdim OS << C->getCapturedVar()->getName(); 1947234353Sdim break; 1948234353Sdim 1949234353Sdim case LCK_ByCopy: 1950234353Sdim OS << C->getCapturedVar()->getName(); 1951234353Sdim break; 1952341825Sdim 1953280031Sdim case LCK_VLAType: 1954280031Sdim llvm_unreachable("VLA type in explicit captures."); 1955234353Sdim } 1956261991Sdim 1957353358Sdim if (C->isPackExpansion()) 1958353358Sdim OS << "..."; 1959353358Sdim 1960288943Sdim if (Node->isInitCapture(C)) 1961261991Sdim PrintExpr(C->getCapturedVar()->getInit()); 1962234353Sdim } 1963234353Sdim OS << ']'; 1964234353Sdim 1965353358Sdim if (!Node->getExplicitTemplateParameters().empty()) { 1966353358Sdim Node->getTemplateParameterList()->print( 1967353358Sdim OS, Node->getLambdaClass()->getASTContext(), 1968353358Sdim /*OmitTemplateKW*/true); 1969353358Sdim } 1970353358Sdim 1971234353Sdim if (Node->hasExplicitParameters()) { 1972353358Sdim OS << '('; 1973234353Sdim CXXMethodDecl *Method = Node->getCallOperator(); 1974234353Sdim NeedComma = false; 1975341825Sdim for (const auto *P : Method->parameters()) { 1976234353Sdim if (NeedComma) { 1977234353Sdim OS << ", "; 1978234353Sdim } else { 1979234353Sdim NeedComma = true; 1980234353Sdim } 1981276479Sdim std::string ParamStr = P->getNameAsString(); 1982276479Sdim P->getOriginalType().print(OS, Policy, ParamStr); 1983234353Sdim } 1984234353Sdim if (Method->isVariadic()) { 1985234353Sdim if (NeedComma) 1986234353Sdim OS << ", "; 1987234353Sdim OS << "..."; 1988234353Sdim } 1989234353Sdim OS << ')'; 1990234353Sdim 1991234353Sdim if (Node->isMutable()) 1992234353Sdim OS << " mutable"; 1993234353Sdim 1994360784Sdim auto *Proto = Method->getType()->castAs<FunctionProtoType>(); 1995249423Sdim Proto->printExceptionSpecification(OS, Policy); 1996234353Sdim 1997234353Sdim // FIXME: Attributes 1998234353Sdim 1999234353Sdim // Print the trailing return type if it was specified in the source. 2000249423Sdim if (Node->hasExplicitResultType()) { 2001249423Sdim OS << " -> "; 2002276479Sdim Proto->getReturnType().print(OS, Policy); 2003249423Sdim } 2004234353Sdim } 2005234353Sdim 2006234353Sdim // Print the body. 2007234353Sdim OS << ' '; 2008353358Sdim if (Policy.TerseOutput) 2009353358Sdim OS << "{}"; 2010353358Sdim else 2011353358Sdim PrintRawCompoundStmt(Node->getBody()); 2012234353Sdim} 2013234353Sdim 2014210299Sedvoid StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 2015218893Sdim if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 2016249423Sdim TSInfo->getType().print(OS, Policy); 2017218893Sdim else 2018249423Sdim Node->getType().print(OS, Policy); 2019249423Sdim OS << "()"; 2020193326Sed} 2021193326Sed 2022193326Sedvoid StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 2023193326Sed if (E->isGlobalNew()) 2024193326Sed OS << "::"; 2025193326Sed OS << "new "; 2026193326Sed unsigned NumPlace = E->getNumPlacementArgs(); 2027243830Sdim if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) { 2028193326Sed OS << "("; 2029193326Sed PrintExpr(E->getPlacementArg(0)); 2030193326Sed for (unsigned i = 1; i < NumPlace; ++i) { 2031243830Sdim if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i))) 2032243830Sdim break; 2033193326Sed OS << ", "; 2034193326Sed PrintExpr(E->getPlacementArg(i)); 2035193326Sed } 2036193326Sed OS << ") "; 2037193326Sed } 2038193326Sed if (E->isParenTypeId()) 2039193326Sed OS << "("; 2040193326Sed std::string TypeS; 2041353358Sdim if (Optional<Expr *> Size = E->getArraySize()) { 2042193326Sed llvm::raw_string_ostream s(TypeS); 2043249423Sdim s << '['; 2044353358Sdim if (*Size) 2045353358Sdim (*Size)->printPretty(s, Helper, Policy); 2046249423Sdim s << ']'; 2047193326Sed } 2048249423Sdim E->getAllocatedType().print(OS, Policy, TypeS); 2049193326Sed if (E->isParenTypeId()) 2050193326Sed OS << ")"; 2051193326Sed 2052234353Sdim CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle(); 2053234353Sdim if (InitStyle) { 2054234353Sdim if (InitStyle == CXXNewExpr::CallInit) 2055234353Sdim OS << "("; 2056234353Sdim PrintExpr(E->getInitializer()); 2057234353Sdim if (InitStyle == CXXNewExpr::CallInit) 2058234353Sdim OS << ")"; 2059193326Sed } 2060193326Sed} 2061193326Sed 2062193326Sedvoid StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 2063193326Sed if (E->isGlobalDelete()) 2064193326Sed OS << "::"; 2065193326Sed OS << "delete "; 2066193326Sed if (E->isArrayForm()) 2067193326Sed OS << "[] "; 2068193326Sed PrintExpr(E->getArgument()); 2069193326Sed} 2070193326Sed 2071198092Srdivackyvoid StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 2072198092Srdivacky PrintExpr(E->getBase()); 2073198092Srdivacky if (E->isArrow()) 2074198092Srdivacky OS << "->"; 2075198092Srdivacky else 2076198092Srdivacky OS << '.'; 2077198092Srdivacky if (E->getQualifier()) 2078198092Srdivacky E->getQualifier()->print(OS, Policy); 2079243830Sdim OS << "~"; 2080198092Srdivacky 2081204643Srdivacky if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 2082204643Srdivacky OS << II->getName(); 2083204643Srdivacky else 2084249423Sdim E->getDestroyedType().print(OS, Policy); 2085198092Srdivacky} 2086198092Srdivacky 2087193326Sedvoid StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 2088288943Sdim if (E->isListInitialization() && !E->isStdInitListInitialization()) 2089288943Sdim OS << "{"; 2090249423Sdim 2091218893Sdim for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 2092218893Sdim if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 2093218893Sdim // Don't print any defaulted arguments 2094218893Sdim break; 2095218893Sdim } 2096218893Sdim 2097218893Sdim if (i) OS << ", "; 2098218893Sdim PrintExpr(E->getArg(i)); 2099202379Srdivacky } 2100249423Sdim 2101288943Sdim if (E->isListInitialization() && !E->isStdInitListInitialization()) 2102288943Sdim OS << "}"; 2103193326Sed} 2104193326Sed 2105309124Sdimvoid StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) { 2106309124Sdim // Parens are printed by the surrounding context. 2107309124Sdim OS << "<forwarded>"; 2108309124Sdim} 2109309124Sdim 2110261991Sdimvoid StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { 2111261991Sdim PrintExpr(E->getSubExpr()); 2112261991Sdim} 2113261991Sdim 2114218893Sdimvoid StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 2115276479Sdim // Just forward to the subexpression. 2116193326Sed PrintExpr(E->getSubExpr()); 2117193326Sed} 2118193326Sed 2119198092Srdivackyvoid 2120193326SedStmtPrinter::VisitCXXUnresolvedConstructExpr( 2121193326Sed CXXUnresolvedConstructExpr *Node) { 2122249423Sdim Node->getTypeAsWritten().print(OS, Policy); 2123193326Sed OS << "("; 2124193326Sed for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 2125198092Srdivacky ArgEnd = Node->arg_end(); 2126193326Sed Arg != ArgEnd; ++Arg) { 2127193326Sed if (Arg != Node->arg_begin()) 2128193326Sed OS << ", "; 2129193326Sed PrintExpr(*Arg); 2130193326Sed } 2131193326Sed OS << ")"; 2132193326Sed} 2133193326Sed 2134199990Srdivackyvoid StmtPrinter::VisitCXXDependentScopeMemberExpr( 2135199990Srdivacky CXXDependentScopeMemberExpr *Node) { 2136200583Srdivacky if (!Node->isImplicitAccess()) { 2137200583Srdivacky PrintExpr(Node->getBase()); 2138200583Srdivacky OS << (Node->isArrow() ? "->" : "."); 2139200583Srdivacky } 2140198092Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 2141198092Srdivacky Qualifier->print(OS, Policy); 2142234353Sdim if (Node->hasTemplateKeyword()) 2143198092Srdivacky OS << "template "; 2144212904Sdim OS << Node->getMemberNameInfo(); 2145249423Sdim if (Node->hasExplicitTemplateArgs()) 2146327952Sdim printTemplateArgumentList(OS, Node->template_arguments(), Policy); 2147193326Sed} 2148193326Sed 2149199990Srdivackyvoid StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 2150200583Srdivacky if (!Node->isImplicitAccess()) { 2151200583Srdivacky PrintExpr(Node->getBase()); 2152200583Srdivacky OS << (Node->isArrow() ? "->" : "."); 2153200583Srdivacky } 2154199990Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 2155199990Srdivacky Qualifier->print(OS, Policy); 2156234353Sdim if (Node->hasTemplateKeyword()) 2157234353Sdim OS << "template "; 2158212904Sdim OS << Node->getMemberNameInfo(); 2159249423Sdim if (Node->hasExplicitTemplateArgs()) 2160327952Sdim printTemplateArgumentList(OS, Node->template_arguments(), Policy); 2161199990Srdivacky} 2162199990Srdivacky 2163234353Sdimstatic const char *getTypeTraitName(TypeTrait TT) { 2164234353Sdim switch (TT) { 2165276479Sdim#define TYPE_TRAIT_1(Spelling, Name, Key) \ 2166276479Sdimcase clang::UTT_##Name: return #Spelling; 2167276479Sdim#define TYPE_TRAIT_2(Spelling, Name, Key) \ 2168276479Sdimcase clang::BTT_##Name: return #Spelling; 2169276479Sdim#define TYPE_TRAIT_N(Spelling, Name, Key) \ 2170276479Sdim case clang::TT_##Name: return #Spelling; 2171276479Sdim#include "clang/Basic/TokenKinds.def" 2172234353Sdim } 2173234353Sdim llvm_unreachable("Type trait not covered by switch"); 2174234353Sdim} 2175234353Sdim 2176221345Sdimstatic const char *getTypeTraitName(ArrayTypeTrait ATT) { 2177221345Sdim switch (ATT) { 2178221345Sdim case ATT_ArrayRank: return "__array_rank"; 2179221345Sdim case ATT_ArrayExtent: return "__array_extent"; 2180221345Sdim } 2181221345Sdim llvm_unreachable("Array type trait not covered by switch"); 2182221345Sdim} 2183221345Sdim 2184221345Sdimstatic const char *getExpressionTraitName(ExpressionTrait ET) { 2185221345Sdim switch (ET) { 2186221345Sdim case ET_IsLValueExpr: return "__is_lvalue_expr"; 2187221345Sdim case ET_IsRValueExpr: return "__is_rvalue_expr"; 2188221345Sdim } 2189221345Sdim llvm_unreachable("Expression type trait not covered by switch"); 2190221345Sdim} 2191221345Sdim 2192234353Sdimvoid StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) { 2193234353Sdim OS << getTypeTraitName(E->getTrait()) << "("; 2194234353Sdim for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { 2195234353Sdim if (I > 0) 2196234353Sdim OS << ", "; 2197249423Sdim E->getArg(I)->getType().print(OS, Policy); 2198234353Sdim } 2199234353Sdim OS << ")"; 2200234353Sdim} 2201234353Sdim 2202221345Sdimvoid StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 2203249423Sdim OS << getTypeTraitName(E->getTrait()) << '('; 2204249423Sdim E->getQueriedType().print(OS, Policy); 2205249423Sdim OS << ')'; 2206221345Sdim} 2207221345Sdim 2208221345Sdimvoid StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { 2209249423Sdim OS << getExpressionTraitName(E->getTrait()) << '('; 2210249423Sdim PrintExpr(E->getQueriedExpression()); 2211249423Sdim OS << ')'; 2212221345Sdim} 2213221345Sdim 2214218893Sdimvoid StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 2215218893Sdim OS << "noexcept("; 2216218893Sdim PrintExpr(E->getOperand()); 2217218893Sdim OS << ")"; 2218218893Sdim} 2219218893Sdim 2220218893Sdimvoid StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 2221218893Sdim PrintExpr(E->getPattern()); 2222218893Sdim OS << "..."; 2223218893Sdim} 2224218893Sdim 2225218893Sdimvoid StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 2226234353Sdim OS << "sizeof...(" << *E->getPack() << ")"; 2227218893Sdim} 2228218893Sdim 2229218893Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 2230218893Sdim SubstNonTypeTemplateParmPackExpr *Node) { 2231234353Sdim OS << *Node->getParameterPack(); 2232218893Sdim} 2233218893Sdim 2234224145Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmExpr( 2235224145Sdim SubstNonTypeTemplateParmExpr *Node) { 2236224145Sdim Visit(Node->getReplacement()); 2237224145Sdim} 2238224145Sdim 2239243830Sdimvoid StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { 2240243830Sdim OS << *E->getParameterPack(); 2241243830Sdim} 2242243830Sdim 2243224145Sdimvoid StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){ 2244360784Sdim PrintExpr(Node->getSubExpr()); 2245224145Sdim} 2246224145Sdim 2247280031Sdimvoid StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) { 2248280031Sdim OS << "("; 2249280031Sdim if (E->getLHS()) { 2250280031Sdim PrintExpr(E->getLHS()); 2251280031Sdim OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 2252280031Sdim } 2253280031Sdim OS << "..."; 2254280031Sdim if (E->getRHS()) { 2255280031Sdim OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 2256280031Sdim PrintExpr(E->getRHS()); 2257280031Sdim } 2258280031Sdim OS << ")"; 2259280031Sdim} 2260280031Sdim 2261360784Sdimvoid StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) { 2262360784Sdim NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc(); 2263360784Sdim if (NNS) 2264360784Sdim NNS.getNestedNameSpecifier()->print(OS, Policy); 2265360784Sdim if (E->getTemplateKWLoc().isValid()) 2266360784Sdim OS << "template "; 2267360784Sdim OS << E->getFoundDecl()->getName(); 2268360784Sdim printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(), 2269360784Sdim Policy); 2270360784Sdim} 2271360784Sdim 2272360784Sdimvoid StmtPrinter::VisitRequiresExpr(RequiresExpr *E) { 2273360784Sdim OS << "requires "; 2274360784Sdim auto LocalParameters = E->getLocalParameters(); 2275360784Sdim if (!LocalParameters.empty()) { 2276360784Sdim OS << "("; 2277360784Sdim for (ParmVarDecl *LocalParam : LocalParameters) { 2278360784Sdim PrintRawDecl(LocalParam); 2279360784Sdim if (LocalParam != LocalParameters.back()) 2280360784Sdim OS << ", "; 2281360784Sdim } 2282360784Sdim 2283360784Sdim OS << ") "; 2284360784Sdim } 2285360784Sdim OS << "{ "; 2286360784Sdim auto Requirements = E->getRequirements(); 2287360784Sdim for (concepts::Requirement *Req : Requirements) { 2288360784Sdim if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) { 2289360784Sdim if (TypeReq->isSubstitutionFailure()) 2290360784Sdim OS << "<<error-type>>"; 2291360784Sdim else 2292360784Sdim TypeReq->getType()->getType().print(OS, Policy); 2293360784Sdim } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) { 2294360784Sdim if (ExprReq->isCompound()) 2295360784Sdim OS << "{ "; 2296360784Sdim if (ExprReq->isExprSubstitutionFailure()) 2297360784Sdim OS << "<<error-expression>>"; 2298360784Sdim else 2299360784Sdim PrintExpr(ExprReq->getExpr()); 2300360784Sdim if (ExprReq->isCompound()) { 2301360784Sdim OS << " }"; 2302360784Sdim if (ExprReq->getNoexceptLoc().isValid()) 2303360784Sdim OS << " noexcept"; 2304360784Sdim const auto &RetReq = ExprReq->getReturnTypeRequirement(); 2305360784Sdim if (!RetReq.isEmpty()) { 2306360784Sdim OS << " -> "; 2307360784Sdim if (RetReq.isSubstitutionFailure()) 2308360784Sdim OS << "<<error-type>>"; 2309360784Sdim else if (RetReq.isTypeConstraint()) 2310360784Sdim RetReq.getTypeConstraint()->print(OS, Policy); 2311360784Sdim } 2312360784Sdim } 2313360784Sdim } else { 2314360784Sdim auto *NestedReq = cast<concepts::NestedRequirement>(Req); 2315360784Sdim OS << "requires "; 2316360784Sdim if (NestedReq->isSubstitutionFailure()) 2317360784Sdim OS << "<<error-expression>>"; 2318360784Sdim else 2319360784Sdim PrintExpr(NestedReq->getConstraintExpr()); 2320360784Sdim } 2321360784Sdim OS << "; "; 2322360784Sdim } 2323360784Sdim OS << "}"; 2324360784Sdim} 2325360784Sdim 2326296417Sdim// C++ Coroutines TS 2327296417Sdim 2328296417Sdimvoid StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) { 2329296417Sdim Visit(S->getBody()); 2330296417Sdim} 2331296417Sdim 2332296417Sdimvoid StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) { 2333296417Sdim OS << "co_return"; 2334296417Sdim if (S->getOperand()) { 2335296417Sdim OS << " "; 2336296417Sdim Visit(S->getOperand()); 2337296417Sdim } 2338296417Sdim OS << ";"; 2339296417Sdim} 2340296417Sdim 2341296417Sdimvoid StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) { 2342296417Sdim OS << "co_await "; 2343296417Sdim PrintExpr(S->getOperand()); 2344296417Sdim} 2345296417Sdim 2346321369Sdimvoid StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) { 2347321369Sdim OS << "co_await "; 2348321369Sdim PrintExpr(S->getOperand()); 2349321369Sdim} 2350321369Sdim 2351296417Sdimvoid StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) { 2352296417Sdim OS << "co_yield "; 2353296417Sdim PrintExpr(S->getOperand()); 2354296417Sdim} 2355296417Sdim 2356198092Srdivacky// Obj-C 2357193326Sed 2358193326Sedvoid StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 2359193326Sed OS << "@"; 2360193326Sed VisitStringLiteral(Node->getString()); 2361193326Sed} 2362193326Sed 2363239462Sdimvoid StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 2364234353Sdim OS << "@"; 2365239462Sdim Visit(E->getSubExpr()); 2366234353Sdim} 2367234353Sdim 2368234353Sdimvoid StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 2369234353Sdim OS << "@[ "; 2370296417Sdim ObjCArrayLiteral::child_range Ch = E->children(); 2371296417Sdim for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) { 2372296417Sdim if (I != Ch.begin()) 2373234353Sdim OS << ", "; 2374296417Sdim Visit(*I); 2375234353Sdim } 2376234353Sdim OS << " ]"; 2377234353Sdim} 2378234353Sdim 2379234353Sdimvoid StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 2380234353Sdim OS << "@{ "; 2381234353Sdim for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { 2382234353Sdim if (I > 0) 2383234353Sdim OS << ", "; 2384341825Sdim 2385234353Sdim ObjCDictionaryElement Element = E->getKeyValueElement(I); 2386234353Sdim Visit(Element.Key); 2387234353Sdim OS << " : "; 2388234353Sdim Visit(Element.Value); 2389234353Sdim if (Element.isPackExpansion()) 2390234353Sdim OS << "..."; 2391234353Sdim } 2392234353Sdim OS << " }"; 2393234353Sdim} 2394234353Sdim 2395193326Sedvoid StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 2396249423Sdim OS << "@encode("; 2397249423Sdim Node->getEncodedType().print(OS, Policy); 2398249423Sdim OS << ')'; 2399193326Sed} 2400193326Sed 2401193326Sedvoid StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 2402276479Sdim OS << "@selector("; 2403276479Sdim Node->getSelector().print(OS); 2404276479Sdim OS << ')'; 2405193326Sed} 2406193326Sed 2407193326Sedvoid StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 2408226633Sdim OS << "@protocol(" << *Node->getProtocol() << ')'; 2409193326Sed} 2410193326Sed 2411193326Sedvoid StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 2412193326Sed OS << "["; 2413207619Srdivacky switch (Mess->getReceiverKind()) { 2414207619Srdivacky case ObjCMessageExpr::Instance: 2415207619Srdivacky PrintExpr(Mess->getInstanceReceiver()); 2416207619Srdivacky break; 2417207619Srdivacky 2418207619Srdivacky case ObjCMessageExpr::Class: 2419249423Sdim Mess->getClassReceiver().print(OS, Policy); 2420207619Srdivacky break; 2421207619Srdivacky 2422207619Srdivacky case ObjCMessageExpr::SuperInstance: 2423207619Srdivacky case ObjCMessageExpr::SuperClass: 2424207619Srdivacky OS << "Super"; 2425207619Srdivacky break; 2426207619Srdivacky } 2427207619Srdivacky 2428193326Sed OS << ' '; 2429193326Sed Selector selector = Mess->getSelector(); 2430193326Sed if (selector.isUnarySelector()) { 2431218893Sdim OS << selector.getNameForSlot(0); 2432193326Sed } else { 2433193326Sed for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 2434193326Sed if (i < selector.getNumArgs()) { 2435193326Sed if (i > 0) OS << ' '; 2436193326Sed if (selector.getIdentifierInfoForSlot(i)) 2437193326Sed OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 2438193326Sed else 2439193326Sed OS << ":"; 2440193326Sed } 2441193326Sed else OS << ", "; // Handle variadic methods. 2442198092Srdivacky 2443193326Sed PrintExpr(Mess->getArg(i)); 2444193326Sed } 2445193326Sed } 2446193326Sed OS << "]"; 2447193326Sed} 2448193326Sed 2449234353Sdimvoid StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { 2450234353Sdim OS << (Node->getValue() ? "__objc_yes" : "__objc_no"); 2451234353Sdim} 2452234353Sdim 2453224145Sdimvoid 2454224145SdimStmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { 2455224145Sdim PrintExpr(E->getSubExpr()); 2456224145Sdim} 2457193326Sed 2458224145Sdimvoid 2459224145SdimStmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { 2460249423Sdim OS << '(' << E->getBridgeKindName(); 2461249423Sdim E->getType().print(OS, Policy); 2462249423Sdim OS << ')'; 2463224145Sdim PrintExpr(E->getSubExpr()); 2464224145Sdim} 2465224145Sdim 2466193326Sedvoid StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 2467193326Sed BlockDecl *BD = Node->getBlockDecl(); 2468193326Sed OS << "^"; 2469198092Srdivacky 2470193326Sed const FunctionType *AFT = Node->getFunctionType(); 2471198092Srdivacky 2472193326Sed if (isa<FunctionNoProtoType>(AFT)) { 2473193326Sed OS << "()"; 2474193326Sed } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 2475193326Sed OS << '('; 2476193326Sed for (BlockDecl::param_iterator AI = BD->param_begin(), 2477193326Sed E = BD->param_end(); AI != E; ++AI) { 2478193326Sed if (AI != BD->param_begin()) OS << ", "; 2479249423Sdim std::string ParamStr = (*AI)->getNameAsString(); 2480249423Sdim (*AI)->getType().print(OS, Policy, ParamStr); 2481193326Sed } 2482198092Srdivacky 2483341825Sdim const auto *FT = cast<FunctionProtoType>(AFT); 2484193326Sed if (FT->isVariadic()) { 2485193326Sed if (!BD->param_empty()) OS << ", "; 2486193326Sed OS << "..."; 2487193326Sed } 2488193326Sed OS << ')'; 2489193326Sed } 2490249423Sdim OS << "{ }"; 2491193326Sed} 2492193326Sed 2493341825Sdimvoid StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { 2494234353Sdim PrintExpr(Node->getSourceExpr()); 2495193326Sed} 2496218893Sdim 2497280031Sdimvoid StmtPrinter::VisitTypoExpr(TypoExpr *Node) { 2498280031Sdim // TODO: Print something reasonable for a TypoExpr, if necessary. 2499309124Sdim llvm_unreachable("Cannot print TypoExpr nodes"); 2500280031Sdim} 2501280031Sdim 2502223017Sdimvoid StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { 2503223017Sdim OS << "__builtin_astype("; 2504223017Sdim PrintExpr(Node->getSrcExpr()); 2505249423Sdim OS << ", "; 2506249423Sdim Node->getType().print(OS, Policy); 2507223017Sdim OS << ")"; 2508223017Sdim} 2509223017Sdim 2510193326Sed//===----------------------------------------------------------------------===// 2511193326Sed// Stmt method implementations 2512193326Sed//===----------------------------------------------------------------------===// 2513193326Sed 2514261991Sdimvoid Stmt::dumpPretty(const ASTContext &Context) const { 2515276479Sdim printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts())); 2516193326Sed} 2517193326Sed 2518353358Sdimvoid Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper, 2519327952Sdim const PrintingPolicy &Policy, unsigned Indentation, 2520353358Sdim StringRef NL, const ASTContext *Context) const { 2521353358Sdim StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context); 2522353358Sdim P.Visit(const_cast<Stmt *>(this)); 2523193326Sed} 2524193326Sed 2525353358Sdimvoid Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper, 2526353358Sdim const PrintingPolicy &Policy, bool AddQuotes) const { 2527353358Sdim std::string Buf; 2528353358Sdim llvm::raw_string_ostream TempOut(Buf); 2529353358Sdim 2530353358Sdim printPretty(TempOut, Helper, Policy); 2531353358Sdim 2532353358Sdim Out << JsonFormat(TempOut.str(), AddQuotes); 2533353358Sdim} 2534353358Sdim 2535193326Sed//===----------------------------------------------------------------------===// 2536193326Sed// PrinterHelper 2537193326Sed//===----------------------------------------------------------------------===// 2538193326Sed 2539193326Sed// Implement virtual destructor. 2540341825SdimPrinterHelper::~PrinterHelper() = default; 2541