StmtPrinter.cpp revision 327952
1//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which 11// pretty print the AST back out to C code. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/Attr.h" 17#include "clang/AST/DeclCXX.h" 18#include "clang/AST/DeclObjC.h" 19#include "clang/AST/DeclOpenMP.h" 20#include "clang/AST/DeclTemplate.h" 21#include "clang/AST/Expr.h" 22#include "clang/AST/ExprCXX.h" 23#include "clang/AST/ExprOpenMP.h" 24#include "clang/AST/PrettyPrinter.h" 25#include "clang/AST/StmtVisitor.h" 26#include "clang/Basic/CharInfo.h" 27#include "clang/Lex/Lexer.h" 28#include "llvm/ADT/SmallString.h" 29#include "llvm/Support/Format.h" 30using namespace clang; 31 32//===----------------------------------------------------------------------===// 33// StmtPrinter Visitor 34//===----------------------------------------------------------------------===// 35 36namespace { 37 class StmtPrinter : public StmtVisitor<StmtPrinter> { 38 raw_ostream &OS; 39 unsigned IndentLevel; 40 clang::PrinterHelper* Helper; 41 PrintingPolicy Policy; 42 const ASTContext *Context; 43 44 public: 45 StmtPrinter(raw_ostream &os, PrinterHelper *helper, 46 const PrintingPolicy &Policy, unsigned Indentation = 0, 47 const ASTContext *Context = nullptr) 48 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy), 49 Context(Context) {} 50 51 void PrintStmt(Stmt *S) { 52 PrintStmt(S, Policy.Indentation); 53 } 54 55 void PrintStmt(Stmt *S, int SubIndent) { 56 IndentLevel += SubIndent; 57 if (S && isa<Expr>(S)) { 58 // If this is an expr used in a stmt context, indent and newline it. 59 Indent(); 60 Visit(S); 61 OS << ";\n"; 62 } else if (S) { 63 Visit(S); 64 } else { 65 Indent() << "<<<NULL STATEMENT>>>\n"; 66 } 67 IndentLevel -= SubIndent; 68 } 69 70 void PrintRawCompoundStmt(CompoundStmt *S); 71 void PrintRawDecl(Decl *D); 72 void PrintRawDeclStmt(const DeclStmt *S); 73 void PrintRawIfStmt(IfStmt *If); 74 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 75 void PrintCallArgs(CallExpr *E); 76 void PrintRawSEHExceptHandler(SEHExceptStmt *S); 77 void PrintRawSEHFinallyStmt(SEHFinallyStmt *S); 78 void PrintOMPExecutableDirective(OMPExecutableDirective *S, 79 bool ForceNoStmt = false); 80 81 void PrintExpr(Expr *E) { 82 if (E) 83 Visit(E); 84 else 85 OS << "<null expr>"; 86 } 87 88 raw_ostream &Indent(int Delta = 0) { 89 for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 90 OS << " "; 91 return OS; 92 } 93 94 void Visit(Stmt* S) { 95 if (Helper && Helper->handledStmt(S,OS)) 96 return; 97 else StmtVisitor<StmtPrinter>::Visit(S); 98 } 99 100 void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 101 Indent() << "<<unknown stmt type>>\n"; 102 } 103 void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 104 OS << "<<unknown expr type>>"; 105 } 106 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 107 108#define ABSTRACT_STMT(CLASS) 109#define STMT(CLASS, PARENT) \ 110 void Visit##CLASS(CLASS *Node); 111#include "clang/AST/StmtNodes.inc" 112 }; 113} 114 115//===----------------------------------------------------------------------===// 116// Stmt printing methods. 117//===----------------------------------------------------------------------===// 118 119/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 120/// with no newline after the }. 121void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 122 OS << "{\n"; 123 for (auto *I : Node->body()) 124 PrintStmt(I); 125 126 Indent() << "}"; 127} 128 129void StmtPrinter::PrintRawDecl(Decl *D) { 130 D->print(OS, Policy, IndentLevel); 131} 132 133void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) { 134 SmallVector<Decl*, 2> Decls(S->decls()); 135 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 136} 137 138void StmtPrinter::VisitNullStmt(NullStmt *Node) { 139 Indent() << ";\n"; 140} 141 142void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 143 Indent(); 144 PrintRawDeclStmt(Node); 145 OS << ";\n"; 146} 147 148void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 149 Indent(); 150 PrintRawCompoundStmt(Node); 151 OS << "\n"; 152} 153 154void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 155 Indent(-1) << "case "; 156 PrintExpr(Node->getLHS()); 157 if (Node->getRHS()) { 158 OS << " ... "; 159 PrintExpr(Node->getRHS()); 160 } 161 OS << ":\n"; 162 163 PrintStmt(Node->getSubStmt(), 0); 164} 165 166void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 167 Indent(-1) << "default:\n"; 168 PrintStmt(Node->getSubStmt(), 0); 169} 170 171void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 172 Indent(-1) << Node->getName() << ":\n"; 173 PrintStmt(Node->getSubStmt(), 0); 174} 175 176void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { 177 for (const auto *Attr : Node->getAttrs()) { 178 Attr->printPretty(OS, Policy); 179 } 180 181 PrintStmt(Node->getSubStmt(), 0); 182} 183 184void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 185 OS << "if ("; 186 if (const DeclStmt *DS = If->getConditionVariableDeclStmt()) 187 PrintRawDeclStmt(DS); 188 else 189 PrintExpr(If->getCond()); 190 OS << ')'; 191 192 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 193 OS << ' '; 194 PrintRawCompoundStmt(CS); 195 OS << (If->getElse() ? ' ' : '\n'); 196 } else { 197 OS << '\n'; 198 PrintStmt(If->getThen()); 199 if (If->getElse()) Indent(); 200 } 201 202 if (Stmt *Else = If->getElse()) { 203 OS << "else"; 204 205 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 206 OS << ' '; 207 PrintRawCompoundStmt(CS); 208 OS << '\n'; 209 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 210 OS << ' '; 211 PrintRawIfStmt(ElseIf); 212 } else { 213 OS << '\n'; 214 PrintStmt(If->getElse()); 215 } 216 } 217} 218 219void StmtPrinter::VisitIfStmt(IfStmt *If) { 220 Indent(); 221 PrintRawIfStmt(If); 222} 223 224void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 225 Indent() << "switch ("; 226 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 227 PrintRawDeclStmt(DS); 228 else 229 PrintExpr(Node->getCond()); 230 OS << ")"; 231 232 // Pretty print compoundstmt bodies (very common). 233 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 234 OS << " "; 235 PrintRawCompoundStmt(CS); 236 OS << "\n"; 237 } else { 238 OS << "\n"; 239 PrintStmt(Node->getBody()); 240 } 241} 242 243void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 244 Indent() << "while ("; 245 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 246 PrintRawDeclStmt(DS); 247 else 248 PrintExpr(Node->getCond()); 249 OS << ")\n"; 250 PrintStmt(Node->getBody()); 251} 252 253void StmtPrinter::VisitDoStmt(DoStmt *Node) { 254 Indent() << "do "; 255 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 256 PrintRawCompoundStmt(CS); 257 OS << " "; 258 } else { 259 OS << "\n"; 260 PrintStmt(Node->getBody()); 261 Indent(); 262 } 263 264 OS << "while ("; 265 PrintExpr(Node->getCond()); 266 OS << ");\n"; 267} 268 269void StmtPrinter::VisitForStmt(ForStmt *Node) { 270 Indent() << "for ("; 271 if (Node->getInit()) { 272 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit())) 273 PrintRawDeclStmt(DS); 274 else 275 PrintExpr(cast<Expr>(Node->getInit())); 276 } 277 OS << ";"; 278 if (Node->getCond()) { 279 OS << " "; 280 PrintExpr(Node->getCond()); 281 } 282 OS << ";"; 283 if (Node->getInc()) { 284 OS << " "; 285 PrintExpr(Node->getInc()); 286 } 287 OS << ") "; 288 289 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 290 PrintRawCompoundStmt(CS); 291 OS << "\n"; 292 } else { 293 OS << "\n"; 294 PrintStmt(Node->getBody()); 295 } 296} 297 298void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 299 Indent() << "for ("; 300 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement())) 301 PrintRawDeclStmt(DS); 302 else 303 PrintExpr(cast<Expr>(Node->getElement())); 304 OS << " in "; 305 PrintExpr(Node->getCollection()); 306 OS << ") "; 307 308 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 309 PrintRawCompoundStmt(CS); 310 OS << "\n"; 311 } else { 312 OS << "\n"; 313 PrintStmt(Node->getBody()); 314 } 315} 316 317void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { 318 Indent() << "for ("; 319 PrintingPolicy SubPolicy(Policy); 320 SubPolicy.SuppressInitializers = true; 321 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel); 322 OS << " : "; 323 PrintExpr(Node->getRangeInit()); 324 OS << ") {\n"; 325 PrintStmt(Node->getBody()); 326 Indent() << "}"; 327 if (Policy.IncludeNewlines) OS << "\n"; 328} 329 330void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) { 331 Indent(); 332 if (Node->isIfExists()) 333 OS << "__if_exists ("; 334 else 335 OS << "__if_not_exists ("; 336 337 if (NestedNameSpecifier *Qualifier 338 = Node->getQualifierLoc().getNestedNameSpecifier()) 339 Qualifier->print(OS, Policy); 340 341 OS << Node->getNameInfo() << ") "; 342 343 PrintRawCompoundStmt(Node->getSubStmt()); 344} 345 346void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 347 Indent() << "goto " << Node->getLabel()->getName() << ";"; 348 if (Policy.IncludeNewlines) OS << "\n"; 349} 350 351void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 352 Indent() << "goto *"; 353 PrintExpr(Node->getTarget()); 354 OS << ";"; 355 if (Policy.IncludeNewlines) OS << "\n"; 356} 357 358void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 359 Indent() << "continue;"; 360 if (Policy.IncludeNewlines) OS << "\n"; 361} 362 363void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 364 Indent() << "break;"; 365 if (Policy.IncludeNewlines) OS << "\n"; 366} 367 368 369void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 370 Indent() << "return"; 371 if (Node->getRetValue()) { 372 OS << " "; 373 PrintExpr(Node->getRetValue()); 374 } 375 OS << ";"; 376 if (Policy.IncludeNewlines) OS << "\n"; 377} 378 379 380void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { 381 Indent() << "asm "; 382 383 if (Node->isVolatile()) 384 OS << "volatile "; 385 386 OS << "("; 387 VisitStringLiteral(Node->getAsmString()); 388 389 // Outputs 390 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 391 Node->getNumClobbers() != 0) 392 OS << " : "; 393 394 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 395 if (i != 0) 396 OS << ", "; 397 398 if (!Node->getOutputName(i).empty()) { 399 OS << '['; 400 OS << Node->getOutputName(i); 401 OS << "] "; 402 } 403 404 VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 405 OS << " ("; 406 Visit(Node->getOutputExpr(i)); 407 OS << ")"; 408 } 409 410 // Inputs 411 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) 412 OS << " : "; 413 414 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 415 if (i != 0) 416 OS << ", "; 417 418 if (!Node->getInputName(i).empty()) { 419 OS << '['; 420 OS << Node->getInputName(i); 421 OS << "] "; 422 } 423 424 VisitStringLiteral(Node->getInputConstraintLiteral(i)); 425 OS << " ("; 426 Visit(Node->getInputExpr(i)); 427 OS << ")"; 428 } 429 430 // Clobbers 431 if (Node->getNumClobbers() != 0) 432 OS << " : "; 433 434 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 435 if (i != 0) 436 OS << ", "; 437 438 VisitStringLiteral(Node->getClobberStringLiteral(i)); 439 } 440 441 OS << ");"; 442 if (Policy.IncludeNewlines) OS << "\n"; 443} 444 445void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) { 446 // FIXME: Implement MS style inline asm statement printer. 447 Indent() << "__asm "; 448 if (Node->hasBraces()) 449 OS << "{\n"; 450 OS << Node->getAsmString() << "\n"; 451 if (Node->hasBraces()) 452 Indent() << "}\n"; 453} 454 455void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) { 456 PrintStmt(Node->getCapturedDecl()->getBody()); 457} 458 459void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 460 Indent() << "@try"; 461 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 462 PrintRawCompoundStmt(TS); 463 OS << "\n"; 464 } 465 466 for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { 467 ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); 468 Indent() << "@catch("; 469 if (catchStmt->getCatchParamDecl()) { 470 if (Decl *DS = catchStmt->getCatchParamDecl()) 471 PrintRawDecl(DS); 472 } 473 OS << ")"; 474 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 475 PrintRawCompoundStmt(CS); 476 OS << "\n"; 477 } 478 } 479 480 if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>( 481 Node->getFinallyStmt())) { 482 Indent() << "@finally"; 483 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 484 OS << "\n"; 485 } 486} 487 488void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 489} 490 491void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 492 Indent() << "@catch (...) { /* todo */ } \n"; 493} 494 495void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 496 Indent() << "@throw"; 497 if (Node->getThrowExpr()) { 498 OS << " "; 499 PrintExpr(Node->getThrowExpr()); 500 } 501 OS << ";\n"; 502} 503 504void StmtPrinter::VisitObjCAvailabilityCheckExpr( 505 ObjCAvailabilityCheckExpr *Node) { 506 OS << "@available(...)"; 507} 508 509void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 510 Indent() << "@synchronized ("; 511 PrintExpr(Node->getSynchExpr()); 512 OS << ")"; 513 PrintRawCompoundStmt(Node->getSynchBody()); 514 OS << "\n"; 515} 516 517void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) { 518 Indent() << "@autoreleasepool"; 519 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt())); 520 OS << "\n"; 521} 522 523void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 524 OS << "catch ("; 525 if (Decl *ExDecl = Node->getExceptionDecl()) 526 PrintRawDecl(ExDecl); 527 else 528 OS << "..."; 529 OS << ") "; 530 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 531} 532 533void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 534 Indent(); 535 PrintRawCXXCatchStmt(Node); 536 OS << "\n"; 537} 538 539void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 540 Indent() << "try "; 541 PrintRawCompoundStmt(Node->getTryBlock()); 542 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 543 OS << " "; 544 PrintRawCXXCatchStmt(Node->getHandler(i)); 545 } 546 OS << "\n"; 547} 548 549void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) { 550 Indent() << (Node->getIsCXXTry() ? "try " : "__try "); 551 PrintRawCompoundStmt(Node->getTryBlock()); 552 SEHExceptStmt *E = Node->getExceptHandler(); 553 SEHFinallyStmt *F = Node->getFinallyHandler(); 554 if(E) 555 PrintRawSEHExceptHandler(E); 556 else { 557 assert(F && "Must have a finally block..."); 558 PrintRawSEHFinallyStmt(F); 559 } 560 OS << "\n"; 561} 562 563void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) { 564 OS << "__finally "; 565 PrintRawCompoundStmt(Node->getBlock()); 566 OS << "\n"; 567} 568 569void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) { 570 OS << "__except ("; 571 VisitExpr(Node->getFilterExpr()); 572 OS << ")\n"; 573 PrintRawCompoundStmt(Node->getBlock()); 574 OS << "\n"; 575} 576 577void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) { 578 Indent(); 579 PrintRawSEHExceptHandler(Node); 580 OS << "\n"; 581} 582 583void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { 584 Indent(); 585 PrintRawSEHFinallyStmt(Node); 586 OS << "\n"; 587} 588 589void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) { 590 Indent() << "__leave;"; 591 if (Policy.IncludeNewlines) OS << "\n"; 592} 593 594//===----------------------------------------------------------------------===// 595// OpenMP clauses printing methods 596//===----------------------------------------------------------------------===// 597 598namespace { 599class OMPClausePrinter : public OMPClauseVisitor<OMPClausePrinter> { 600 raw_ostream &OS; 601 const PrintingPolicy &Policy; 602 /// \brief Process clauses with list of variables. 603 template <typename T> 604 void VisitOMPClauseList(T *Node, char StartSym); 605public: 606 OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) 607 : OS(OS), Policy(Policy) { } 608#define OPENMP_CLAUSE(Name, Class) \ 609 void Visit##Class(Class *S); 610#include "clang/Basic/OpenMPKinds.def" 611}; 612 613void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) { 614 OS << "if("; 615 if (Node->getNameModifier() != OMPD_unknown) 616 OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": "; 617 Node->getCondition()->printPretty(OS, nullptr, Policy, 0); 618 OS << ")"; 619} 620 621void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) { 622 OS << "final("; 623 Node->getCondition()->printPretty(OS, nullptr, Policy, 0); 624 OS << ")"; 625} 626 627void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) { 628 OS << "num_threads("; 629 Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0); 630 OS << ")"; 631} 632 633void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) { 634 OS << "safelen("; 635 Node->getSafelen()->printPretty(OS, nullptr, Policy, 0); 636 OS << ")"; 637} 638 639void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) { 640 OS << "simdlen("; 641 Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0); 642 OS << ")"; 643} 644 645void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) { 646 OS << "collapse("; 647 Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0); 648 OS << ")"; 649} 650 651void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) { 652 OS << "default(" 653 << getOpenMPSimpleClauseTypeName(OMPC_default, Node->getDefaultKind()) 654 << ")"; 655} 656 657void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) { 658 OS << "proc_bind(" 659 << getOpenMPSimpleClauseTypeName(OMPC_proc_bind, Node->getProcBindKind()) 660 << ")"; 661} 662 663void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { 664 OS << "schedule("; 665 if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) { 666 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, 667 Node->getFirstScheduleModifier()); 668 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) { 669 OS << ", "; 670 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, 671 Node->getSecondScheduleModifier()); 672 } 673 OS << ": "; 674 } 675 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind()); 676 if (auto *E = Node->getChunkSize()) { 677 OS << ", "; 678 E->printPretty(OS, nullptr, Policy); 679 } 680 OS << ")"; 681} 682 683void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) { 684 OS << "ordered"; 685 if (auto *Num = Node->getNumForLoops()) { 686 OS << "("; 687 Num->printPretty(OS, nullptr, Policy, 0); 688 OS << ")"; 689 } 690} 691 692void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) { 693 OS << "nowait"; 694} 695 696void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) { 697 OS << "untied"; 698} 699 700void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) { 701 OS << "nogroup"; 702} 703 704void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) { 705 OS << "mergeable"; 706} 707 708void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; } 709 710void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; } 711 712void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) { 713 OS << "update"; 714} 715 716void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) { 717 OS << "capture"; 718} 719 720void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) { 721 OS << "seq_cst"; 722} 723 724void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) { 725 OS << "threads"; 726} 727 728void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; } 729 730void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) { 731 OS << "device("; 732 Node->getDevice()->printPretty(OS, nullptr, Policy, 0); 733 OS << ")"; 734} 735 736void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) { 737 OS << "num_teams("; 738 Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0); 739 OS << ")"; 740} 741 742void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) { 743 OS << "thread_limit("; 744 Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0); 745 OS << ")"; 746} 747 748void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) { 749 OS << "priority("; 750 Node->getPriority()->printPretty(OS, nullptr, Policy, 0); 751 OS << ")"; 752} 753 754void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) { 755 OS << "grainsize("; 756 Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0); 757 OS << ")"; 758} 759 760void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) { 761 OS << "num_tasks("; 762 Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0); 763 OS << ")"; 764} 765 766void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) { 767 OS << "hint("; 768 Node->getHint()->printPretty(OS, nullptr, Policy, 0); 769 OS << ")"; 770} 771 772template<typename T> 773void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { 774 for (typename T::varlist_iterator I = Node->varlist_begin(), 775 E = Node->varlist_end(); 776 I != E; ++I) { 777 assert(*I && "Expected non-null Stmt"); 778 OS << (I == Node->varlist_begin() ? StartSym : ','); 779 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) { 780 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) 781 DRE->printPretty(OS, nullptr, Policy, 0); 782 else 783 DRE->getDecl()->printQualifiedName(OS); 784 } else 785 (*I)->printPretty(OS, nullptr, Policy, 0); 786 } 787} 788 789void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) { 790 if (!Node->varlist_empty()) { 791 OS << "private"; 792 VisitOMPClauseList(Node, '('); 793 OS << ")"; 794 } 795} 796 797void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) { 798 if (!Node->varlist_empty()) { 799 OS << "firstprivate"; 800 VisitOMPClauseList(Node, '('); 801 OS << ")"; 802 } 803} 804 805void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) { 806 if (!Node->varlist_empty()) { 807 OS << "lastprivate"; 808 VisitOMPClauseList(Node, '('); 809 OS << ")"; 810 } 811} 812 813void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) { 814 if (!Node->varlist_empty()) { 815 OS << "shared"; 816 VisitOMPClauseList(Node, '('); 817 OS << ")"; 818 } 819} 820 821void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) { 822 if (!Node->varlist_empty()) { 823 OS << "reduction("; 824 NestedNameSpecifier *QualifierLoc = 825 Node->getQualifierLoc().getNestedNameSpecifier(); 826 OverloadedOperatorKind OOK = 827 Node->getNameInfo().getName().getCXXOverloadedOperator(); 828 if (QualifierLoc == nullptr && OOK != OO_None) { 829 // Print reduction identifier in C format 830 OS << getOperatorSpelling(OOK); 831 } else { 832 // Use C++ format 833 if (QualifierLoc != nullptr) 834 QualifierLoc->print(OS, Policy); 835 OS << Node->getNameInfo(); 836 } 837 OS << ":"; 838 VisitOMPClauseList(Node, ' '); 839 OS << ")"; 840 } 841} 842 843void OMPClausePrinter::VisitOMPTaskReductionClause( 844 OMPTaskReductionClause *Node) { 845 if (!Node->varlist_empty()) { 846 OS << "task_reduction("; 847 NestedNameSpecifier *QualifierLoc = 848 Node->getQualifierLoc().getNestedNameSpecifier(); 849 OverloadedOperatorKind OOK = 850 Node->getNameInfo().getName().getCXXOverloadedOperator(); 851 if (QualifierLoc == nullptr && OOK != OO_None) { 852 // Print reduction identifier in C format 853 OS << getOperatorSpelling(OOK); 854 } else { 855 // Use C++ format 856 if (QualifierLoc != nullptr) 857 QualifierLoc->print(OS, Policy); 858 OS << Node->getNameInfo(); 859 } 860 OS << ":"; 861 VisitOMPClauseList(Node, ' '); 862 OS << ")"; 863 } 864} 865 866void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) { 867 if (!Node->varlist_empty()) { 868 OS << "in_reduction("; 869 NestedNameSpecifier *QualifierLoc = 870 Node->getQualifierLoc().getNestedNameSpecifier(); 871 OverloadedOperatorKind OOK = 872 Node->getNameInfo().getName().getCXXOverloadedOperator(); 873 if (QualifierLoc == nullptr && OOK != OO_None) { 874 // Print reduction identifier in C format 875 OS << getOperatorSpelling(OOK); 876 } else { 877 // Use C++ format 878 if (QualifierLoc != nullptr) 879 QualifierLoc->print(OS, Policy); 880 OS << Node->getNameInfo(); 881 } 882 OS << ":"; 883 VisitOMPClauseList(Node, ' '); 884 OS << ")"; 885 } 886} 887 888void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) { 889 if (!Node->varlist_empty()) { 890 OS << "linear"; 891 if (Node->getModifierLoc().isValid()) { 892 OS << '(' 893 << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier()); 894 } 895 VisitOMPClauseList(Node, '('); 896 if (Node->getModifierLoc().isValid()) 897 OS << ')'; 898 if (Node->getStep() != nullptr) { 899 OS << ": "; 900 Node->getStep()->printPretty(OS, nullptr, Policy, 0); 901 } 902 OS << ")"; 903 } 904} 905 906void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) { 907 if (!Node->varlist_empty()) { 908 OS << "aligned"; 909 VisitOMPClauseList(Node, '('); 910 if (Node->getAlignment() != nullptr) { 911 OS << ": "; 912 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0); 913 } 914 OS << ")"; 915 } 916} 917 918void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) { 919 if (!Node->varlist_empty()) { 920 OS << "copyin"; 921 VisitOMPClauseList(Node, '('); 922 OS << ")"; 923 } 924} 925 926void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) { 927 if (!Node->varlist_empty()) { 928 OS << "copyprivate"; 929 VisitOMPClauseList(Node, '('); 930 OS << ")"; 931 } 932} 933 934void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) { 935 if (!Node->varlist_empty()) { 936 VisitOMPClauseList(Node, '('); 937 OS << ")"; 938 } 939} 940 941void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) { 942 OS << "depend("; 943 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), 944 Node->getDependencyKind()); 945 if (!Node->varlist_empty()) { 946 OS << " :"; 947 VisitOMPClauseList(Node, ' '); 948 } 949 OS << ")"; 950} 951 952void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { 953 if (!Node->varlist_empty()) { 954 OS << "map("; 955 if (Node->getMapType() != OMPC_MAP_unknown) { 956 if (Node->getMapTypeModifier() != OMPC_MAP_unknown) { 957 OS << getOpenMPSimpleClauseTypeName(OMPC_map, 958 Node->getMapTypeModifier()); 959 OS << ','; 960 } 961 OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType()); 962 OS << ':'; 963 } 964 VisitOMPClauseList(Node, ' '); 965 OS << ")"; 966 } 967} 968 969void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) { 970 if (!Node->varlist_empty()) { 971 OS << "to"; 972 VisitOMPClauseList(Node, '('); 973 OS << ")"; 974 } 975} 976 977void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) { 978 if (!Node->varlist_empty()) { 979 OS << "from"; 980 VisitOMPClauseList(Node, '('); 981 OS << ")"; 982 } 983} 984 985void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) { 986 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName( 987 OMPC_dist_schedule, Node->getDistScheduleKind()); 988 if (auto *E = Node->getChunkSize()) { 989 OS << ", "; 990 E->printPretty(OS, nullptr, Policy); 991 } 992 OS << ")"; 993} 994 995void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) { 996 OS << "defaultmap("; 997 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 998 Node->getDefaultmapModifier()); 999 OS << ": "; 1000 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 1001 Node->getDefaultmapKind()); 1002 OS << ")"; 1003} 1004 1005void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) { 1006 if (!Node->varlist_empty()) { 1007 OS << "use_device_ptr"; 1008 VisitOMPClauseList(Node, '('); 1009 OS << ")"; 1010 } 1011} 1012 1013void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) { 1014 if (!Node->varlist_empty()) { 1015 OS << "is_device_ptr"; 1016 VisitOMPClauseList(Node, '('); 1017 OS << ")"; 1018 } 1019} 1020} 1021 1022//===----------------------------------------------------------------------===// 1023// OpenMP directives printing methods 1024//===----------------------------------------------------------------------===// 1025 1026void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, 1027 bool ForceNoStmt) { 1028 OMPClausePrinter Printer(OS, Policy); 1029 ArrayRef<OMPClause *> Clauses = S->clauses(); 1030 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 1031 I != E; ++I) 1032 if (*I && !(*I)->isImplicit()) { 1033 Printer.Visit(*I); 1034 OS << ' '; 1035 } 1036 OS << "\n"; 1037 if (S->hasAssociatedStmt() && S->getAssociatedStmt() && !ForceNoStmt) { 1038 assert(isa<CapturedStmt>(S->getAssociatedStmt()) && 1039 "Expected captured statement!"); 1040 Stmt *CS = cast<CapturedStmt>(S->getAssociatedStmt())->getCapturedStmt(); 1041 PrintStmt(CS); 1042 } 1043} 1044 1045void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) { 1046 Indent() << "#pragma omp parallel "; 1047 PrintOMPExecutableDirective(Node); 1048} 1049 1050void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) { 1051 Indent() << "#pragma omp simd "; 1052 PrintOMPExecutableDirective(Node); 1053} 1054 1055void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) { 1056 Indent() << "#pragma omp for "; 1057 PrintOMPExecutableDirective(Node); 1058} 1059 1060void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) { 1061 Indent() << "#pragma omp for simd "; 1062 PrintOMPExecutableDirective(Node); 1063} 1064 1065void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) { 1066 Indent() << "#pragma omp sections "; 1067 PrintOMPExecutableDirective(Node); 1068} 1069 1070void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) { 1071 Indent() << "#pragma omp section"; 1072 PrintOMPExecutableDirective(Node); 1073} 1074 1075void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) { 1076 Indent() << "#pragma omp single "; 1077 PrintOMPExecutableDirective(Node); 1078} 1079 1080void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) { 1081 Indent() << "#pragma omp master"; 1082 PrintOMPExecutableDirective(Node); 1083} 1084 1085void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) { 1086 Indent() << "#pragma omp critical"; 1087 if (Node->getDirectiveName().getName()) { 1088 OS << " ("; 1089 Node->getDirectiveName().printName(OS); 1090 OS << ")"; 1091 } 1092 OS << " "; 1093 PrintOMPExecutableDirective(Node); 1094} 1095 1096void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { 1097 Indent() << "#pragma omp parallel for "; 1098 PrintOMPExecutableDirective(Node); 1099} 1100 1101void StmtPrinter::VisitOMPParallelForSimdDirective( 1102 OMPParallelForSimdDirective *Node) { 1103 Indent() << "#pragma omp parallel for simd "; 1104 PrintOMPExecutableDirective(Node); 1105} 1106 1107void StmtPrinter::VisitOMPParallelSectionsDirective( 1108 OMPParallelSectionsDirective *Node) { 1109 Indent() << "#pragma omp parallel sections "; 1110 PrintOMPExecutableDirective(Node); 1111} 1112 1113void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) { 1114 Indent() << "#pragma omp task "; 1115 PrintOMPExecutableDirective(Node); 1116} 1117 1118void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) { 1119 Indent() << "#pragma omp taskyield"; 1120 PrintOMPExecutableDirective(Node); 1121} 1122 1123void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) { 1124 Indent() << "#pragma omp barrier"; 1125 PrintOMPExecutableDirective(Node); 1126} 1127 1128void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { 1129 Indent() << "#pragma omp taskwait"; 1130 PrintOMPExecutableDirective(Node); 1131} 1132 1133void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { 1134 Indent() << "#pragma omp taskgroup "; 1135 PrintOMPExecutableDirective(Node); 1136} 1137 1138void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) { 1139 Indent() << "#pragma omp flush "; 1140 PrintOMPExecutableDirective(Node); 1141} 1142 1143void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { 1144 Indent() << "#pragma omp ordered "; 1145 PrintOMPExecutableDirective(Node); 1146} 1147 1148void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) { 1149 Indent() << "#pragma omp atomic "; 1150 PrintOMPExecutableDirective(Node); 1151} 1152 1153void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) { 1154 Indent() << "#pragma omp target "; 1155 PrintOMPExecutableDirective(Node); 1156} 1157 1158void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) { 1159 Indent() << "#pragma omp target data "; 1160 PrintOMPExecutableDirective(Node); 1161} 1162 1163void StmtPrinter::VisitOMPTargetEnterDataDirective( 1164 OMPTargetEnterDataDirective *Node) { 1165 Indent() << "#pragma omp target enter data "; 1166 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 1167} 1168 1169void StmtPrinter::VisitOMPTargetExitDataDirective( 1170 OMPTargetExitDataDirective *Node) { 1171 Indent() << "#pragma omp target exit data "; 1172 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 1173} 1174 1175void StmtPrinter::VisitOMPTargetParallelDirective( 1176 OMPTargetParallelDirective *Node) { 1177 Indent() << "#pragma omp target parallel "; 1178 PrintOMPExecutableDirective(Node); 1179} 1180 1181void StmtPrinter::VisitOMPTargetParallelForDirective( 1182 OMPTargetParallelForDirective *Node) { 1183 Indent() << "#pragma omp target parallel for "; 1184 PrintOMPExecutableDirective(Node); 1185} 1186 1187void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { 1188 Indent() << "#pragma omp teams "; 1189 PrintOMPExecutableDirective(Node); 1190} 1191 1192void StmtPrinter::VisitOMPCancellationPointDirective( 1193 OMPCancellationPointDirective *Node) { 1194 Indent() << "#pragma omp cancellation point " 1195 << getOpenMPDirectiveName(Node->getCancelRegion()); 1196 PrintOMPExecutableDirective(Node); 1197} 1198 1199void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { 1200 Indent() << "#pragma omp cancel " 1201 << getOpenMPDirectiveName(Node->getCancelRegion()) << " "; 1202 PrintOMPExecutableDirective(Node); 1203} 1204 1205void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) { 1206 Indent() << "#pragma omp taskloop "; 1207 PrintOMPExecutableDirective(Node); 1208} 1209 1210void StmtPrinter::VisitOMPTaskLoopSimdDirective( 1211 OMPTaskLoopSimdDirective *Node) { 1212 Indent() << "#pragma omp taskloop simd "; 1213 PrintOMPExecutableDirective(Node); 1214} 1215 1216void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) { 1217 Indent() << "#pragma omp distribute "; 1218 PrintOMPExecutableDirective(Node); 1219} 1220 1221void StmtPrinter::VisitOMPTargetUpdateDirective( 1222 OMPTargetUpdateDirective *Node) { 1223 Indent() << "#pragma omp target update "; 1224 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 1225} 1226 1227void StmtPrinter::VisitOMPDistributeParallelForDirective( 1228 OMPDistributeParallelForDirective *Node) { 1229 Indent() << "#pragma omp distribute parallel for "; 1230 PrintOMPExecutableDirective(Node); 1231} 1232 1233void StmtPrinter::VisitOMPDistributeParallelForSimdDirective( 1234 OMPDistributeParallelForSimdDirective *Node) { 1235 Indent() << "#pragma omp distribute parallel for simd "; 1236 PrintOMPExecutableDirective(Node); 1237} 1238 1239void StmtPrinter::VisitOMPDistributeSimdDirective( 1240 OMPDistributeSimdDirective *Node) { 1241 Indent() << "#pragma omp distribute simd "; 1242 PrintOMPExecutableDirective(Node); 1243} 1244 1245void StmtPrinter::VisitOMPTargetParallelForSimdDirective( 1246 OMPTargetParallelForSimdDirective *Node) { 1247 Indent() << "#pragma omp target parallel for simd "; 1248 PrintOMPExecutableDirective(Node); 1249} 1250 1251void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) { 1252 Indent() << "#pragma omp target simd "; 1253 PrintOMPExecutableDirective(Node); 1254} 1255 1256void StmtPrinter::VisitOMPTeamsDistributeDirective( 1257 OMPTeamsDistributeDirective *Node) { 1258 Indent() << "#pragma omp teams distribute "; 1259 PrintOMPExecutableDirective(Node); 1260} 1261 1262void StmtPrinter::VisitOMPTeamsDistributeSimdDirective( 1263 OMPTeamsDistributeSimdDirective *Node) { 1264 Indent() << "#pragma omp teams distribute simd "; 1265 PrintOMPExecutableDirective(Node); 1266} 1267 1268void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective( 1269 OMPTeamsDistributeParallelForSimdDirective *Node) { 1270 Indent() << "#pragma omp teams distribute parallel for simd "; 1271 PrintOMPExecutableDirective(Node); 1272} 1273 1274void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective( 1275 OMPTeamsDistributeParallelForDirective *Node) { 1276 Indent() << "#pragma omp teams distribute parallel for "; 1277 PrintOMPExecutableDirective(Node); 1278} 1279 1280void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) { 1281 Indent() << "#pragma omp target teams "; 1282 PrintOMPExecutableDirective(Node); 1283} 1284 1285void StmtPrinter::VisitOMPTargetTeamsDistributeDirective( 1286 OMPTargetTeamsDistributeDirective *Node) { 1287 Indent() << "#pragma omp target teams distribute "; 1288 PrintOMPExecutableDirective(Node); 1289} 1290 1291void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective( 1292 OMPTargetTeamsDistributeParallelForDirective *Node) { 1293 Indent() << "#pragma omp target teams distribute parallel for "; 1294 PrintOMPExecutableDirective(Node); 1295} 1296 1297void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective( 1298 OMPTargetTeamsDistributeParallelForSimdDirective *Node) { 1299 Indent() << "#pragma omp target teams distribute parallel for simd "; 1300 PrintOMPExecutableDirective(Node); 1301} 1302 1303void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective( 1304 OMPTargetTeamsDistributeSimdDirective *Node) { 1305 Indent() << "#pragma omp target teams distribute simd "; 1306 PrintOMPExecutableDirective(Node); 1307} 1308 1309//===----------------------------------------------------------------------===// 1310// Expr printing methods. 1311//===----------------------------------------------------------------------===// 1312 1313void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 1314 if (auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) { 1315 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); 1316 return; 1317 } 1318 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1319 Qualifier->print(OS, Policy); 1320 if (Node->hasTemplateKeyword()) 1321 OS << "template "; 1322 OS << Node->getNameInfo(); 1323 if (Node->hasExplicitTemplateArgs()) 1324 printTemplateArgumentList(OS, Node->template_arguments(), Policy); 1325} 1326 1327void StmtPrinter::VisitDependentScopeDeclRefExpr( 1328 DependentScopeDeclRefExpr *Node) { 1329 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1330 Qualifier->print(OS, Policy); 1331 if (Node->hasTemplateKeyword()) 1332 OS << "template "; 1333 OS << Node->getNameInfo(); 1334 if (Node->hasExplicitTemplateArgs()) 1335 printTemplateArgumentList(OS, Node->template_arguments(), Policy); 1336} 1337 1338void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 1339 if (Node->getQualifier()) 1340 Node->getQualifier()->print(OS, Policy); 1341 if (Node->hasTemplateKeyword()) 1342 OS << "template "; 1343 OS << Node->getNameInfo(); 1344 if (Node->hasExplicitTemplateArgs()) 1345 printTemplateArgumentList(OS, Node->template_arguments(), Policy); 1346} 1347 1348static bool isImplicitSelf(const Expr *E) { 1349 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 1350 if (const ImplicitParamDecl *PD = 1351 dyn_cast<ImplicitParamDecl>(DRE->getDecl())) { 1352 if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf && 1353 DRE->getLocStart().isInvalid()) 1354 return true; 1355 } 1356 } 1357 return false; 1358} 1359 1360void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 1361 if (Node->getBase()) { 1362 if (!Policy.SuppressImplicitBase || 1363 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) { 1364 PrintExpr(Node->getBase()); 1365 OS << (Node->isArrow() ? "->" : "."); 1366 } 1367 } 1368 OS << *Node->getDecl(); 1369} 1370 1371void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 1372 if (Node->isSuperReceiver()) 1373 OS << "super."; 1374 else if (Node->isObjectReceiver() && Node->getBase()) { 1375 PrintExpr(Node->getBase()); 1376 OS << "."; 1377 } else if (Node->isClassReceiver() && Node->getClassReceiver()) { 1378 OS << Node->getClassReceiver()->getName() << "."; 1379 } 1380 1381 if (Node->isImplicitProperty()) 1382 Node->getImplicitPropertyGetter()->getSelector().print(OS); 1383 else 1384 OS << Node->getExplicitProperty()->getName(); 1385} 1386 1387void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) { 1388 1389 PrintExpr(Node->getBaseExpr()); 1390 OS << "["; 1391 PrintExpr(Node->getKeyExpr()); 1392 OS << "]"; 1393} 1394 1395void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 1396 OS << PredefinedExpr::getIdentTypeName(Node->getIdentType()); 1397} 1398 1399void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 1400 unsigned value = Node->getValue(); 1401 1402 switch (Node->getKind()) { 1403 case CharacterLiteral::Ascii: break; // no prefix. 1404 case CharacterLiteral::Wide: OS << 'L'; break; 1405 case CharacterLiteral::UTF8: OS << "u8"; break; 1406 case CharacterLiteral::UTF16: OS << 'u'; break; 1407 case CharacterLiteral::UTF32: OS << 'U'; break; 1408 } 1409 1410 switch (value) { 1411 case '\\': 1412 OS << "'\\\\'"; 1413 break; 1414 case '\'': 1415 OS << "'\\''"; 1416 break; 1417 case '\a': 1418 // TODO: K&R: the meaning of '\\a' is different in traditional C 1419 OS << "'\\a'"; 1420 break; 1421 case '\b': 1422 OS << "'\\b'"; 1423 break; 1424 // Nonstandard escape sequence. 1425 /*case '\e': 1426 OS << "'\\e'"; 1427 break;*/ 1428 case '\f': 1429 OS << "'\\f'"; 1430 break; 1431 case '\n': 1432 OS << "'\\n'"; 1433 break; 1434 case '\r': 1435 OS << "'\\r'"; 1436 break; 1437 case '\t': 1438 OS << "'\\t'"; 1439 break; 1440 case '\v': 1441 OS << "'\\v'"; 1442 break; 1443 default: 1444 // A character literal might be sign-extended, which 1445 // would result in an invalid \U escape sequence. 1446 // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF' 1447 // are not correctly handled. 1448 if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii) 1449 value &= 0xFFu; 1450 if (value < 256 && isPrintable((unsigned char)value)) 1451 OS << "'" << (char)value << "'"; 1452 else if (value < 256) 1453 OS << "'\\x" << llvm::format("%02x", value) << "'"; 1454 else if (value <= 0xFFFF) 1455 OS << "'\\u" << llvm::format("%04x", value) << "'"; 1456 else 1457 OS << "'\\U" << llvm::format("%08x", value) << "'"; 1458 } 1459} 1460 1461/// Prints the given expression using the original source text. Returns true on 1462/// success, false otherwise. 1463static bool printExprAsWritten(raw_ostream &OS, Expr *E, 1464 const ASTContext *Context) { 1465 if (!Context) 1466 return false; 1467 bool Invalid = false; 1468 StringRef Source = Lexer::getSourceText( 1469 CharSourceRange::getTokenRange(E->getSourceRange()), 1470 Context->getSourceManager(), Context->getLangOpts(), &Invalid); 1471 if (!Invalid) { 1472 OS << Source; 1473 return true; 1474 } 1475 return false; 1476} 1477 1478void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 1479 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1480 return; 1481 bool isSigned = Node->getType()->isSignedIntegerType(); 1482 OS << Node->getValue().toString(10, isSigned); 1483 1484 // Emit suffixes. Integer literals are always a builtin integer type. 1485 switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 1486 default: llvm_unreachable("Unexpected type for integer literal!"); 1487 case BuiltinType::Char_S: 1488 case BuiltinType::Char_U: OS << "i8"; break; 1489 case BuiltinType::UChar: OS << "Ui8"; break; 1490 case BuiltinType::Short: OS << "i16"; break; 1491 case BuiltinType::UShort: OS << "Ui16"; break; 1492 case BuiltinType::Int: break; // no suffix. 1493 case BuiltinType::UInt: OS << 'U'; break; 1494 case BuiltinType::Long: OS << 'L'; break; 1495 case BuiltinType::ULong: OS << "UL"; break; 1496 case BuiltinType::LongLong: OS << "LL"; break; 1497 case BuiltinType::ULongLong: OS << "ULL"; break; 1498 } 1499} 1500 1501static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, 1502 bool PrintSuffix) { 1503 SmallString<16> Str; 1504 Node->getValue().toString(Str); 1505 OS << Str; 1506 if (Str.find_first_not_of("-0123456789") == StringRef::npos) 1507 OS << '.'; // Trailing dot in order to separate from ints. 1508 1509 if (!PrintSuffix) 1510 return; 1511 1512 // Emit suffixes. Float literals are always a builtin float type. 1513 switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 1514 default: llvm_unreachable("Unexpected type for float literal!"); 1515 case BuiltinType::Half: break; // FIXME: suffix? 1516 case BuiltinType::Double: break; // no suffix. 1517 case BuiltinType::Float16: OS << "F16"; break; 1518 case BuiltinType::Float: OS << 'F'; break; 1519 case BuiltinType::LongDouble: OS << 'L'; break; 1520 case BuiltinType::Float128: OS << 'Q'; break; 1521 } 1522} 1523 1524void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 1525 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1526 return; 1527 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true); 1528} 1529 1530void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 1531 PrintExpr(Node->getSubExpr()); 1532 OS << "i"; 1533} 1534 1535void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 1536 Str->outputString(OS); 1537} 1538void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 1539 OS << "("; 1540 PrintExpr(Node->getSubExpr()); 1541 OS << ")"; 1542} 1543void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 1544 if (!Node->isPostfix()) { 1545 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 1546 1547 // Print a space if this is an "identifier operator" like __real, or if 1548 // it might be concatenated incorrectly like '+'. 1549 switch (Node->getOpcode()) { 1550 default: break; 1551 case UO_Real: 1552 case UO_Imag: 1553 case UO_Extension: 1554 OS << ' '; 1555 break; 1556 case UO_Plus: 1557 case UO_Minus: 1558 if (isa<UnaryOperator>(Node->getSubExpr())) 1559 OS << ' '; 1560 break; 1561 } 1562 } 1563 PrintExpr(Node->getSubExpr()); 1564 1565 if (Node->isPostfix()) 1566 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 1567} 1568 1569void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 1570 OS << "__builtin_offsetof("; 1571 Node->getTypeSourceInfo()->getType().print(OS, Policy); 1572 OS << ", "; 1573 bool PrintedSomething = false; 1574 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 1575 OffsetOfNode ON = Node->getComponent(i); 1576 if (ON.getKind() == OffsetOfNode::Array) { 1577 // Array node 1578 OS << "["; 1579 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 1580 OS << "]"; 1581 PrintedSomething = true; 1582 continue; 1583 } 1584 1585 // Skip implicit base indirections. 1586 if (ON.getKind() == OffsetOfNode::Base) 1587 continue; 1588 1589 // Field or identifier node. 1590 IdentifierInfo *Id = ON.getFieldName(); 1591 if (!Id) 1592 continue; 1593 1594 if (PrintedSomething) 1595 OS << "."; 1596 else 1597 PrintedSomething = true; 1598 OS << Id->getName(); 1599 } 1600 OS << ")"; 1601} 1602 1603void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ 1604 switch(Node->getKind()) { 1605 case UETT_SizeOf: 1606 OS << "sizeof"; 1607 break; 1608 case UETT_AlignOf: 1609 if (Policy.Alignof) 1610 OS << "alignof"; 1611 else if (Policy.UnderscoreAlignof) 1612 OS << "_Alignof"; 1613 else 1614 OS << "__alignof"; 1615 break; 1616 case UETT_VecStep: 1617 OS << "vec_step"; 1618 break; 1619 case UETT_OpenMPRequiredSimdAlign: 1620 OS << "__builtin_omp_required_simd_align"; 1621 break; 1622 } 1623 if (Node->isArgumentType()) { 1624 OS << '('; 1625 Node->getArgumentType().print(OS, Policy); 1626 OS << ')'; 1627 } else { 1628 OS << " "; 1629 PrintExpr(Node->getArgumentExpr()); 1630 } 1631} 1632 1633void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { 1634 OS << "_Generic("; 1635 PrintExpr(Node->getControllingExpr()); 1636 for (unsigned i = 0; i != Node->getNumAssocs(); ++i) { 1637 OS << ", "; 1638 QualType T = Node->getAssocType(i); 1639 if (T.isNull()) 1640 OS << "default"; 1641 else 1642 T.print(OS, Policy); 1643 OS << ": "; 1644 PrintExpr(Node->getAssocExpr(i)); 1645 } 1646 OS << ")"; 1647} 1648 1649void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 1650 PrintExpr(Node->getLHS()); 1651 OS << "["; 1652 PrintExpr(Node->getRHS()); 1653 OS << "]"; 1654} 1655 1656void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { 1657 PrintExpr(Node->getBase()); 1658 OS << "["; 1659 if (Node->getLowerBound()) 1660 PrintExpr(Node->getLowerBound()); 1661 if (Node->getColonLoc().isValid()) { 1662 OS << ":"; 1663 if (Node->getLength()) 1664 PrintExpr(Node->getLength()); 1665 } 1666 OS << "]"; 1667} 1668 1669void StmtPrinter::PrintCallArgs(CallExpr *Call) { 1670 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 1671 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 1672 // Don't print any defaulted arguments 1673 break; 1674 } 1675 1676 if (i) OS << ", "; 1677 PrintExpr(Call->getArg(i)); 1678 } 1679} 1680 1681void StmtPrinter::VisitCallExpr(CallExpr *Call) { 1682 PrintExpr(Call->getCallee()); 1683 OS << "("; 1684 PrintCallArgs(Call); 1685 OS << ")"; 1686} 1687 1688static bool isImplicitThis(const Expr *E) { 1689 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) 1690 return TE->isImplicit(); 1691 return false; 1692} 1693 1694void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 1695 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) { 1696 PrintExpr(Node->getBase()); 1697 1698 MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase()); 1699 FieldDecl *ParentDecl = 1700 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) 1701 : nullptr; 1702 1703 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion()) 1704 OS << (Node->isArrow() ? "->" : "."); 1705 } 1706 1707 if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 1708 if (FD->isAnonymousStructOrUnion()) 1709 return; 1710 1711 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1712 Qualifier->print(OS, Policy); 1713 if (Node->hasTemplateKeyword()) 1714 OS << "template "; 1715 OS << Node->getMemberNameInfo(); 1716 if (Node->hasExplicitTemplateArgs()) 1717 printTemplateArgumentList(OS, Node->template_arguments(), Policy); 1718} 1719void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 1720 PrintExpr(Node->getBase()); 1721 OS << (Node->isArrow() ? "->isa" : ".isa"); 1722} 1723 1724void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 1725 PrintExpr(Node->getBase()); 1726 OS << "."; 1727 OS << Node->getAccessor().getName(); 1728} 1729void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 1730 OS << '('; 1731 Node->getTypeAsWritten().print(OS, Policy); 1732 OS << ')'; 1733 PrintExpr(Node->getSubExpr()); 1734} 1735void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 1736 OS << '('; 1737 Node->getType().print(OS, Policy); 1738 OS << ')'; 1739 PrintExpr(Node->getInitializer()); 1740} 1741void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 1742 // No need to print anything, simply forward to the subexpression. 1743 PrintExpr(Node->getSubExpr()); 1744} 1745void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 1746 PrintExpr(Node->getLHS()); 1747 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 1748 PrintExpr(Node->getRHS()); 1749} 1750void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 1751 PrintExpr(Node->getLHS()); 1752 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 1753 PrintExpr(Node->getRHS()); 1754} 1755void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 1756 PrintExpr(Node->getCond()); 1757 OS << " ? "; 1758 PrintExpr(Node->getLHS()); 1759 OS << " : "; 1760 PrintExpr(Node->getRHS()); 1761} 1762 1763// GNU extensions. 1764 1765void 1766StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 1767 PrintExpr(Node->getCommon()); 1768 OS << " ?: "; 1769 PrintExpr(Node->getFalseExpr()); 1770} 1771void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 1772 OS << "&&" << Node->getLabel()->getName(); 1773} 1774 1775void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 1776 OS << "("; 1777 PrintRawCompoundStmt(E->getSubStmt()); 1778 OS << ")"; 1779} 1780 1781void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 1782 OS << "__builtin_choose_expr("; 1783 PrintExpr(Node->getCond()); 1784 OS << ", "; 1785 PrintExpr(Node->getLHS()); 1786 OS << ", "; 1787 PrintExpr(Node->getRHS()); 1788 OS << ")"; 1789} 1790 1791void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 1792 OS << "__null"; 1793} 1794 1795void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 1796 OS << "__builtin_shufflevector("; 1797 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 1798 if (i) OS << ", "; 1799 PrintExpr(Node->getExpr(i)); 1800 } 1801 OS << ")"; 1802} 1803 1804void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) { 1805 OS << "__builtin_convertvector("; 1806 PrintExpr(Node->getSrcExpr()); 1807 OS << ", "; 1808 Node->getType().print(OS, Policy); 1809 OS << ")"; 1810} 1811 1812void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 1813 if (Node->getSyntacticForm()) { 1814 Visit(Node->getSyntacticForm()); 1815 return; 1816 } 1817 1818 OS << "{"; 1819 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 1820 if (i) OS << ", "; 1821 if (Node->getInit(i)) 1822 PrintExpr(Node->getInit(i)); 1823 else 1824 OS << "{}"; 1825 } 1826 OS << "}"; 1827} 1828 1829void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) { 1830 // There's no way to express this expression in any of our supported 1831 // languages, so just emit something terse and (hopefully) clear. 1832 OS << "{"; 1833 PrintExpr(Node->getSubExpr()); 1834 OS << "}"; 1835} 1836 1837void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) { 1838 OS << "*"; 1839} 1840 1841void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 1842 OS << "("; 1843 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 1844 if (i) OS << ", "; 1845 PrintExpr(Node->getExpr(i)); 1846 } 1847 OS << ")"; 1848} 1849 1850void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 1851 bool NeedsEquals = true; 1852 for (const DesignatedInitExpr::Designator &D : Node->designators()) { 1853 if (D.isFieldDesignator()) { 1854 if (D.getDotLoc().isInvalid()) { 1855 if (IdentifierInfo *II = D.getFieldName()) { 1856 OS << II->getName() << ":"; 1857 NeedsEquals = false; 1858 } 1859 } else { 1860 OS << "." << D.getFieldName()->getName(); 1861 } 1862 } else { 1863 OS << "["; 1864 if (D.isArrayDesignator()) { 1865 PrintExpr(Node->getArrayIndex(D)); 1866 } else { 1867 PrintExpr(Node->getArrayRangeStart(D)); 1868 OS << " ... "; 1869 PrintExpr(Node->getArrayRangeEnd(D)); 1870 } 1871 OS << "]"; 1872 } 1873 } 1874 1875 if (NeedsEquals) 1876 OS << " = "; 1877 else 1878 OS << " "; 1879 PrintExpr(Node->getInit()); 1880} 1881 1882void StmtPrinter::VisitDesignatedInitUpdateExpr( 1883 DesignatedInitUpdateExpr *Node) { 1884 OS << "{"; 1885 OS << "/*base*/"; 1886 PrintExpr(Node->getBase()); 1887 OS << ", "; 1888 1889 OS << "/*updater*/"; 1890 PrintExpr(Node->getUpdater()); 1891 OS << "}"; 1892} 1893 1894void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) { 1895 OS << "/*no init*/"; 1896} 1897 1898void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 1899 if (Node->getType()->getAsCXXRecordDecl()) { 1900 OS << "/*implicit*/"; 1901 Node->getType().print(OS, Policy); 1902 OS << "()"; 1903 } else { 1904 OS << "/*implicit*/("; 1905 Node->getType().print(OS, Policy); 1906 OS << ')'; 1907 if (Node->getType()->isRecordType()) 1908 OS << "{}"; 1909 else 1910 OS << 0; 1911 } 1912} 1913 1914void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 1915 OS << "__builtin_va_arg("; 1916 PrintExpr(Node->getSubExpr()); 1917 OS << ", "; 1918 Node->getType().print(OS, Policy); 1919 OS << ")"; 1920} 1921 1922void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { 1923 PrintExpr(Node->getSyntacticForm()); 1924} 1925 1926void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { 1927 const char *Name = nullptr; 1928 switch (Node->getOp()) { 1929#define BUILTIN(ID, TYPE, ATTRS) 1930#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 1931 case AtomicExpr::AO ## ID: \ 1932 Name = #ID "("; \ 1933 break; 1934#include "clang/Basic/Builtins.def" 1935 } 1936 OS << Name; 1937 1938 // AtomicExpr stores its subexpressions in a permuted order. 1939 PrintExpr(Node->getPtr()); 1940 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && 1941 Node->getOp() != AtomicExpr::AO__atomic_load_n && 1942 Node->getOp() != AtomicExpr::AO__opencl_atomic_load) { 1943 OS << ", "; 1944 PrintExpr(Node->getVal1()); 1945 } 1946 if (Node->getOp() == AtomicExpr::AO__atomic_exchange || 1947 Node->isCmpXChg()) { 1948 OS << ", "; 1949 PrintExpr(Node->getVal2()); 1950 } 1951 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange || 1952 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) { 1953 OS << ", "; 1954 PrintExpr(Node->getWeak()); 1955 } 1956 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init && 1957 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) { 1958 OS << ", "; 1959 PrintExpr(Node->getOrder()); 1960 } 1961 if (Node->isCmpXChg()) { 1962 OS << ", "; 1963 PrintExpr(Node->getOrderFail()); 1964 } 1965 OS << ")"; 1966} 1967 1968// C++ 1969void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 1970 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 1971 "", 1972#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 1973 Spelling, 1974#include "clang/Basic/OperatorKinds.def" 1975 }; 1976 1977 OverloadedOperatorKind Kind = Node->getOperator(); 1978 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 1979 if (Node->getNumArgs() == 1) { 1980 OS << OpStrings[Kind] << ' '; 1981 PrintExpr(Node->getArg(0)); 1982 } else { 1983 PrintExpr(Node->getArg(0)); 1984 OS << ' ' << OpStrings[Kind]; 1985 } 1986 } else if (Kind == OO_Arrow) { 1987 PrintExpr(Node->getArg(0)); 1988 } else if (Kind == OO_Call) { 1989 PrintExpr(Node->getArg(0)); 1990 OS << '('; 1991 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 1992 if (ArgIdx > 1) 1993 OS << ", "; 1994 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 1995 PrintExpr(Node->getArg(ArgIdx)); 1996 } 1997 OS << ')'; 1998 } else if (Kind == OO_Subscript) { 1999 PrintExpr(Node->getArg(0)); 2000 OS << '['; 2001 PrintExpr(Node->getArg(1)); 2002 OS << ']'; 2003 } else if (Node->getNumArgs() == 1) { 2004 OS << OpStrings[Kind] << ' '; 2005 PrintExpr(Node->getArg(0)); 2006 } else if (Node->getNumArgs() == 2) { 2007 PrintExpr(Node->getArg(0)); 2008 OS << ' ' << OpStrings[Kind] << ' '; 2009 PrintExpr(Node->getArg(1)); 2010 } else { 2011 llvm_unreachable("unknown overloaded operator"); 2012 } 2013} 2014 2015void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 2016 // If we have a conversion operator call only print the argument. 2017 CXXMethodDecl *MD = Node->getMethodDecl(); 2018 if (MD && isa<CXXConversionDecl>(MD)) { 2019 PrintExpr(Node->getImplicitObjectArgument()); 2020 return; 2021 } 2022 VisitCallExpr(cast<CallExpr>(Node)); 2023} 2024 2025void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 2026 PrintExpr(Node->getCallee()); 2027 OS << "<<<"; 2028 PrintCallArgs(Node->getConfig()); 2029 OS << ">>>("; 2030 PrintCallArgs(Node); 2031 OS << ")"; 2032} 2033 2034void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 2035 OS << Node->getCastName() << '<'; 2036 Node->getTypeAsWritten().print(OS, Policy); 2037 OS << ">("; 2038 PrintExpr(Node->getSubExpr()); 2039 OS << ")"; 2040} 2041 2042void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 2043 VisitCXXNamedCastExpr(Node); 2044} 2045 2046void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 2047 VisitCXXNamedCastExpr(Node); 2048} 2049 2050void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 2051 VisitCXXNamedCastExpr(Node); 2052} 2053 2054void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 2055 VisitCXXNamedCastExpr(Node); 2056} 2057 2058void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 2059 OS << "typeid("; 2060 if (Node->isTypeOperand()) { 2061 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 2062 } else { 2063 PrintExpr(Node->getExprOperand()); 2064 } 2065 OS << ")"; 2066} 2067 2068void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 2069 OS << "__uuidof("; 2070 if (Node->isTypeOperand()) { 2071 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 2072 } else { 2073 PrintExpr(Node->getExprOperand()); 2074 } 2075 OS << ")"; 2076} 2077 2078void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) { 2079 PrintExpr(Node->getBaseExpr()); 2080 if (Node->isArrow()) 2081 OS << "->"; 2082 else 2083 OS << "."; 2084 if (NestedNameSpecifier *Qualifier = 2085 Node->getQualifierLoc().getNestedNameSpecifier()) 2086 Qualifier->print(OS, Policy); 2087 OS << Node->getPropertyDecl()->getDeclName(); 2088} 2089 2090void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) { 2091 PrintExpr(Node->getBase()); 2092 OS << "["; 2093 PrintExpr(Node->getIdx()); 2094 OS << "]"; 2095} 2096 2097void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { 2098 switch (Node->getLiteralOperatorKind()) { 2099 case UserDefinedLiteral::LOK_Raw: 2100 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString(); 2101 break; 2102 case UserDefinedLiteral::LOK_Template: { 2103 DeclRefExpr *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts()); 2104 const TemplateArgumentList *Args = 2105 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs(); 2106 assert(Args); 2107 2108 if (Args->size() != 1) { 2109 OS << "operator\"\"" << Node->getUDSuffix()->getName(); 2110 printTemplateArgumentList(OS, Args->asArray(), Policy); 2111 OS << "()"; 2112 return; 2113 } 2114 2115 const TemplateArgument &Pack = Args->get(0); 2116 for (const auto &P : Pack.pack_elements()) { 2117 char C = (char)P.getAsIntegral().getZExtValue(); 2118 OS << C; 2119 } 2120 break; 2121 } 2122 case UserDefinedLiteral::LOK_Integer: { 2123 // Print integer literal without suffix. 2124 IntegerLiteral *Int = cast<IntegerLiteral>(Node->getCookedLiteral()); 2125 OS << Int->getValue().toString(10, /*isSigned*/false); 2126 break; 2127 } 2128 case UserDefinedLiteral::LOK_Floating: { 2129 // Print floating literal without suffix. 2130 FloatingLiteral *Float = cast<FloatingLiteral>(Node->getCookedLiteral()); 2131 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false); 2132 break; 2133 } 2134 case UserDefinedLiteral::LOK_String: 2135 case UserDefinedLiteral::LOK_Character: 2136 PrintExpr(Node->getCookedLiteral()); 2137 break; 2138 } 2139 OS << Node->getUDSuffix()->getName(); 2140} 2141 2142void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 2143 OS << (Node->getValue() ? "true" : "false"); 2144} 2145 2146void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 2147 OS << "nullptr"; 2148} 2149 2150void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 2151 OS << "this"; 2152} 2153 2154void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 2155 if (!Node->getSubExpr()) 2156 OS << "throw"; 2157 else { 2158 OS << "throw "; 2159 PrintExpr(Node->getSubExpr()); 2160 } 2161} 2162 2163void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 2164 // Nothing to print: we picked up the default argument. 2165} 2166 2167void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) { 2168 // Nothing to print: we picked up the default initializer. 2169} 2170 2171void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 2172 Node->getType().print(OS, Policy); 2173 // If there are no parens, this is list-initialization, and the braces are 2174 // part of the syntax of the inner construct. 2175 if (Node->getLParenLoc().isValid()) 2176 OS << "("; 2177 PrintExpr(Node->getSubExpr()); 2178 if (Node->getLParenLoc().isValid()) 2179 OS << ")"; 2180} 2181 2182void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 2183 PrintExpr(Node->getSubExpr()); 2184} 2185 2186void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 2187 Node->getType().print(OS, Policy); 2188 if (Node->isStdInitListInitialization()) 2189 /* Nothing to do; braces are part of creating the std::initializer_list. */; 2190 else if (Node->isListInitialization()) 2191 OS << "{"; 2192 else 2193 OS << "("; 2194 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 2195 ArgEnd = Node->arg_end(); 2196 Arg != ArgEnd; ++Arg) { 2197 if ((*Arg)->isDefaultArgument()) 2198 break; 2199 if (Arg != Node->arg_begin()) 2200 OS << ", "; 2201 PrintExpr(*Arg); 2202 } 2203 if (Node->isStdInitListInitialization()) 2204 /* See above. */; 2205 else if (Node->isListInitialization()) 2206 OS << "}"; 2207 else 2208 OS << ")"; 2209} 2210 2211void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { 2212 OS << '['; 2213 bool NeedComma = false; 2214 switch (Node->getCaptureDefault()) { 2215 case LCD_None: 2216 break; 2217 2218 case LCD_ByCopy: 2219 OS << '='; 2220 NeedComma = true; 2221 break; 2222 2223 case LCD_ByRef: 2224 OS << '&'; 2225 NeedComma = true; 2226 break; 2227 } 2228 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(), 2229 CEnd = Node->explicit_capture_end(); 2230 C != CEnd; 2231 ++C) { 2232 if (C->capturesVLAType()) 2233 continue; 2234 2235 if (NeedComma) 2236 OS << ", "; 2237 NeedComma = true; 2238 2239 switch (C->getCaptureKind()) { 2240 case LCK_This: 2241 OS << "this"; 2242 break; 2243 case LCK_StarThis: 2244 OS << "*this"; 2245 break; 2246 case LCK_ByRef: 2247 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C)) 2248 OS << '&'; 2249 OS << C->getCapturedVar()->getName(); 2250 break; 2251 2252 case LCK_ByCopy: 2253 OS << C->getCapturedVar()->getName(); 2254 break; 2255 case LCK_VLAType: 2256 llvm_unreachable("VLA type in explicit captures."); 2257 } 2258 2259 if (Node->isInitCapture(C)) 2260 PrintExpr(C->getCapturedVar()->getInit()); 2261 } 2262 OS << ']'; 2263 2264 if (Node->hasExplicitParameters()) { 2265 OS << " ("; 2266 CXXMethodDecl *Method = Node->getCallOperator(); 2267 NeedComma = false; 2268 for (auto P : Method->parameters()) { 2269 if (NeedComma) { 2270 OS << ", "; 2271 } else { 2272 NeedComma = true; 2273 } 2274 std::string ParamStr = P->getNameAsString(); 2275 P->getOriginalType().print(OS, Policy, ParamStr); 2276 } 2277 if (Method->isVariadic()) { 2278 if (NeedComma) 2279 OS << ", "; 2280 OS << "..."; 2281 } 2282 OS << ')'; 2283 2284 if (Node->isMutable()) 2285 OS << " mutable"; 2286 2287 const FunctionProtoType *Proto 2288 = Method->getType()->getAs<FunctionProtoType>(); 2289 Proto->printExceptionSpecification(OS, Policy); 2290 2291 // FIXME: Attributes 2292 2293 // Print the trailing return type if it was specified in the source. 2294 if (Node->hasExplicitResultType()) { 2295 OS << " -> "; 2296 Proto->getReturnType().print(OS, Policy); 2297 } 2298 } 2299 2300 // Print the body. 2301 CompoundStmt *Body = Node->getBody(); 2302 OS << ' '; 2303 PrintStmt(Body); 2304} 2305 2306void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 2307 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 2308 TSInfo->getType().print(OS, Policy); 2309 else 2310 Node->getType().print(OS, Policy); 2311 OS << "()"; 2312} 2313 2314void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 2315 if (E->isGlobalNew()) 2316 OS << "::"; 2317 OS << "new "; 2318 unsigned NumPlace = E->getNumPlacementArgs(); 2319 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) { 2320 OS << "("; 2321 PrintExpr(E->getPlacementArg(0)); 2322 for (unsigned i = 1; i < NumPlace; ++i) { 2323 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i))) 2324 break; 2325 OS << ", "; 2326 PrintExpr(E->getPlacementArg(i)); 2327 } 2328 OS << ") "; 2329 } 2330 if (E->isParenTypeId()) 2331 OS << "("; 2332 std::string TypeS; 2333 if (Expr *Size = E->getArraySize()) { 2334 llvm::raw_string_ostream s(TypeS); 2335 s << '['; 2336 Size->printPretty(s, Helper, Policy); 2337 s << ']'; 2338 } 2339 E->getAllocatedType().print(OS, Policy, TypeS); 2340 if (E->isParenTypeId()) 2341 OS << ")"; 2342 2343 CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle(); 2344 if (InitStyle) { 2345 if (InitStyle == CXXNewExpr::CallInit) 2346 OS << "("; 2347 PrintExpr(E->getInitializer()); 2348 if (InitStyle == CXXNewExpr::CallInit) 2349 OS << ")"; 2350 } 2351} 2352 2353void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 2354 if (E->isGlobalDelete()) 2355 OS << "::"; 2356 OS << "delete "; 2357 if (E->isArrayForm()) 2358 OS << "[] "; 2359 PrintExpr(E->getArgument()); 2360} 2361 2362void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 2363 PrintExpr(E->getBase()); 2364 if (E->isArrow()) 2365 OS << "->"; 2366 else 2367 OS << '.'; 2368 if (E->getQualifier()) 2369 E->getQualifier()->print(OS, Policy); 2370 OS << "~"; 2371 2372 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 2373 OS << II->getName(); 2374 else 2375 E->getDestroyedType().print(OS, Policy); 2376} 2377 2378void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 2379 if (E->isListInitialization() && !E->isStdInitListInitialization()) 2380 OS << "{"; 2381 2382 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 2383 if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 2384 // Don't print any defaulted arguments 2385 break; 2386 } 2387 2388 if (i) OS << ", "; 2389 PrintExpr(E->getArg(i)); 2390 } 2391 2392 if (E->isListInitialization() && !E->isStdInitListInitialization()) 2393 OS << "}"; 2394} 2395 2396void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) { 2397 // Parens are printed by the surrounding context. 2398 OS << "<forwarded>"; 2399} 2400 2401void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { 2402 PrintExpr(E->getSubExpr()); 2403} 2404 2405void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 2406 // Just forward to the subexpression. 2407 PrintExpr(E->getSubExpr()); 2408} 2409 2410void 2411StmtPrinter::VisitCXXUnresolvedConstructExpr( 2412 CXXUnresolvedConstructExpr *Node) { 2413 Node->getTypeAsWritten().print(OS, Policy); 2414 OS << "("; 2415 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 2416 ArgEnd = Node->arg_end(); 2417 Arg != ArgEnd; ++Arg) { 2418 if (Arg != Node->arg_begin()) 2419 OS << ", "; 2420 PrintExpr(*Arg); 2421 } 2422 OS << ")"; 2423} 2424 2425void StmtPrinter::VisitCXXDependentScopeMemberExpr( 2426 CXXDependentScopeMemberExpr *Node) { 2427 if (!Node->isImplicitAccess()) { 2428 PrintExpr(Node->getBase()); 2429 OS << (Node->isArrow() ? "->" : "."); 2430 } 2431 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 2432 Qualifier->print(OS, Policy); 2433 if (Node->hasTemplateKeyword()) 2434 OS << "template "; 2435 OS << Node->getMemberNameInfo(); 2436 if (Node->hasExplicitTemplateArgs()) 2437 printTemplateArgumentList(OS, Node->template_arguments(), Policy); 2438} 2439 2440void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 2441 if (!Node->isImplicitAccess()) { 2442 PrintExpr(Node->getBase()); 2443 OS << (Node->isArrow() ? "->" : "."); 2444 } 2445 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 2446 Qualifier->print(OS, Policy); 2447 if (Node->hasTemplateKeyword()) 2448 OS << "template "; 2449 OS << Node->getMemberNameInfo(); 2450 if (Node->hasExplicitTemplateArgs()) 2451 printTemplateArgumentList(OS, Node->template_arguments(), Policy); 2452} 2453 2454static const char *getTypeTraitName(TypeTrait TT) { 2455 switch (TT) { 2456#define TYPE_TRAIT_1(Spelling, Name, Key) \ 2457case clang::UTT_##Name: return #Spelling; 2458#define TYPE_TRAIT_2(Spelling, Name, Key) \ 2459case clang::BTT_##Name: return #Spelling; 2460#define TYPE_TRAIT_N(Spelling, Name, Key) \ 2461 case clang::TT_##Name: return #Spelling; 2462#include "clang/Basic/TokenKinds.def" 2463 } 2464 llvm_unreachable("Type trait not covered by switch"); 2465} 2466 2467static const char *getTypeTraitName(ArrayTypeTrait ATT) { 2468 switch (ATT) { 2469 case ATT_ArrayRank: return "__array_rank"; 2470 case ATT_ArrayExtent: return "__array_extent"; 2471 } 2472 llvm_unreachable("Array type trait not covered by switch"); 2473} 2474 2475static const char *getExpressionTraitName(ExpressionTrait ET) { 2476 switch (ET) { 2477 case ET_IsLValueExpr: return "__is_lvalue_expr"; 2478 case ET_IsRValueExpr: return "__is_rvalue_expr"; 2479 } 2480 llvm_unreachable("Expression type trait not covered by switch"); 2481} 2482 2483void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) { 2484 OS << getTypeTraitName(E->getTrait()) << "("; 2485 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { 2486 if (I > 0) 2487 OS << ", "; 2488 E->getArg(I)->getType().print(OS, Policy); 2489 } 2490 OS << ")"; 2491} 2492 2493void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 2494 OS << getTypeTraitName(E->getTrait()) << '('; 2495 E->getQueriedType().print(OS, Policy); 2496 OS << ')'; 2497} 2498 2499void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { 2500 OS << getExpressionTraitName(E->getTrait()) << '('; 2501 PrintExpr(E->getQueriedExpression()); 2502 OS << ')'; 2503} 2504 2505void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 2506 OS << "noexcept("; 2507 PrintExpr(E->getOperand()); 2508 OS << ")"; 2509} 2510 2511void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 2512 PrintExpr(E->getPattern()); 2513 OS << "..."; 2514} 2515 2516void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 2517 OS << "sizeof...(" << *E->getPack() << ")"; 2518} 2519 2520void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 2521 SubstNonTypeTemplateParmPackExpr *Node) { 2522 OS << *Node->getParameterPack(); 2523} 2524 2525void StmtPrinter::VisitSubstNonTypeTemplateParmExpr( 2526 SubstNonTypeTemplateParmExpr *Node) { 2527 Visit(Node->getReplacement()); 2528} 2529 2530void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { 2531 OS << *E->getParameterPack(); 2532} 2533 2534void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){ 2535 PrintExpr(Node->GetTemporaryExpr()); 2536} 2537 2538void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) { 2539 OS << "("; 2540 if (E->getLHS()) { 2541 PrintExpr(E->getLHS()); 2542 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 2543 } 2544 OS << "..."; 2545 if (E->getRHS()) { 2546 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 2547 PrintExpr(E->getRHS()); 2548 } 2549 OS << ")"; 2550} 2551 2552// C++ Coroutines TS 2553 2554void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) { 2555 Visit(S->getBody()); 2556} 2557 2558void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) { 2559 OS << "co_return"; 2560 if (S->getOperand()) { 2561 OS << " "; 2562 Visit(S->getOperand()); 2563 } 2564 OS << ";"; 2565} 2566 2567void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) { 2568 OS << "co_await "; 2569 PrintExpr(S->getOperand()); 2570} 2571 2572 2573void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) { 2574 OS << "co_await "; 2575 PrintExpr(S->getOperand()); 2576} 2577 2578 2579void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) { 2580 OS << "co_yield "; 2581 PrintExpr(S->getOperand()); 2582} 2583 2584// Obj-C 2585 2586void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 2587 OS << "@"; 2588 VisitStringLiteral(Node->getString()); 2589} 2590 2591void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 2592 OS << "@"; 2593 Visit(E->getSubExpr()); 2594} 2595 2596void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 2597 OS << "@[ "; 2598 ObjCArrayLiteral::child_range Ch = E->children(); 2599 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) { 2600 if (I != Ch.begin()) 2601 OS << ", "; 2602 Visit(*I); 2603 } 2604 OS << " ]"; 2605} 2606 2607void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 2608 OS << "@{ "; 2609 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { 2610 if (I > 0) 2611 OS << ", "; 2612 2613 ObjCDictionaryElement Element = E->getKeyValueElement(I); 2614 Visit(Element.Key); 2615 OS << " : "; 2616 Visit(Element.Value); 2617 if (Element.isPackExpansion()) 2618 OS << "..."; 2619 } 2620 OS << " }"; 2621} 2622 2623void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 2624 OS << "@encode("; 2625 Node->getEncodedType().print(OS, Policy); 2626 OS << ')'; 2627} 2628 2629void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 2630 OS << "@selector("; 2631 Node->getSelector().print(OS); 2632 OS << ')'; 2633} 2634 2635void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 2636 OS << "@protocol(" << *Node->getProtocol() << ')'; 2637} 2638 2639void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 2640 OS << "["; 2641 switch (Mess->getReceiverKind()) { 2642 case ObjCMessageExpr::Instance: 2643 PrintExpr(Mess->getInstanceReceiver()); 2644 break; 2645 2646 case ObjCMessageExpr::Class: 2647 Mess->getClassReceiver().print(OS, Policy); 2648 break; 2649 2650 case ObjCMessageExpr::SuperInstance: 2651 case ObjCMessageExpr::SuperClass: 2652 OS << "Super"; 2653 break; 2654 } 2655 2656 OS << ' '; 2657 Selector selector = Mess->getSelector(); 2658 if (selector.isUnarySelector()) { 2659 OS << selector.getNameForSlot(0); 2660 } else { 2661 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 2662 if (i < selector.getNumArgs()) { 2663 if (i > 0) OS << ' '; 2664 if (selector.getIdentifierInfoForSlot(i)) 2665 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 2666 else 2667 OS << ":"; 2668 } 2669 else OS << ", "; // Handle variadic methods. 2670 2671 PrintExpr(Mess->getArg(i)); 2672 } 2673 } 2674 OS << "]"; 2675} 2676 2677void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { 2678 OS << (Node->getValue() ? "__objc_yes" : "__objc_no"); 2679} 2680 2681void 2682StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { 2683 PrintExpr(E->getSubExpr()); 2684} 2685 2686void 2687StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { 2688 OS << '(' << E->getBridgeKindName(); 2689 E->getType().print(OS, Policy); 2690 OS << ')'; 2691 PrintExpr(E->getSubExpr()); 2692} 2693 2694void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 2695 BlockDecl *BD = Node->getBlockDecl(); 2696 OS << "^"; 2697 2698 const FunctionType *AFT = Node->getFunctionType(); 2699 2700 if (isa<FunctionNoProtoType>(AFT)) { 2701 OS << "()"; 2702 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 2703 OS << '('; 2704 for (BlockDecl::param_iterator AI = BD->param_begin(), 2705 E = BD->param_end(); AI != E; ++AI) { 2706 if (AI != BD->param_begin()) OS << ", "; 2707 std::string ParamStr = (*AI)->getNameAsString(); 2708 (*AI)->getType().print(OS, Policy, ParamStr); 2709 } 2710 2711 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 2712 if (FT->isVariadic()) { 2713 if (!BD->param_empty()) OS << ", "; 2714 OS << "..."; 2715 } 2716 OS << ')'; 2717 } 2718 OS << "{ }"; 2719} 2720 2721void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { 2722 PrintExpr(Node->getSourceExpr()); 2723} 2724 2725void StmtPrinter::VisitTypoExpr(TypoExpr *Node) { 2726 // TODO: Print something reasonable for a TypoExpr, if necessary. 2727 llvm_unreachable("Cannot print TypoExpr nodes"); 2728} 2729 2730void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { 2731 OS << "__builtin_astype("; 2732 PrintExpr(Node->getSrcExpr()); 2733 OS << ", "; 2734 Node->getType().print(OS, Policy); 2735 OS << ")"; 2736} 2737 2738//===----------------------------------------------------------------------===// 2739// Stmt method implementations 2740//===----------------------------------------------------------------------===// 2741 2742void Stmt::dumpPretty(const ASTContext &Context) const { 2743 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts())); 2744} 2745 2746void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper, 2747 const PrintingPolicy &Policy, unsigned Indentation, 2748 const ASTContext *Context) const { 2749 StmtPrinter P(OS, Helper, Policy, Indentation, Context); 2750 P.Visit(const_cast<Stmt*>(this)); 2751} 2752 2753//===----------------------------------------------------------------------===// 2754// PrinterHelper 2755//===----------------------------------------------------------------------===// 2756 2757// Implement virtual destructor. 2758PrinterHelper::~PrinterHelper() {} 2759