clang 17.0.0git
StmtPrinter.cpp
Go to the documentation of this file.
1//===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
10// pretty print the AST back out to C code.
11//
12//===----------------------------------------------------------------------===//
13
15#include "clang/AST/Attr.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
22#include "clang/AST/Expr.h"
23#include "clang/AST/ExprCXX.h"
24#include "clang/AST/ExprObjC.h"
29#include "clang/AST/Stmt.h"
30#include "clang/AST/StmtCXX.h"
31#include "clang/AST/StmtObjC.h"
35#include "clang/AST/Type.h"
40#include "clang/Basic/LLVM.h"
41#include "clang/Basic/Lambda.h"
46#include "clang/Lex/Lexer.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/ADT/SmallString.h"
49#include "llvm/ADT/SmallVector.h"
50#include "llvm/ADT/StringExtras.h"
51#include "llvm/ADT/StringRef.h"
52#include "llvm/Support/Casting.h"
53#include "llvm/Support/Compiler.h"
54#include "llvm/Support/ErrorHandling.h"
55#include "llvm/Support/raw_ostream.h"
56#include <cassert>
57#include <optional>
58#include <string>
59
60using namespace clang;
61
62//===----------------------------------------------------------------------===//
63// StmtPrinter Visitor
64//===----------------------------------------------------------------------===//
65
66namespace {
67
68 class StmtPrinter : public StmtVisitor<StmtPrinter> {
69 raw_ostream &OS;
70 unsigned IndentLevel;
71 PrinterHelper* Helper;
72 PrintingPolicy Policy;
73 std::string NL;
74 const ASTContext *Context;
75
76 public:
77 StmtPrinter(raw_ostream &os, PrinterHelper *helper,
78 const PrintingPolicy &Policy, unsigned Indentation = 0,
79 StringRef NL = "\n", const ASTContext *Context = nullptr)
80 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
81 NL(NL), Context(Context) {}
82
83 void PrintStmt(Stmt *S) { PrintStmt(S, Policy.Indentation); }
84
85 void PrintStmt(Stmt *S, int SubIndent) {
86 IndentLevel += SubIndent;
87 if (S && isa<Expr>(S)) {
88 // If this is an expr used in a stmt context, indent and newline it.
89 Indent();
90 Visit(S);
91 OS << ";" << NL;
92 } else if (S) {
93 Visit(S);
94 } else {
95 Indent() << "<<<NULL STATEMENT>>>" << NL;
96 }
97 IndentLevel -= SubIndent;
98 }
99
100 void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {
101 // FIXME: Cope better with odd prefix widths.
102 IndentLevel += (PrefixWidth + 1) / 2;
103 if (auto *DS = dyn_cast<DeclStmt>(S))
104 PrintRawDeclStmt(DS);
105 else
106 PrintExpr(cast<Expr>(S));
107 OS << "; ";
108 IndentLevel -= (PrefixWidth + 1) / 2;
109 }
110
111 void PrintControlledStmt(Stmt *S) {
112 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
113 OS << " ";
114 PrintRawCompoundStmt(CS);
115 OS << NL;
116 } else {
117 OS << NL;
118 PrintStmt(S);
119 }
120 }
121
122 void PrintRawCompoundStmt(CompoundStmt *S);
123 void PrintRawDecl(Decl *D);
124 void PrintRawDeclStmt(const DeclStmt *S);
125 void PrintRawIfStmt(IfStmt *If);
126 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
127 void PrintCallArgs(CallExpr *E);
128 void PrintRawSEHExceptHandler(SEHExceptStmt *S);
129 void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
130 void PrintOMPExecutableDirective(OMPExecutableDirective *S,
131 bool ForceNoStmt = false);
132 void PrintFPPragmas(CompoundStmt *S);
133
134 void PrintExpr(Expr *E) {
135 if (E)
136 Visit(E);
137 else
138 OS << "<null expr>";
139 }
140
141 raw_ostream &Indent(int Delta = 0) {
142 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
143 OS << " ";
144 return OS;
145 }
146
147 void Visit(Stmt* S) {
148 if (Helper && Helper->handledStmt(S,OS))
149 return;
151 }
152
153 void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
154 Indent() << "<<unknown stmt type>>" << NL;
155 }
156
157 void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
158 OS << "<<unknown expr type>>";
159 }
160
161 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
162
163#define ABSTRACT_STMT(CLASS)
164#define STMT(CLASS, PARENT) \
165 void Visit##CLASS(CLASS *Node);
166#include "clang/AST/StmtNodes.inc"
167 };
168
169} // namespace
170
171//===----------------------------------------------------------------------===//
172// Stmt printing methods.
173//===----------------------------------------------------------------------===//
174
175/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
176/// with no newline after the }.
177void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
178 OS << "{" << NL;
179 PrintFPPragmas(Node);
180 for (auto *I : Node->body())
181 PrintStmt(I);
182
183 Indent() << "}";
184}
185
186void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {
187 if (!S->hasStoredFPFeatures())
188 return;
189 FPOptionsOverride FPO = S->getStoredFPFeatures();
190 bool FEnvAccess = false;
191 if (FPO.hasAllowFEnvAccessOverride()) {
192 FEnvAccess = FPO.getAllowFEnvAccessOverride();
193 Indent() << "#pragma STDC FENV_ACCESS " << (FEnvAccess ? "ON" : "OFF")
194 << NL;
195 }
196 if (FPO.hasSpecifiedExceptionModeOverride()) {
198 FPO.getSpecifiedExceptionModeOverride();
199 if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
200 Indent() << "#pragma clang fp exceptions(";
201 switch (FPO.getSpecifiedExceptionModeOverride()) {
202 default:
203 break;
205 OS << "ignore";
206 break;
208 OS << "maytrap";
209 break;
211 OS << "strict";
212 break;
213 }
214 OS << ")\n";
215 }
216 }
217 if (FPO.hasConstRoundingModeOverride()) {
218 LangOptions::RoundingMode RM = FPO.getConstRoundingModeOverride();
219 Indent() << "#pragma STDC FENV_ROUND ";
220 switch (RM) {
221 case llvm::RoundingMode::TowardZero:
222 OS << "FE_TOWARDZERO";
223 break;
224 case llvm::RoundingMode::NearestTiesToEven:
225 OS << "FE_TONEAREST";
226 break;
227 case llvm::RoundingMode::TowardPositive:
228 OS << "FE_UPWARD";
229 break;
230 case llvm::RoundingMode::TowardNegative:
231 OS << "FE_DOWNWARD";
232 break;
233 case llvm::RoundingMode::NearestTiesToAway:
234 OS << "FE_TONEARESTFROMZERO";
235 break;
236 case llvm::RoundingMode::Dynamic:
237 OS << "FE_DYNAMIC";
238 break;
239 default:
240 llvm_unreachable("Invalid rounding mode");
241 }
242 OS << NL;
243 }
244}
245
246void StmtPrinter::PrintRawDecl(Decl *D) {
247 D->print(OS, Policy, IndentLevel);
248}
249
250void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
251 SmallVector<Decl *, 2> Decls(S->decls());
252 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
253}
254
255void StmtPrinter::VisitNullStmt(NullStmt *Node) {
256 Indent() << ";" << NL;
257}
258
259void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
260 Indent();
261 PrintRawDeclStmt(Node);
262 OS << ";" << NL;
263}
264
265void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
266 Indent();
267 PrintRawCompoundStmt(Node);
268 OS << "" << NL;
269}
270
271void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
272 Indent(-1) << "case ";
273 PrintExpr(Node->getLHS());
274 if (Node->getRHS()) {
275 OS << " ... ";
276 PrintExpr(Node->getRHS());
277 }
278 OS << ":" << NL;
279
280 PrintStmt(Node->getSubStmt(), 0);
281}
282
283void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
284 Indent(-1) << "default:" << NL;
285 PrintStmt(Node->getSubStmt(), 0);
286}
287
288void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
289 Indent(-1) << Node->getName() << ":" << NL;
290 PrintStmt(Node->getSubStmt(), 0);
291}
292
293void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
294 for (const auto *Attr : Node->getAttrs()) {
295 Attr->printPretty(OS, Policy);
296 }
297
298 PrintStmt(Node->getSubStmt(), 0);
299}
300
301void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
302 if (If->isConsteval()) {
303 OS << "if ";
304 if (If->isNegatedConsteval())
305 OS << "!";
306 OS << "consteval";
307 OS << NL;
308 PrintStmt(If->getThen());
309 if (Stmt *Else = If->getElse()) {
310 Indent();
311 OS << "else";
312 PrintStmt(Else);
313 OS << NL;
314 }
315 return;
316 }
317
318 OS << "if (";
319 if (If->getInit())
320 PrintInitStmt(If->getInit(), 4);
321 if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
322 PrintRawDeclStmt(DS);
323 else
324 PrintExpr(If->getCond());
325 OS << ')';
326
327 if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
328 OS << ' ';
329 PrintRawCompoundStmt(CS);
330 OS << (If->getElse() ? " " : NL);
331 } else {
332 OS << NL;
333 PrintStmt(If->getThen());
334 if (If->getElse()) Indent();
335 }
336
337 if (Stmt *Else = If->getElse()) {
338 OS << "else";
339
340 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
341 OS << ' ';
342 PrintRawCompoundStmt(CS);
343 OS << NL;
344 } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
345 OS << ' ';
346 PrintRawIfStmt(ElseIf);
347 } else {
348 OS << NL;
349 PrintStmt(If->getElse());
350 }
351 }
352}
353
354void StmtPrinter::VisitIfStmt(IfStmt *If) {
355 Indent();
356 PrintRawIfStmt(If);
357}
358
359void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
360 Indent() << "switch (";
361 if (Node->getInit())
362 PrintInitStmt(Node->getInit(), 8);
363 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
364 PrintRawDeclStmt(DS);
365 else
366 PrintExpr(Node->getCond());
367 OS << ")";
368 PrintControlledStmt(Node->getBody());
369}
370
371void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
372 Indent() << "while (";
373 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
374 PrintRawDeclStmt(DS);
375 else
376 PrintExpr(Node->getCond());
377 OS << ")" << NL;
378 PrintStmt(Node->getBody());
379}
380
381void StmtPrinter::VisitDoStmt(DoStmt *Node) {
382 Indent() << "do ";
383 if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
384 PrintRawCompoundStmt(CS);
385 OS << " ";
386 } else {
387 OS << NL;
388 PrintStmt(Node->getBody());
389 Indent();
390 }
391
392 OS << "while (";
393 PrintExpr(Node->getCond());
394 OS << ");" << NL;
395}
396
397void StmtPrinter::VisitForStmt(ForStmt *Node) {
398 Indent() << "for (";
399 if (Node->getInit())
400 PrintInitStmt(Node->getInit(), 5);
401 else
402 OS << (Node->getCond() ? "; " : ";");
403 if (Node->getCond())
404 PrintExpr(Node->getCond());
405 OS << ";";
406 if (Node->getInc()) {
407 OS << " ";
408 PrintExpr(Node->getInc());
409 }
410 OS << ")";
411 PrintControlledStmt(Node->getBody());
412}
413
414void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
415 Indent() << "for (";
416 if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
417 PrintRawDeclStmt(DS);
418 else
419 PrintExpr(cast<Expr>(Node->getElement()));
420 OS << " in ";
421 PrintExpr(Node->getCollection());
422 OS << ")";
423 PrintControlledStmt(Node->getBody());
424}
425
426void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
427 Indent() << "for (";
428 if (Node->getInit())
429 PrintInitStmt(Node->getInit(), 5);
430 PrintingPolicy SubPolicy(Policy);
431 SubPolicy.SuppressInitializers = true;
432 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
433 OS << " : ";
434 PrintExpr(Node->getRangeInit());
435 OS << ")";
436 PrintControlledStmt(Node->getBody());
437}
438
439void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
440 Indent();
441 if (Node->isIfExists())
442 OS << "__if_exists (";
443 else
444 OS << "__if_not_exists (";
445
446 if (NestedNameSpecifier *Qualifier
447 = Node->getQualifierLoc().getNestedNameSpecifier())
448 Qualifier->print(OS, Policy);
449
450 OS << Node->getNameInfo() << ") ";
451
452 PrintRawCompoundStmt(Node->getSubStmt());
453}
454
455void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
456 Indent() << "goto " << Node->getLabel()->getName() << ";";
457 if (Policy.IncludeNewlines) OS << NL;
458}
459
460void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
461 Indent() << "goto *";
462 PrintExpr(Node->getTarget());
463 OS << ";";
464 if (Policy.IncludeNewlines) OS << NL;
465}
466
467void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
468 Indent() << "continue;";
469 if (Policy.IncludeNewlines) OS << NL;
470}
471
472void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
473 Indent() << "break;";
474 if (Policy.IncludeNewlines) OS << NL;
475}
476
477void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
478 Indent() << "return";
479 if (Node->getRetValue()) {
480 OS << " ";
481 PrintExpr(Node->getRetValue());
482 }
483 OS << ";";
484 if (Policy.IncludeNewlines) OS << NL;
485}
486
487void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
488 Indent() << "asm ";
489
490 if (Node->isVolatile())
491 OS << "volatile ";
492
493 if (Node->isAsmGoto())
494 OS << "goto ";
495
496 OS << "(";
497 VisitStringLiteral(Node->getAsmString());
498
499 // Outputs
500 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
501 Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)
502 OS << " : ";
503
504 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
505 if (i != 0)
506 OS << ", ";
507
508 if (!Node->getOutputName(i).empty()) {
509 OS << '[';
510 OS << Node->getOutputName(i);
511 OS << "] ";
512 }
513
514 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
515 OS << " (";
516 Visit(Node->getOutputExpr(i));
517 OS << ")";
518 }
519
520 // Inputs
521 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||
522 Node->getNumLabels() != 0)
523 OS << " : ";
524
525 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
526 if (i != 0)
527 OS << ", ";
528
529 if (!Node->getInputName(i).empty()) {
530 OS << '[';
531 OS << Node->getInputName(i);
532 OS << "] ";
533 }
534
535 VisitStringLiteral(Node->getInputConstraintLiteral(i));
536 OS << " (";
537 Visit(Node->getInputExpr(i));
538 OS << ")";
539 }
540
541 // Clobbers
542 if (Node->getNumClobbers() != 0 || Node->getNumLabels())
543 OS << " : ";
544
545 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
546 if (i != 0)
547 OS << ", ";
548
549 VisitStringLiteral(Node->getClobberStringLiteral(i));
550 }
551
552 // Labels
553 if (Node->getNumLabels() != 0)
554 OS << " : ";
555
556 for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {
557 if (i != 0)
558 OS << ", ";
559 OS << Node->getLabelName(i);
560 }
561
562 OS << ");";
563 if (Policy.IncludeNewlines) OS << NL;
564}
565
566void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
567 // FIXME: Implement MS style inline asm statement printer.
568 Indent() << "__asm ";
569 if (Node->hasBraces())
570 OS << "{" << NL;
571 OS << Node->getAsmString() << NL;
572 if (Node->hasBraces())
573 Indent() << "}" << NL;
574}
575
576void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
577 PrintStmt(Node->getCapturedDecl()->getBody());
578}
579
580void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
581 Indent() << "@try";
582 if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
583 PrintRawCompoundStmt(TS);
584 OS << NL;
585 }
586
587 for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) {
588 Indent() << "@catch(";
589 if (Decl *DS = catchStmt->getCatchParamDecl())
590 PrintRawDecl(DS);
591 OS << ")";
592 if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
593 PrintRawCompoundStmt(CS);
594 OS << NL;
595 }
596 }
597
598 if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
599 Indent() << "@finally";
600 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
601 OS << NL;
602 }
603}
604
605void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
606}
607
608void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
609 Indent() << "@catch (...) { /* todo */ } " << NL;
610}
611
612void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
613 Indent() << "@throw";
614 if (Node->getThrowExpr()) {
615 OS << " ";
616 PrintExpr(Node->getThrowExpr());
617 }
618 OS << ";" << NL;
619}
620
621void StmtPrinter::VisitObjCAvailabilityCheckExpr(
623 OS << "@available(...)";
624}
625
626void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
627 Indent() << "@synchronized (";
628 PrintExpr(Node->getSynchExpr());
629 OS << ")";
630 PrintRawCompoundStmt(Node->getSynchBody());
631 OS << NL;
632}
633
634void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
635 Indent() << "@autoreleasepool";
636 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt()));
637 OS << NL;
638}
639
640void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
641 OS << "catch (";
642 if (Decl *ExDecl = Node->getExceptionDecl())
643 PrintRawDecl(ExDecl);
644 else
645 OS << "...";
646 OS << ") ";
647 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
648}
649
650void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
651 Indent();
652 PrintRawCXXCatchStmt(Node);
653 OS << NL;
654}
655
656void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
657 Indent() << "try ";
658 PrintRawCompoundStmt(Node->getTryBlock());
659 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
660 OS << " ";
661 PrintRawCXXCatchStmt(Node->getHandler(i));
662 }
663 OS << NL;
664}
665
666void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
667 Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
668 PrintRawCompoundStmt(Node->getTryBlock());
669 SEHExceptStmt *E = Node->getExceptHandler();
670 SEHFinallyStmt *F = Node->getFinallyHandler();
671 if(E)
672 PrintRawSEHExceptHandler(E);
673 else {
674 assert(F && "Must have a finally block...");
675 PrintRawSEHFinallyStmt(F);
676 }
677 OS << NL;
678}
679
680void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
681 OS << "__finally ";
682 PrintRawCompoundStmt(Node->getBlock());
683 OS << NL;
684}
685
686void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
687 OS << "__except (";
688 VisitExpr(Node->getFilterExpr());
689 OS << ")" << NL;
690 PrintRawCompoundStmt(Node->getBlock());
691 OS << NL;
692}
693
694void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
695 Indent();
696 PrintRawSEHExceptHandler(Node);
697 OS << NL;
698}
699
700void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
701 Indent();
702 PrintRawSEHFinallyStmt(Node);
703 OS << NL;
704}
705
706void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
707 Indent() << "__leave;";
708 if (Policy.IncludeNewlines) OS << NL;
709}
710
711//===----------------------------------------------------------------------===//
712// OpenMP directives printing methods
713//===----------------------------------------------------------------------===//
714
715void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) {
716 PrintStmt(Node->getLoopStmt());
717}
718
719void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
720 bool ForceNoStmt) {
721 OMPClausePrinter Printer(OS, Policy);
722 ArrayRef<OMPClause *> Clauses = S->clauses();
723 for (auto *Clause : Clauses)
724 if (Clause && !Clause->isImplicit()) {
725 OS << ' ';
726 Printer.Visit(Clause);
727 }
728 OS << NL;
729 if (!ForceNoStmt && S->hasAssociatedStmt())
730 PrintStmt(S->getRawStmt());
731}
732
733void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) {
734 Indent() << "#pragma omp metadirective";
735 PrintOMPExecutableDirective(Node);
736}
737
738void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
739 Indent() << "#pragma omp parallel";
740 PrintOMPExecutableDirective(Node);
741}
742
743void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
744 Indent() << "#pragma omp simd";
745 PrintOMPExecutableDirective(Node);
746}
747
748void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {
749 Indent() << "#pragma omp tile";
750 PrintOMPExecutableDirective(Node);
751}
752
753void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {
754 Indent() << "#pragma omp unroll";
755 PrintOMPExecutableDirective(Node);
756}
757
758void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
759 Indent() << "#pragma omp for";
760 PrintOMPExecutableDirective(Node);
761}
762
763void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
764 Indent() << "#pragma omp for simd";
765 PrintOMPExecutableDirective(Node);
766}
767
768void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
769 Indent() << "#pragma omp sections";
770 PrintOMPExecutableDirective(Node);
771}
772
773void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
774 Indent() << "#pragma omp section";
775 PrintOMPExecutableDirective(Node);
776}
777
778void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
779 Indent() << "#pragma omp single";
780 PrintOMPExecutableDirective(Node);
781}
782
783void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
784 Indent() << "#pragma omp master";
785 PrintOMPExecutableDirective(Node);
786}
787
788void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
789 Indent() << "#pragma omp critical";
790 if (Node->getDirectiveName().getName()) {
791 OS << " (";
792 Node->getDirectiveName().printName(OS, Policy);
793 OS << ")";
794 }
795 PrintOMPExecutableDirective(Node);
796}
797
798void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
799 Indent() << "#pragma omp parallel for";
800 PrintOMPExecutableDirective(Node);
801}
802
803void StmtPrinter::VisitOMPParallelForSimdDirective(
805 Indent() << "#pragma omp parallel for simd";
806 PrintOMPExecutableDirective(Node);
807}
808
809void StmtPrinter::VisitOMPParallelMasterDirective(
811 Indent() << "#pragma omp parallel master";
812 PrintOMPExecutableDirective(Node);
813}
814
815void StmtPrinter::VisitOMPParallelMaskedDirective(
817 Indent() << "#pragma omp parallel masked";
818 PrintOMPExecutableDirective(Node);
819}
820
821void StmtPrinter::VisitOMPParallelSectionsDirective(
823 Indent() << "#pragma omp parallel sections";
824 PrintOMPExecutableDirective(Node);
825}
826
827void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
828 Indent() << "#pragma omp task";
829 PrintOMPExecutableDirective(Node);
830}
831
832void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
833 Indent() << "#pragma omp taskyield";
834 PrintOMPExecutableDirective(Node);
835}
836
837void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
838 Indent() << "#pragma omp barrier";
839 PrintOMPExecutableDirective(Node);
840}
841
842void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
843 Indent() << "#pragma omp taskwait";
844 PrintOMPExecutableDirective(Node);
845}
846
847void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
848 Indent() << "#pragma omp error";
849 PrintOMPExecutableDirective(Node);
850}
851
852void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
853 Indent() << "#pragma omp taskgroup";
854 PrintOMPExecutableDirective(Node);
855}
856
857void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
858 Indent() << "#pragma omp flush";
859 PrintOMPExecutableDirective(Node);
860}
861
862void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
863 Indent() << "#pragma omp depobj";
864 PrintOMPExecutableDirective(Node);
865}
866
867void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
868 Indent() << "#pragma omp scan";
869 PrintOMPExecutableDirective(Node);
870}
871
872void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
873 Indent() << "#pragma omp ordered";
874 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
875}
876
877void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
878 Indent() << "#pragma omp atomic";
879 PrintOMPExecutableDirective(Node);
880}
881
882void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
883 Indent() << "#pragma omp target";
884 PrintOMPExecutableDirective(Node);
885}
886
887void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
888 Indent() << "#pragma omp target data";
889 PrintOMPExecutableDirective(Node);
890}
891
892void StmtPrinter::VisitOMPTargetEnterDataDirective(
894 Indent() << "#pragma omp target enter data";
895 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
896}
897
898void StmtPrinter::VisitOMPTargetExitDataDirective(
900 Indent() << "#pragma omp target exit data";
901 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
902}
903
904void StmtPrinter::VisitOMPTargetParallelDirective(
906 Indent() << "#pragma omp target parallel";
907 PrintOMPExecutableDirective(Node);
908}
909
910void StmtPrinter::VisitOMPTargetParallelForDirective(
912 Indent() << "#pragma omp target parallel for";
913 PrintOMPExecutableDirective(Node);
914}
915
916void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
917 Indent() << "#pragma omp teams";
918 PrintOMPExecutableDirective(Node);
919}
920
921void StmtPrinter::VisitOMPCancellationPointDirective(
923 Indent() << "#pragma omp cancellation point "
924 << getOpenMPDirectiveName(Node->getCancelRegion());
925 PrintOMPExecutableDirective(Node);
926}
927
928void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
929 Indent() << "#pragma omp cancel "
930 << getOpenMPDirectiveName(Node->getCancelRegion());
931 PrintOMPExecutableDirective(Node);
932}
933
934void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
935 Indent() << "#pragma omp taskloop";
936 PrintOMPExecutableDirective(Node);
937}
938
939void StmtPrinter::VisitOMPTaskLoopSimdDirective(
941 Indent() << "#pragma omp taskloop simd";
942 PrintOMPExecutableDirective(Node);
943}
944
945void StmtPrinter::VisitOMPMasterTaskLoopDirective(
947 Indent() << "#pragma omp master taskloop";
948 PrintOMPExecutableDirective(Node);
949}
950
951void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
953 Indent() << "#pragma omp masked taskloop";
954 PrintOMPExecutableDirective(Node);
955}
956
957void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
959 Indent() << "#pragma omp master taskloop simd";
960 PrintOMPExecutableDirective(Node);
961}
962
963void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
965 Indent() << "#pragma omp masked taskloop simd";
966 PrintOMPExecutableDirective(Node);
967}
968
969void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
971 Indent() << "#pragma omp parallel master taskloop";
972 PrintOMPExecutableDirective(Node);
973}
974
975void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
977 Indent() << "#pragma omp parallel masked taskloop";
978 PrintOMPExecutableDirective(Node);
979}
980
981void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
983 Indent() << "#pragma omp parallel master taskloop simd";
984 PrintOMPExecutableDirective(Node);
985}
986
987void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
989 Indent() << "#pragma omp parallel masked taskloop simd";
990 PrintOMPExecutableDirective(Node);
991}
992
993void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
994 Indent() << "#pragma omp distribute";
995 PrintOMPExecutableDirective(Node);
996}
997
998void StmtPrinter::VisitOMPTargetUpdateDirective(
1000 Indent() << "#pragma omp target update";
1001 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1002}
1003
1004void StmtPrinter::VisitOMPDistributeParallelForDirective(
1006 Indent() << "#pragma omp distribute parallel for";
1007 PrintOMPExecutableDirective(Node);
1008}
1009
1010void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1012 Indent() << "#pragma omp distribute parallel for simd";
1013 PrintOMPExecutableDirective(Node);
1014}
1015
1016void StmtPrinter::VisitOMPDistributeSimdDirective(
1018 Indent() << "#pragma omp distribute simd";
1019 PrintOMPExecutableDirective(Node);
1020}
1021
1022void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1024 Indent() << "#pragma omp target parallel for simd";
1025 PrintOMPExecutableDirective(Node);
1026}
1027
1028void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1029 Indent() << "#pragma omp target simd";
1030 PrintOMPExecutableDirective(Node);
1031}
1032
1033void StmtPrinter::VisitOMPTeamsDistributeDirective(
1035 Indent() << "#pragma omp teams distribute";
1036 PrintOMPExecutableDirective(Node);
1037}
1038
1039void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1041 Indent() << "#pragma omp teams distribute simd";
1042 PrintOMPExecutableDirective(Node);
1043}
1044
1045void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1047 Indent() << "#pragma omp teams distribute parallel for simd";
1048 PrintOMPExecutableDirective(Node);
1049}
1050
1051void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1053 Indent() << "#pragma omp teams distribute parallel for";
1054 PrintOMPExecutableDirective(Node);
1055}
1056
1057void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1058 Indent() << "#pragma omp target teams";
1059 PrintOMPExecutableDirective(Node);
1060}
1061
1062void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1064 Indent() << "#pragma omp target teams distribute";
1065 PrintOMPExecutableDirective(Node);
1066}
1067
1068void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1070 Indent() << "#pragma omp target teams distribute parallel for";
1071 PrintOMPExecutableDirective(Node);
1072}
1073
1074void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1076 Indent() << "#pragma omp target teams distribute parallel for simd";
1077 PrintOMPExecutableDirective(Node);
1078}
1079
1080void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1082 Indent() << "#pragma omp target teams distribute simd";
1083 PrintOMPExecutableDirective(Node);
1084}
1085
1086void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1087 Indent() << "#pragma omp interop";
1088 PrintOMPExecutableDirective(Node);
1089}
1090
1091void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1092 Indent() << "#pragma omp dispatch";
1093 PrintOMPExecutableDirective(Node);
1094}
1095
1096void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1097 Indent() << "#pragma omp masked";
1098 PrintOMPExecutableDirective(Node);
1099}
1100
1101void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1102 Indent() << "#pragma omp loop";
1103 PrintOMPExecutableDirective(Node);
1104}
1105
1106void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1108 Indent() << "#pragma omp teams loop";
1109 PrintOMPExecutableDirective(Node);
1110}
1111
1112void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1114 Indent() << "#pragma omp target teams loop";
1115 PrintOMPExecutableDirective(Node);
1116}
1117
1118void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1120 Indent() << "#pragma omp parallel loop";
1121 PrintOMPExecutableDirective(Node);
1122}
1123
1124void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1126 Indent() << "#pragma omp target parallel loop";
1127 PrintOMPExecutableDirective(Node);
1128}
1129
1130//===----------------------------------------------------------------------===//
1131// Expr printing methods.
1132//===----------------------------------------------------------------------===//
1133
1134void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1135 OS << Node->getBuiltinStr() << "()";
1136}
1137
1138void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1139 PrintExpr(Node->getSubExpr());
1140}
1141
1142void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1143 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
1144 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1145 return;
1146 }
1147 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) {
1148 TPOD->printAsExpr(OS, Policy);
1149 return;
1150 }
1151 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1152 Qualifier->print(OS, Policy);
1153 if (Node->hasTemplateKeyword())
1154 OS << "template ";
1155 if (Policy.CleanUglifiedParameters &&
1156 isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) &&
1157 Node->getDecl()->getIdentifier())
1158 OS << Node->getDecl()->getIdentifier()->deuglifiedName();
1159 else
1160 Node->getNameInfo().printName(OS, Policy);
1161 if (Node->hasExplicitTemplateArgs()) {
1162 const TemplateParameterList *TPL = nullptr;
1163 if (!Node->hadMultipleCandidates())
1164 if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
1165 TPL = TD->getTemplateParameters();
1166 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1167 }
1168}
1169
1170void StmtPrinter::VisitDependentScopeDeclRefExpr(
1172 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1173 Qualifier->print(OS, Policy);
1174 if (Node->hasTemplateKeyword())
1175 OS << "template ";
1176 OS << Node->getNameInfo();
1177 if (Node->hasExplicitTemplateArgs())
1178 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1179}
1180
1181void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1182 if (Node->getQualifier())
1183 Node->getQualifier()->print(OS, Policy);
1184 if (Node->hasTemplateKeyword())
1185 OS << "template ";
1186 OS << Node->getNameInfo();
1187 if (Node->hasExplicitTemplateArgs())
1188 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1189}
1190
1191static bool isImplicitSelf(const Expr *E) {
1192 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1193 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1194 if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
1195 DRE->getBeginLoc().isInvalid())
1196 return true;
1197 }
1198 }
1199 return false;
1200}
1201
1202void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1203 if (Node->getBase()) {
1204 if (!Policy.SuppressImplicitBase ||
1205 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1206 PrintExpr(Node->getBase());
1207 OS << (Node->isArrow() ? "->" : ".");
1208 }
1209 }
1210 OS << *Node->getDecl();
1211}
1212
1213void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1214 if (Node->isSuperReceiver())
1215 OS << "super.";
1216 else if (Node->isObjectReceiver() && Node->getBase()) {
1217 PrintExpr(Node->getBase());
1218 OS << ".";
1219 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1220 OS << Node->getClassReceiver()->getName() << ".";
1221 }
1222
1223 if (Node->isImplicitProperty()) {
1224 if (const auto *Getter = Node->getImplicitPropertyGetter())
1225 Getter->getSelector().print(OS);
1226 else
1228 Node->getImplicitPropertySetter()->getSelector());
1229 } else
1230 OS << Node->getExplicitProperty()->getName();
1231}
1232
1233void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1234 PrintExpr(Node->getBaseExpr());
1235 OS << "[";
1236 PrintExpr(Node->getKeyExpr());
1237 OS << "]";
1238}
1239
1240void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1242 OS << "__builtin_sycl_unique_stable_name(";
1243 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1244 OS << ")";
1245}
1246
1247void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1248 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1249}
1250
1251void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1252 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1253}
1254
1255/// Prints the given expression using the original source text. Returns true on
1256/// success, false otherwise.
1257static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1258 const ASTContext *Context) {
1259 if (!Context)
1260 return false;
1261 bool Invalid = false;
1262 StringRef Source = Lexer::getSourceText(
1264 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1265 if (!Invalid) {
1266 OS << Source;
1267 return true;
1268 }
1269 return false;
1270}
1271
1272void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1273 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1274 return;
1275 bool isSigned = Node->getType()->isSignedIntegerType();
1276 OS << toString(Node->getValue(), 10, isSigned);
1277
1278 if (isa<BitIntType>(Node->getType())) {
1279 OS << (isSigned ? "wb" : "uwb");
1280 return;
1281 }
1282
1283 // Emit suffixes. Integer literals are always a builtin integer type.
1284 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1285 default: llvm_unreachable("Unexpected type for integer literal!");
1286 case BuiltinType::Char_S:
1287 case BuiltinType::Char_U: OS << "i8"; break;
1288 case BuiltinType::UChar: OS << "Ui8"; break;
1289 case BuiltinType::SChar: OS << "i8"; break;
1290 case BuiltinType::Short: OS << "i16"; break;
1291 case BuiltinType::UShort: OS << "Ui16"; break;
1292 case BuiltinType::Int: break; // no suffix.
1293 case BuiltinType::UInt: OS << 'U'; break;
1294 case BuiltinType::Long: OS << 'L'; break;
1295 case BuiltinType::ULong: OS << "UL"; break;
1296 case BuiltinType::LongLong: OS << "LL"; break;
1297 case BuiltinType::ULongLong: OS << "ULL"; break;
1298 case BuiltinType::Int128:
1299 break; // no suffix.
1300 case BuiltinType::UInt128:
1301 break; // no suffix.
1302 case BuiltinType::WChar_S:
1303 case BuiltinType::WChar_U:
1304 break; // no suffix
1305 }
1306}
1307
1308void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1309 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1310 return;
1311 OS << Node->getValueAsString(/*Radix=*/10);
1312
1313 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1314 default: llvm_unreachable("Unexpected type for fixed point literal!");
1315 case BuiltinType::ShortFract: OS << "hr"; break;
1316 case BuiltinType::ShortAccum: OS << "hk"; break;
1317 case BuiltinType::UShortFract: OS << "uhr"; break;
1318 case BuiltinType::UShortAccum: OS << "uhk"; break;
1319 case BuiltinType::Fract: OS << "r"; break;
1320 case BuiltinType::Accum: OS << "k"; break;
1321 case BuiltinType::UFract: OS << "ur"; break;
1322 case BuiltinType::UAccum: OS << "uk"; break;
1323 case BuiltinType::LongFract: OS << "lr"; break;
1324 case BuiltinType::LongAccum: OS << "lk"; break;
1325 case BuiltinType::ULongFract: OS << "ulr"; break;
1326 case BuiltinType::ULongAccum: OS << "ulk"; break;
1327 }
1328}
1329
1330static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1331 bool PrintSuffix) {
1332 SmallString<16> Str;
1333 Node->getValue().toString(Str);
1334 OS << Str;
1335 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1336 OS << '.'; // Trailing dot in order to separate from ints.
1337
1338 if (!PrintSuffix)
1339 return;
1340
1341 // Emit suffixes. Float literals are always a builtin float type.
1342 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1343 default: llvm_unreachable("Unexpected type for float literal!");
1344 case BuiltinType::Half: break; // FIXME: suffix?
1345 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1346 case BuiltinType::Double: break; // no suffix.
1347 case BuiltinType::Float16: OS << "F16"; break;
1348 case BuiltinType::Float: OS << 'F'; break;
1349 case BuiltinType::LongDouble: OS << 'L'; break;
1350 case BuiltinType::Float128: OS << 'Q'; break;
1351 }
1352}
1353
1354void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1355 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1356 return;
1357 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1358}
1359
1360void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1361 PrintExpr(Node->getSubExpr());
1362 OS << "i";
1363}
1364
1365void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1366 Str->outputString(OS);
1367}
1368
1369void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1370 OS << "(";
1371 PrintExpr(Node->getSubExpr());
1372 OS << ")";
1373}
1374
1375void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1376 if (!Node->isPostfix()) {
1377 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1378
1379 // Print a space if this is an "identifier operator" like __real, or if
1380 // it might be concatenated incorrectly like '+'.
1381 switch (Node->getOpcode()) {
1382 default: break;
1383 case UO_Real:
1384 case UO_Imag:
1385 case UO_Extension:
1386 OS << ' ';
1387 break;
1388 case UO_Plus:
1389 case UO_Minus:
1390 if (isa<UnaryOperator>(Node->getSubExpr()))
1391 OS << ' ';
1392 break;
1393 }
1394 }
1395 PrintExpr(Node->getSubExpr());
1396
1397 if (Node->isPostfix())
1398 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1399}
1400
1401void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1402 OS << "__builtin_offsetof(";
1403 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1404 OS << ", ";
1405 bool PrintedSomething = false;
1406 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1407 OffsetOfNode ON = Node->getComponent(i);
1408 if (ON.getKind() == OffsetOfNode::Array) {
1409 // Array node
1410 OS << "[";
1411 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1412 OS << "]";
1413 PrintedSomething = true;
1414 continue;
1415 }
1416
1417 // Skip implicit base indirections.
1418 if (ON.getKind() == OffsetOfNode::Base)
1419 continue;
1420
1421 // Field or identifier node.
1423 if (!Id)
1424 continue;
1425
1426 if (PrintedSomething)
1427 OS << ".";
1428 else
1429 PrintedSomething = true;
1430 OS << Id->getName();
1431 }
1432 OS << ")";
1433}
1434
1435void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1437 const char *Spelling = getTraitSpelling(Node->getKind());
1438 if (Node->getKind() == UETT_AlignOf) {
1439 if (Policy.Alignof)
1440 Spelling = "alignof";
1441 else if (Policy.UnderscoreAlignof)
1442 Spelling = "_Alignof";
1443 else
1444 Spelling = "__alignof";
1445 }
1446
1447 OS << Spelling;
1448
1449 if (Node->isArgumentType()) {
1450 OS << '(';
1451 Node->getArgumentType().print(OS, Policy);
1452 OS << ')';
1453 } else {
1454 OS << " ";
1455 PrintExpr(Node->getArgumentExpr());
1456 }
1457}
1458
1459void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1460 OS << "_Generic(";
1461 PrintExpr(Node->getControllingExpr());
1462 for (const GenericSelectionExpr::Association Assoc : Node->associations()) {
1463 OS << ", ";
1464 QualType T = Assoc.getType();
1465 if (T.isNull())
1466 OS << "default";
1467 else
1468 T.print(OS, Policy);
1469 OS << ": ";
1470 PrintExpr(Assoc.getAssociationExpr());
1471 }
1472 OS << ")";
1473}
1474
1475void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1476 PrintExpr(Node->getLHS());
1477 OS << "[";
1478 PrintExpr(Node->getRHS());
1479 OS << "]";
1480}
1481
1482void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1483 PrintExpr(Node->getBase());
1484 OS << "[";
1485 PrintExpr(Node->getRowIdx());
1486 OS << "]";
1487 OS << "[";
1488 PrintExpr(Node->getColumnIdx());
1489 OS << "]";
1490}
1491
1492void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
1493 PrintExpr(Node->getBase());
1494 OS << "[";
1495 if (Node->getLowerBound())
1496 PrintExpr(Node->getLowerBound());
1497 if (Node->getColonLocFirst().isValid()) {
1498 OS << ":";
1499 if (Node->getLength())
1500 PrintExpr(Node->getLength());
1501 }
1502 if (Node->getColonLocSecond().isValid()) {
1503 OS << ":";
1504 if (Node->getStride())
1505 PrintExpr(Node->getStride());
1506 }
1507 OS << "]";
1508}
1509
1510void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1511 OS << "(";
1512 for (Expr *E : Node->getDimensions()) {
1513 OS << "[";
1514 PrintExpr(E);
1515 OS << "]";
1516 }
1517 OS << ")";
1518 PrintExpr(Node->getBase());
1519}
1520
1521void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1522 OS << "iterator(";
1523 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1524 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1525 VD->getType().print(OS, Policy);
1526 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1527 OS << " " << VD->getName() << " = ";
1528 PrintExpr(Range.Begin);
1529 OS << ":";
1530 PrintExpr(Range.End);
1531 if (Range.Step) {
1532 OS << ":";
1533 PrintExpr(Range.Step);
1534 }
1535 if (I < E - 1)
1536 OS << ", ";
1537 }
1538 OS << ")";
1539}
1540
1541void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1542 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1543 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1544 // Don't print any defaulted arguments
1545 break;
1546 }
1547
1548 if (i) OS << ", ";
1549 PrintExpr(Call->getArg(i));
1550 }
1551}
1552
1553void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1554 PrintExpr(Call->getCallee());
1555 OS << "(";
1556 PrintCallArgs(Call);
1557 OS << ")";
1558}
1559
1560static bool isImplicitThis(const Expr *E) {
1561 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1562 return TE->isImplicit();
1563 return false;
1564}
1565
1566void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1567 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1568 PrintExpr(Node->getBase());
1569
1570 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1571 FieldDecl *ParentDecl =
1572 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1573 : nullptr;
1574
1575 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1576 OS << (Node->isArrow() ? "->" : ".");
1577 }
1578
1579 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1580 if (FD->isAnonymousStructOrUnion())
1581 return;
1582
1583 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1584 Qualifier->print(OS, Policy);
1585 if (Node->hasTemplateKeyword())
1586 OS << "template ";
1587 OS << Node->getMemberNameInfo();
1588 const TemplateParameterList *TPL = nullptr;
1589 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1590 if (!Node->hadMultipleCandidates())
1591 if (auto *FTD = FD->getPrimaryTemplate())
1592 TPL = FTD->getTemplateParameters();
1593 } else if (auto *VTSD =
1594 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1595 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1596 if (Node->hasExplicitTemplateArgs())
1597 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1598}
1599
1600void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1601 PrintExpr(Node->getBase());
1602 OS << (Node->isArrow() ? "->isa" : ".isa");
1603}
1604
1605void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1606 PrintExpr(Node->getBase());
1607 OS << ".";
1608 OS << Node->getAccessor().getName();
1609}
1610
1611void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1612 OS << '(';
1613 Node->getTypeAsWritten().print(OS, Policy);
1614 OS << ')';
1615 PrintExpr(Node->getSubExpr());
1616}
1617
1618void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1619 OS << '(';
1620 Node->getType().print(OS, Policy);
1621 OS << ')';
1622 PrintExpr(Node->getInitializer());
1623}
1624
1625void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1626 // No need to print anything, simply forward to the subexpression.
1627 PrintExpr(Node->getSubExpr());
1628}
1629
1630void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1631 PrintExpr(Node->getLHS());
1632 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1633 PrintExpr(Node->getRHS());
1634}
1635
1636void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1637 PrintExpr(Node->getLHS());
1638 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1639 PrintExpr(Node->getRHS());
1640}
1641
1642void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1643 PrintExpr(Node->getCond());
1644 OS << " ? ";
1645 PrintExpr(Node->getLHS());
1646 OS << " : ";
1647 PrintExpr(Node->getRHS());
1648}
1649
1650// GNU extensions.
1651
1652void
1653StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1654 PrintExpr(Node->getCommon());
1655 OS << " ?: ";
1656 PrintExpr(Node->getFalseExpr());
1657}
1658
1659void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1660 OS << "&&" << Node->getLabel()->getName();
1661}
1662
1663void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1664 OS << "(";
1665 PrintRawCompoundStmt(E->getSubStmt());
1666 OS << ")";
1667}
1668
1669void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1670 OS << "__builtin_choose_expr(";
1671 PrintExpr(Node->getCond());
1672 OS << ", ";
1673 PrintExpr(Node->getLHS());
1674 OS << ", ";
1675 PrintExpr(Node->getRHS());
1676 OS << ")";
1677}
1678
1679void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1680 OS << "__null";
1681}
1682
1683void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1684 OS << "__builtin_shufflevector(";
1685 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1686 if (i) OS << ", ";
1687 PrintExpr(Node->getExpr(i));
1688 }
1689 OS << ")";
1690}
1691
1692void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1693 OS << "__builtin_convertvector(";
1694 PrintExpr(Node->getSrcExpr());
1695 OS << ", ";
1696 Node->getType().print(OS, Policy);
1697 OS << ")";
1698}
1699
1700void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1701 if (Node->getSyntacticForm()) {
1702 Visit(Node->getSyntacticForm());
1703 return;
1704 }
1705
1706 OS << "{";
1707 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1708 if (i) OS << ", ";
1709 if (Node->getInit(i))
1710 PrintExpr(Node->getInit(i));
1711 else
1712 OS << "{}";
1713 }
1714 OS << "}";
1715}
1716
1717void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1718 // There's no way to express this expression in any of our supported
1719 // languages, so just emit something terse and (hopefully) clear.
1720 OS << "{";
1721 PrintExpr(Node->getSubExpr());
1722 OS << "}";
1723}
1724
1725void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1726 OS << "*";
1727}
1728
1729void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1730 OS << "(";
1731 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1732 if (i) OS << ", ";
1733 PrintExpr(Node->getExpr(i));
1734 }
1735 OS << ")";
1736}
1737
1738void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1739 bool NeedsEquals = true;
1740 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1741 if (D.isFieldDesignator()) {
1742 if (D.getDotLoc().isInvalid()) {
1743 if (const IdentifierInfo *II = D.getFieldName()) {
1744 OS << II->getName() << ":";
1745 NeedsEquals = false;
1746 }
1747 } else {
1748 OS << "." << D.getFieldName()->getName();
1749 }
1750 } else {
1751 OS << "[";
1752 if (D.isArrayDesignator()) {
1753 PrintExpr(Node->getArrayIndex(D));
1754 } else {
1755 PrintExpr(Node->getArrayRangeStart(D));
1756 OS << " ... ";
1757 PrintExpr(Node->getArrayRangeEnd(D));
1758 }
1759 OS << "]";
1760 }
1761 }
1762
1763 if (NeedsEquals)
1764 OS << " = ";
1765 else
1766 OS << " ";
1767 PrintExpr(Node->getInit());
1768}
1769
1770void StmtPrinter::VisitDesignatedInitUpdateExpr(
1772 OS << "{";
1773 OS << "/*base*/";
1774 PrintExpr(Node->getBase());
1775 OS << ", ";
1776
1777 OS << "/*updater*/";
1778 PrintExpr(Node->getUpdater());
1779 OS << "}";
1780}
1781
1782void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1783 OS << "/*no init*/";
1784}
1785
1786void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1787 if (Node->getType()->getAsCXXRecordDecl()) {
1788 OS << "/*implicit*/";
1789 Node->getType().print(OS, Policy);
1790 OS << "()";
1791 } else {
1792 OS << "/*implicit*/(";
1793 Node->getType().print(OS, Policy);
1794 OS << ')';
1795 if (Node->getType()->isRecordType())
1796 OS << "{}";
1797 else
1798 OS << 0;
1799 }
1800}
1801
1802void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1803 OS << "__builtin_va_arg(";
1804 PrintExpr(Node->getSubExpr());
1805 OS << ", ";
1806 Node->getType().print(OS, Policy);
1807 OS << ")";
1808}
1809
1810void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1811 PrintExpr(Node->getSyntacticForm());
1812}
1813
1814void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1815 const char *Name = nullptr;
1816 switch (Node->getOp()) {
1817#define BUILTIN(ID, TYPE, ATTRS)
1818#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1819 case AtomicExpr::AO ## ID: \
1820 Name = #ID "("; \
1821 break;
1822#include "clang/Basic/Builtins.def"
1823 }
1824 OS << Name;
1825
1826 // AtomicExpr stores its subexpressions in a permuted order.
1827 PrintExpr(Node->getPtr());
1828 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1829 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1830 Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
1831 Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
1832 OS << ", ";
1833 PrintExpr(Node->getVal1());
1834 }
1835 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1836 Node->isCmpXChg()) {
1837 OS << ", ";
1838 PrintExpr(Node->getVal2());
1839 }
1840 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1841 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1842 OS << ", ";
1843 PrintExpr(Node->getWeak());
1844 }
1845 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1846 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1847 OS << ", ";
1848 PrintExpr(Node->getOrder());
1849 }
1850 if (Node->isCmpXChg()) {
1851 OS << ", ";
1852 PrintExpr(Node->getOrderFail());
1853 }
1854 OS << ")";
1855}
1856
1857// C++
1858void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1859 OverloadedOperatorKind Kind = Node->getOperator();
1860 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1861 if (Node->getNumArgs() == 1) {
1862 OS << getOperatorSpelling(Kind) << ' ';
1863 PrintExpr(Node->getArg(0));
1864 } else {
1865 PrintExpr(Node->getArg(0));
1866 OS << ' ' << getOperatorSpelling(Kind);
1867 }
1868 } else if (Kind == OO_Arrow) {
1869 PrintExpr(Node->getArg(0));
1870 } else if (Kind == OO_Call || Kind == OO_Subscript) {
1871 PrintExpr(Node->getArg(0));
1872 OS << (Kind == OO_Call ? '(' : '[');
1873 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1874 if (ArgIdx > 1)
1875 OS << ", ";
1876 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1877 PrintExpr(Node->getArg(ArgIdx));
1878 }
1879 OS << (Kind == OO_Call ? ')' : ']');
1880 } else if (Node->getNumArgs() == 1) {
1881 OS << getOperatorSpelling(Kind) << ' ';
1882 PrintExpr(Node->getArg(0));
1883 } else if (Node->getNumArgs() == 2) {
1884 PrintExpr(Node->getArg(0));
1885 OS << ' ' << getOperatorSpelling(Kind) << ' ';
1886 PrintExpr(Node->getArg(1));
1887 } else {
1888 llvm_unreachable("unknown overloaded operator");
1889 }
1890}
1891
1892void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1893 // If we have a conversion operator call only print the argument.
1894 CXXMethodDecl *MD = Node->getMethodDecl();
1895 if (MD && isa<CXXConversionDecl>(MD)) {
1896 PrintExpr(Node->getImplicitObjectArgument());
1897 return;
1898 }
1899 VisitCallExpr(cast<CallExpr>(Node));
1900}
1901
1902void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
1903 PrintExpr(Node->getCallee());
1904 OS << "<<<";
1905 PrintCallArgs(Node->getConfig());
1906 OS << ">>>(";
1907 PrintCallArgs(Node);
1908 OS << ")";
1909}
1910
1911void StmtPrinter::VisitCXXRewrittenBinaryOperator(
1914 Node->getDecomposedForm();
1915 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
1916 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
1917 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
1918}
1919
1920void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1921 OS << Node->getCastName() << '<';
1922 Node->getTypeAsWritten().print(OS, Policy);
1923 OS << ">(";
1924 PrintExpr(Node->getSubExpr());
1925 OS << ")";
1926}
1927
1928void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1929 VisitCXXNamedCastExpr(Node);
1930}
1931
1932void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1933 VisitCXXNamedCastExpr(Node);
1934}
1935
1936void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
1937 VisitCXXNamedCastExpr(Node);
1938}
1939
1940void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
1941 VisitCXXNamedCastExpr(Node);
1942}
1943
1944void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
1945 OS << "__builtin_bit_cast(";
1946 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
1947 OS << ", ";
1948 PrintExpr(Node->getSubExpr());
1949 OS << ")";
1950}
1951
1952void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
1953 VisitCXXNamedCastExpr(Node);
1954}
1955
1956void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
1957 OS << "typeid(";
1958 if (Node->isTypeOperand()) {
1959 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1960 } else {
1961 PrintExpr(Node->getExprOperand());
1962 }
1963 OS << ")";
1964}
1965
1966void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
1967 OS << "__uuidof(";
1968 if (Node->isTypeOperand()) {
1969 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1970 } else {
1971 PrintExpr(Node->getExprOperand());
1972 }
1973 OS << ")";
1974}
1975
1976void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
1977 PrintExpr(Node->getBaseExpr());
1978 if (Node->isArrow())
1979 OS << "->";
1980 else
1981 OS << ".";
1982 if (NestedNameSpecifier *Qualifier =
1983 Node->getQualifierLoc().getNestedNameSpecifier())
1984 Qualifier->print(OS, Policy);
1985 OS << Node->getPropertyDecl()->getDeclName();
1986}
1987
1988void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
1989 PrintExpr(Node->getBase());
1990 OS << "[";
1991 PrintExpr(Node->getIdx());
1992 OS << "]";
1993}
1994
1995void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
1996 switch (Node->getLiteralOperatorKind()) {
1998 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
1999 break;
2001 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2002 const TemplateArgumentList *Args =
2003 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2004 assert(Args);
2005
2006 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2007 const TemplateParameterList *TPL = nullptr;
2008 if (!DRE->hadMultipleCandidates())
2009 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2010 TPL = TD->getTemplateParameters();
2011 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2012 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2013 OS << "()";
2014 return;
2015 }
2016
2017 const TemplateArgument &Pack = Args->get(0);
2018 for (const auto &P : Pack.pack_elements()) {
2019 char C = (char)P.getAsIntegral().getZExtValue();
2020 OS << C;
2021 }
2022 break;
2023 }
2025 // Print integer literal without suffix.
2026 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2027 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2028 break;
2029 }
2031 // Print floating literal without suffix.
2032 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
2033 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2034 break;
2035 }
2038 PrintExpr(Node->getCookedLiteral());
2039 break;
2040 }
2041 OS << Node->getUDSuffix()->getName();
2042}
2043
2044void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2045 OS << (Node->getValue() ? "true" : "false");
2046}
2047
2048void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2049 OS << "nullptr";
2050}
2051
2052void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2053 OS << "this";
2054}
2055
2056void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2057 if (!Node->getSubExpr())
2058 OS << "throw";
2059 else {
2060 OS << "throw ";
2061 PrintExpr(Node->getSubExpr());
2062 }
2063}
2064
2065void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2066 // Nothing to print: we picked up the default argument.
2067}
2068
2069void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2070 // Nothing to print: we picked up the default initializer.
2071}
2072
2073void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2074 auto TargetType = Node->getType();
2075 auto *Auto = TargetType->getContainedDeducedType();
2076 bool Bare = Auto && Auto->isDeduced();
2077
2078 // Parenthesize deduced casts.
2079 if (Bare)
2080 OS << '(';
2081 TargetType.print(OS, Policy);
2082 if (Bare)
2083 OS << ')';
2084
2085 // No extra braces surrounding the inner construct.
2086 if (!Node->isListInitialization())
2087 OS << '(';
2088 PrintExpr(Node->getSubExpr());
2089 if (!Node->isListInitialization())
2090 OS << ')';
2091}
2092
2093void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2094 PrintExpr(Node->getSubExpr());
2095}
2096
2097void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2098 Node->getType().print(OS, Policy);
2099 if (Node->isStdInitListInitialization())
2100 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2101 else if (Node->isListInitialization())
2102 OS << "{";
2103 else
2104 OS << "(";
2105 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2106 ArgEnd = Node->arg_end();
2107 Arg != ArgEnd; ++Arg) {
2108 if ((*Arg)->isDefaultArgument())
2109 break;
2110 if (Arg != Node->arg_begin())
2111 OS << ", ";
2112 PrintExpr(*Arg);
2113 }
2114 if (Node->isStdInitListInitialization())
2115 /* See above. */;
2116 else if (Node->isListInitialization())
2117 OS << "}";
2118 else
2119 OS << ")";
2120}
2121
2122void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2123 OS << '[';
2124 bool NeedComma = false;
2125 switch (Node->getCaptureDefault()) {
2126 case LCD_None:
2127 break;
2128
2129 case LCD_ByCopy:
2130 OS << '=';
2131 NeedComma = true;
2132 break;
2133
2134 case LCD_ByRef:
2135 OS << '&';
2136 NeedComma = true;
2137 break;
2138 }
2139 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
2140 CEnd = Node->explicit_capture_end();
2141 C != CEnd;
2142 ++C) {
2143 if (C->capturesVLAType())
2144 continue;
2145
2146 if (NeedComma)
2147 OS << ", ";
2148 NeedComma = true;
2149
2150 switch (C->getCaptureKind()) {
2151 case LCK_This:
2152 OS << "this";
2153 break;
2154
2155 case LCK_StarThis:
2156 OS << "*this";
2157 break;
2158
2159 case LCK_ByRef:
2160 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2161 OS << '&';
2162 OS << C->getCapturedVar()->getName();
2163 break;
2164
2165 case LCK_ByCopy:
2166 OS << C->getCapturedVar()->getName();
2167 break;
2168
2169 case LCK_VLAType:
2170 llvm_unreachable("VLA type in explicit captures.");
2171 }
2172
2173 if (C->isPackExpansion())
2174 OS << "...";
2175
2176 if (Node->isInitCapture(C)) {
2177 // Init captures are always VarDecl.
2178 auto *D = cast<VarDecl>(C->getCapturedVar());
2179
2180 llvm::StringRef Pre;
2181 llvm::StringRef Post;
2182 if (D->getInitStyle() == VarDecl::CallInit &&
2183 !isa<ParenListExpr>(D->getInit())) {
2184 Pre = "(";
2185 Post = ")";
2186 } else if (D->getInitStyle() == VarDecl::CInit) {
2187 Pre = " = ";
2188 }
2189
2190 OS << Pre;
2191 PrintExpr(D->getInit());
2192 OS << Post;
2193 }
2194 }
2195 OS << ']';
2196
2197 if (!Node->getExplicitTemplateParameters().empty()) {
2198 Node->getTemplateParameterList()->print(
2199 OS, Node->getLambdaClass()->getASTContext(),
2200 /*OmitTemplateKW*/true);
2201 }
2202
2203 if (Node->hasExplicitParameters()) {
2204 OS << '(';
2205 CXXMethodDecl *Method = Node->getCallOperator();
2206 NeedComma = false;
2207 for (const auto *P : Method->parameters()) {
2208 if (NeedComma) {
2209 OS << ", ";
2210 } else {
2211 NeedComma = true;
2212 }
2213 std::string ParamStr =
2214 (Policy.CleanUglifiedParameters && P->getIdentifier())
2215 ? P->getIdentifier()->deuglifiedName().str()
2216 : P->getNameAsString();
2217 P->getOriginalType().print(OS, Policy, ParamStr);
2218 }
2219 if (Method->isVariadic()) {
2220 if (NeedComma)
2221 OS << ", ";
2222 OS << "...";
2223 }
2224 OS << ')';
2225
2226 if (Node->isMutable())
2227 OS << " mutable";
2228
2229 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2230 Proto->printExceptionSpecification(OS, Policy);
2231
2232 // FIXME: Attributes
2233
2234 // Print the trailing return type if it was specified in the source.
2235 if (Node->hasExplicitResultType()) {
2236 OS << " -> ";
2237 Proto->getReturnType().print(OS, Policy);
2238 }
2239 }
2240
2241 // Print the body.
2242 OS << ' ';
2243 if (Policy.TerseOutput)
2244 OS << "{}";
2245 else
2246 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2247}
2248
2249void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2250 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2251 TSInfo->getType().print(OS, Policy);
2252 else
2253 Node->getType().print(OS, Policy);
2254 OS << "()";
2255}
2256
2257void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2258 if (E->isGlobalNew())
2259 OS << "::";
2260 OS << "new ";
2261 unsigned NumPlace = E->getNumPlacementArgs();
2262 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2263 OS << "(";
2264 PrintExpr(E->getPlacementArg(0));
2265 for (unsigned i = 1; i < NumPlace; ++i) {
2266 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2267 break;
2268 OS << ", ";
2269 PrintExpr(E->getPlacementArg(i));
2270 }
2271 OS << ") ";
2272 }
2273 if (E->isParenTypeId())
2274 OS << "(";
2275 std::string TypeS;
2276 if (E->isArray()) {
2277 llvm::raw_string_ostream s(TypeS);
2278 s << '[';
2279 if (std::optional<Expr *> Size = E->getArraySize())
2280 (*Size)->printPretty(s, Helper, Policy);
2281 s << ']';
2282 }
2283 E->getAllocatedType().print(OS, Policy, TypeS);
2284 if (E->isParenTypeId())
2285 OS << ")";
2286
2288 if (InitStyle != CXXNewExpr::NoInit) {
2289 bool Bare = InitStyle == CXXNewExpr::CallInit &&
2290 !isa<ParenListExpr>(E->getInitializer());
2291 if (Bare)
2292 OS << "(";
2293 PrintExpr(E->getInitializer());
2294 if (Bare)
2295 OS << ")";
2296 }
2297}
2298
2299void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2300 if (E->isGlobalDelete())
2301 OS << "::";
2302 OS << "delete ";
2303 if (E->isArrayForm())
2304 OS << "[] ";
2305 PrintExpr(E->getArgument());
2306}
2307
2308void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2309 PrintExpr(E->getBase());
2310 if (E->isArrow())
2311 OS << "->";
2312 else
2313 OS << '.';
2314 if (E->getQualifier())
2315 E->getQualifier()->print(OS, Policy);
2316 OS << "~";
2317
2319 OS << II->getName();
2320 else
2321 E->getDestroyedType().print(OS, Policy);
2322}
2323
2324void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2326 OS << "{";
2327
2328 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2329 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2330 // Don't print any defaulted arguments
2331 break;
2332 }
2333
2334 if (i) OS << ", ";
2335 PrintExpr(E->getArg(i));
2336 }
2337
2339 OS << "}";
2340}
2341
2342void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2343 // Parens are printed by the surrounding context.
2344 OS << "<forwarded>";
2345}
2346
2347void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2348 PrintExpr(E->getSubExpr());
2349}
2350
2351void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2352 // Just forward to the subexpression.
2353 PrintExpr(E->getSubExpr());
2354}
2355
2356void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2358 Node->getTypeAsWritten().print(OS, Policy);
2359 if (!Node->isListInitialization())
2360 OS << '(';
2361 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2362 ++Arg) {
2363 if (Arg != Node->arg_begin())
2364 OS << ", ";
2365 PrintExpr(*Arg);
2366 }
2367 if (!Node->isListInitialization())
2368 OS << ')';
2369}
2370
2371void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2373 if (!Node->isImplicitAccess()) {
2374 PrintExpr(Node->getBase());
2375 OS << (Node->isArrow() ? "->" : ".");
2376 }
2377 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2378 Qualifier->print(OS, Policy);
2379 if (Node->hasTemplateKeyword())
2380 OS << "template ";
2381 OS << Node->getMemberNameInfo();
2382 if (Node->hasExplicitTemplateArgs())
2383 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2384}
2385
2386void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2387 if (!Node->isImplicitAccess()) {
2388 PrintExpr(Node->getBase());
2389 OS << (Node->isArrow() ? "->" : ".");
2390 }
2391 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2392 Qualifier->print(OS, Policy);
2393 if (Node->hasTemplateKeyword())
2394 OS << "template ";
2395 OS << Node->getMemberNameInfo();
2396 if (Node->hasExplicitTemplateArgs())
2397 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2398}
2399
2400void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2401 OS << getTraitSpelling(E->getTrait()) << "(";
2402 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2403 if (I > 0)
2404 OS << ", ";
2405 E->getArg(I)->getType().print(OS, Policy);
2406 }
2407 OS << ")";
2408}
2409
2410void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2411 OS << getTraitSpelling(E->getTrait()) << '(';
2412 E->getQueriedType().print(OS, Policy);
2413 OS << ')';
2414}
2415
2416void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2417 OS << getTraitSpelling(E->getTrait()) << '(';
2418 PrintExpr(E->getQueriedExpression());
2419 OS << ')';
2420}
2421
2422void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2423 OS << "noexcept(";
2424 PrintExpr(E->getOperand());
2425 OS << ")";
2426}
2427
2428void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2429 PrintExpr(E->getPattern());
2430 OS << "...";
2431}
2432
2433void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2434 OS << "sizeof...(" << *E->getPack() << ")";
2435}
2436
2437void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2439 OS << *Node->getParameterPack();
2440}
2441
2442void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2444 Visit(Node->getReplacement());
2445}
2446
2447void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2448 OS << *E->getParameterPack();
2449}
2450
2451void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2452 PrintExpr(Node->getSubExpr());
2453}
2454
2455void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2456 OS << "(";
2457 if (E->getLHS()) {
2458 PrintExpr(E->getLHS());
2459 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2460 }
2461 OS << "...";
2462 if (E->getRHS()) {
2463 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2464 PrintExpr(E->getRHS());
2465 }
2466 OS << ")";
2467}
2468
2469void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2470 OS << "(";
2471 llvm::interleaveComma(Node->getInitExprs(), OS,
2472 [&](Expr *E) { PrintExpr(E); });
2473 OS << ")";
2474}
2475
2476void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2478 if (NNS)
2479 NNS.getNestedNameSpecifier()->print(OS, Policy);
2480 if (E->getTemplateKWLoc().isValid())
2481 OS << "template ";
2482 OS << E->getFoundDecl()->getName();
2484 Policy,
2486}
2487
2488void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2489 OS << "requires ";
2490 auto LocalParameters = E->getLocalParameters();
2491 if (!LocalParameters.empty()) {
2492 OS << "(";
2493 for (ParmVarDecl *LocalParam : LocalParameters) {
2494 PrintRawDecl(LocalParam);
2495 if (LocalParam != LocalParameters.back())
2496 OS << ", ";
2497 }
2498
2499 OS << ") ";
2500 }
2501 OS << "{ ";
2502 auto Requirements = E->getRequirements();
2503 for (concepts::Requirement *Req : Requirements) {
2504 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2505 if (TypeReq->isSubstitutionFailure())
2506 OS << "<<error-type>>";
2507 else
2508 TypeReq->getType()->getType().print(OS, Policy);
2509 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2510 if (ExprReq->isCompound())
2511 OS << "{ ";
2512 if (ExprReq->isExprSubstitutionFailure())
2513 OS << "<<error-expression>>";
2514 else
2515 PrintExpr(ExprReq->getExpr());
2516 if (ExprReq->isCompound()) {
2517 OS << " }";
2518 if (ExprReq->getNoexceptLoc().isValid())
2519 OS << " noexcept";
2520 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2521 if (!RetReq.isEmpty()) {
2522 OS << " -> ";
2523 if (RetReq.isSubstitutionFailure())
2524 OS << "<<error-type>>";
2525 else if (RetReq.isTypeConstraint())
2526 RetReq.getTypeConstraint()->print(OS, Policy);
2527 }
2528 }
2529 } else {
2530 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2531 OS << "requires ";
2532 if (NestedReq->hasInvalidConstraint())
2533 OS << "<<error-expression>>";
2534 else
2535 PrintExpr(NestedReq->getConstraintExpr());
2536 }
2537 OS << "; ";
2538 }
2539 OS << "}";
2540}
2541
2542// C++ Coroutines
2543
2544void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2545 Visit(S->getBody());
2546}
2547
2548void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2549 OS << "co_return";
2550 if (S->getOperand()) {
2551 OS << " ";
2552 Visit(S->getOperand());
2553 }
2554 OS << ";";
2555}
2556
2557void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2558 OS << "co_await ";
2559 PrintExpr(S->getOperand());
2560}
2561
2562void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2563 OS << "co_await ";
2564 PrintExpr(S->getOperand());
2565}
2566
2567void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2568 OS << "co_yield ";
2569 PrintExpr(S->getOperand());
2570}
2571
2572// Obj-C
2573
2574void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2575 OS << "@";
2576 VisitStringLiteral(Node->getString());
2577}
2578
2579void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2580 OS << "@";
2581 Visit(E->getSubExpr());
2582}
2583
2584void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2585 OS << "@[ ";
2587 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2588 if (I != Ch.begin())
2589 OS << ", ";
2590 Visit(*I);
2591 }
2592 OS << " ]";
2593}
2594
2595void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2596 OS << "@{ ";
2597 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2598 if (I > 0)
2599 OS << ", ";
2600
2602 Visit(Element.Key);
2603 OS << " : ";
2604 Visit(Element.Value);
2605 if (Element.isPackExpansion())
2606 OS << "...";
2607 }
2608 OS << " }";
2609}
2610
2611void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2612 OS << "@encode(";
2613 Node->getEncodedType().print(OS, Policy);
2614 OS << ')';
2615}
2616
2617void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2618 OS << "@selector(";
2619 Node->getSelector().print(OS);
2620 OS << ')';
2621}
2622
2623void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2624 OS << "@protocol(" << *Node->getProtocol() << ')';
2625}
2626
2627void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2628 OS << "[";
2629 switch (Mess->getReceiverKind()) {
2631 PrintExpr(Mess->getInstanceReceiver());
2632 break;
2633
2635 Mess->getClassReceiver().print(OS, Policy);
2636 break;
2637
2640 OS << "Super";
2641 break;
2642 }
2643
2644 OS << ' ';
2645 Selector selector = Mess->getSelector();
2646 if (selector.isUnarySelector()) {
2647 OS << selector.getNameForSlot(0);
2648 } else {
2649 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2650 if (i < selector.getNumArgs()) {
2651 if (i > 0) OS << ' ';
2652 if (selector.getIdentifierInfoForSlot(i))
2653 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2654 else
2655 OS << ":";
2656 }
2657 else OS << ", "; // Handle variadic methods.
2658
2659 PrintExpr(Mess->getArg(i));
2660 }
2661 }
2662 OS << "]";
2663}
2664
2665void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2666 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2667}
2668
2669void
2670StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2671 PrintExpr(E->getSubExpr());
2672}
2673
2674void
2675StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2676 OS << '(' << E->getBridgeKindName();
2677 E->getType().print(OS, Policy);
2678 OS << ')';
2679 PrintExpr(E->getSubExpr());
2680}
2681
2682void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2683 BlockDecl *BD = Node->getBlockDecl();
2684 OS << "^";
2685
2686 const FunctionType *AFT = Node->getFunctionType();
2687
2688 if (isa<FunctionNoProtoType>(AFT)) {
2689 OS << "()";
2690 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2691 OS << '(';
2692 for (BlockDecl::param_iterator AI = BD->param_begin(),
2693 E = BD->param_end(); AI != E; ++AI) {
2694 if (AI != BD->param_begin()) OS << ", ";
2695 std::string ParamStr = (*AI)->getNameAsString();
2696 (*AI)->getType().print(OS, Policy, ParamStr);
2697 }
2698
2699 const auto *FT = cast<FunctionProtoType>(AFT);
2700 if (FT->isVariadic()) {
2701 if (!BD->param_empty()) OS << ", ";
2702 OS << "...";
2703 }
2704 OS << ')';
2705 }
2706 OS << "{ }";
2707}
2708
2709void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2710 PrintExpr(Node->getSourceExpr());
2711}
2712
2713void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2714 // TODO: Print something reasonable for a TypoExpr, if necessary.
2715 llvm_unreachable("Cannot print TypoExpr nodes");
2716}
2717
2718void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2719 OS << "<recovery-expr>(";
2720 const char *Sep = "";
2721 for (Expr *E : Node->subExpressions()) {
2722 OS << Sep;
2723 PrintExpr(E);
2724 Sep = ", ";
2725 }
2726 OS << ')';
2727}
2728
2729void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2730 OS << "__builtin_astype(";
2731 PrintExpr(Node->getSrcExpr());
2732 OS << ", ";
2733 Node->getType().print(OS, Policy);
2734 OS << ")";
2735}
2736
2737//===----------------------------------------------------------------------===//
2738// Stmt method implementations
2739//===----------------------------------------------------------------------===//
2740
2741void Stmt::dumpPretty(const ASTContext &Context) const {
2742 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2743}
2744
2745void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2746 const PrintingPolicy &Policy, unsigned Indentation,
2747 StringRef NL, const ASTContext *Context) const {
2748 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2749 P.Visit(const_cast<Stmt *>(this));
2750}
2751
2752void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2753 const PrintingPolicy &Policy,
2754 unsigned Indentation, StringRef NL,
2755 const ASTContext *Context) const {
2756 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2757 P.PrintControlledStmt(const_cast<Stmt *>(this));
2758}
2759
2760void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2761 const PrintingPolicy &Policy, bool AddQuotes) const {
2762 std::string Buf;
2763 llvm::raw_string_ostream TempOut(Buf);
2764
2765 printPretty(TempOut, Helper, Policy);
2766
2767 Out << JsonFormat(TempOut.str(), AddQuotes);
2768}
2769
2770//===----------------------------------------------------------------------===//
2771// PrinterHelper
2772//===----------------------------------------------------------------------===//
2773
2774// Implement virtual destructor.
Defines the clang::ASTContext interface.
int Id
Definition: ASTDiff.cpp:190
DynTypedNode Node
StringRef P
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1048
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines enumerations for expression traits intrinsics.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines several types used to describe C++ lambda expressions that are shared between the parser and ...
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
Defines an enumeration for C++ overloaded operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__device__ __2f16 float bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
SourceManager & getSourceManager()
Definition: ASTContext.h:691
const LangOptions & getLangOpts() const
Definition: ASTContext.h:761
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4317
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5531
Represents a loop initializing the elements of an array.
Definition: Expr.h:5478
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2661
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2827
ArrayTypeTrait getTrait() const
Definition: ExprCXX.h:2866
QualType getQueriedType() const
Definition: ExprCXX.h:2868
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition: Expr.h:6086
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6289
Attr - This represents one attribute.
Definition: Attr.h:40
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const
Represents an attribute applied to a statement.
Definition: Stmt.h:1896
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4220
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3819
StringRef getOpcodeStr() const
Definition: Expr.h:3884
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4355
param_iterator param_end()
Definition: Decl.h:4454
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition: Decl.h:4449
param_iterator param_begin()
Definition: Decl.h:4453
bool param_empty() const
Definition: Decl.h:4452
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6025
BreakStmt - This represents a break.
Definition: Stmt.h:2796
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5115
This class is used for builtin types like 'int'.
Definition: Type.h:2646
Kind getKind() const
Definition: Type.h:2684
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition: Expr.h:3750
Represents a call to a CUDA kernel function.
Definition: ExprCXX.h:231
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition: ExprCXX.h:601
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1470
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
A C++ const_cast expression (C++ [expr.const.cast]).
Definition: ExprCXX.h:563
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1518
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition: ExprCXX.h:1669
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition: ExprCXX.h:1620
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition: ExprCXX.h:1609
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition: ExprCXX.h:1666
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1249
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1356
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2473
bool isArrayForm() const
Definition: ExprCXX.h:2499
bool isGlobalDelete() const
Definition: ExprCXX.h:2498
Expr * getArgument()
Definition: ExprCXX.h:2514
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition: ExprCXX.h:3629
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition: ExprCXX.h:478
Represents a folding of a pack over an operator.
Definition: ExprCXX.h:4676
Expr * getRHS() const
Definition: ExprCXX.h:4711
Expr * getLHS() const
Definition: ExprCXX.h:4710
BinaryOperatorKind getOperator() const
Definition: ExprCXX.h:4730
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Definition: ExprCXX.h:1787
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1709
Represents a call to a member function that may be written either with member call syntax (e....
Definition: ExprCXX.h:176
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2035
Abstract class common to all of the C++ "named"/"keyword" casts.
Definition: ExprCXX.h:372
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2199
bool isArray() const
Definition: ExprCXX.h:2320
QualType getAllocatedType() const
Definition: ExprCXX.h:2290
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Definition: ExprCXX.h:2325
Expr * getPlacementArg(unsigned I)
Definition: ExprCXX.h:2359
unsigned getNumPlacementArgs() const
Definition: ExprCXX.h:2350
bool isParenTypeId() const
Definition: ExprCXX.h:2367
InitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition: ExprCXX.h:2381
@ CallInit
New-expression has a C++98 paren-delimited initializer.
Definition: ExprCXX.h:2254
@ NoInit
New-expression has no initializer as written.
Definition: ExprCXX.h:2251
bool isGlobalNew() const
Definition: ExprCXX.h:2373
Expr * getInitializer()
The initializer of this new-expression.
Definition: ExprCXX.h:2389
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4072
Expr * getOperand() const
Definition: ExprCXX.h:4089
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:81
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4798
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition: ExprCXX.h:2592
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition: ExprCXX.h:2655
IdentifierInfo * getDestroyedTypeIdentifier() const
In a dependent pseudo-destructor expression for which we do not have full type information on the des...
Definition: ExprCXX.h:2692
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition: ExprCXX.cpp:335
NestedNameSpecifier * getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition: ExprCXX.h:2649
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
A rewritten comparison expression that was originally written using operator syntax.
Definition: ExprCXX.h:283
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2151
A C++ static_cast expression (C++ [expr.static.cast]).
Definition: ExprCXX.h:433
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition: ExprCXX.h:797
Represents a C++ functional cast expression that builds a temporary object.
Definition: ExprCXX.h:1855
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1187
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:69
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:845
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition: ExprCXX.h:3503
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition: ExprCXX.h:1062
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2817
This captures a statement into a function.
Definition: Stmt.h:3573
CaseStmt - Represent a case statement.
Definition: Stmt.h:1617
Expr * getSubExpr()
Definition: Expr.h:3537
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterKind Kind, raw_ostream &OS)
Definition: Expr.cpp:1029
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4537
Represents a 'co_await' expression.
Definition: ExprCXX.h:5008
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4067
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3417
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1424
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
Definition: ASTConcept.h:149
NamedDecl * getFoundDecl() const
Definition: ASTConcept.h:161
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:165
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ASTConcept.h:169
SourceLocation getTemplateKWLoc() const
Definition: ASTConcept.h:159
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:41
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4158
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1044
ContinueStmt - This represents a continue.
Definition: Stmt.h:2766
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4478
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition: StmtCXX.h:473
Represents the body of a coroutine.
Definition: StmtCXX.h:320
Represents a 'co_yield' expression.
Definition: ExprCXX.h:5089
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1237
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1315
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Represents a 'co_await' expression while the type of the promise is dependent.
Definition: ExprCXX.h:5040
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3269
Represents a single C99 designator.
Definition: Expr.h:5102
Represents a C99 designated initializer expression.
Definition: Expr.h:5060
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2541
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3420
This represents one expression.
Definition: Expr.h:110
QualType getType() const
Definition: Expr.h:142
An expression trait intrinsic.
Definition: ExprCXX.h:2897
Expr * getQueriedExpression() const
Definition: ExprCXX.h:2934
ExpressionTrait getTrait() const
Definition: ExprCXX.h:2932
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition: Expr.h:5965
Represents difference between two FPOptions values.
Definition: LangOptions.h:806
Represents a member of a struct/union/class.
Definition: Decl.h:2945
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition: Decl.cpp:4366
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2597
const Expr * getSubExpr() const
Definition: Expr.h:1027
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2586
bool isVariadic() const
Whether this function is variadic.
Definition: Decl.cpp:3026
Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...
Definition: ExprCXX.h:4484
VarDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition: ExprCXX.h:4511
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4056
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3709
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:3075
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4612
Represents a C11 generic selection.
Definition: Expr.h:5686
AssociationTy< false > Association
Definition: Expr.h:5840
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2678
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IfStmt - This represents an if/then/else.
Definition: Stmt.h:1954
Stmt * getThen()
Definition: Stmt.h:2043
Stmt * getInit()
Definition: Stmt.h:2104
Expr * getCond()
Definition: Stmt.h:2031
bool isNegatedConsteval() const
Definition: Stmt.h:2143
Stmt * getElse()
Definition: Stmt.h:2052
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
Definition: Stmt.h:2087
bool isConsteval() const
Definition: Stmt.h:2134
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1728
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3634
@ ObjCSelf
Parameter for Objective-C 'self' argument.
Definition: Decl.h:1664
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5567
IndirectGotoStmt - This represents an indirect goto.
Definition: Stmt.h:2717
Describes an C or C++ initializer list.
Definition: Expr.h:4815
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:1847
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1924
llvm::RoundingMode RoundingMode
Definition: LangOptions.h:85
FPExceptionModeKind
Possible floating point exception behavior.
Definition: LangOptions.h:270
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Definition: LangOptions.h:272
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
Definition: LangOptions.h:274
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
Definition: LangOptions.h:276
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Definition: Lexer.cpp:960
This represents a Microsoft inline-assembly statement extension.
Definition: Stmt.h:3298
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Definition: StmtCXX.h:253
A member reference to an MSPropertyDecl.
Definition: ExprCXX.h:929
MS property subscript expression.
Definition: ExprCXX.h:1000
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4564
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition: Expr.h:2739
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3180
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
Represents a place-holder for an object not to be initialized by anything.
Definition: Expr.h:5387
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition: Stmt.h:1387
OpenMP 5.0 [2.1.5, Array Sections].
Definition: ExprOpenMP.h:56
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition: ExprOpenMP.h:148
This represents '#pragma omp atomic' directive.
Definition: StmtOpenMP.h:2895
This represents '#pragma omp barrier' directive.
Definition: StmtOpenMP.h:2573
This represents '#pragma omp cancel' directive.
Definition: StmtOpenMP.h:3600
This represents '#pragma omp cancellation point' directive.
Definition: StmtOpenMP.h:3542
Representation of an OpenMP canonical loop.
Definition: StmtOpenMP.h:142
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:2024
This represents implicit clause 'depend' for the '#pragma omp task' directive.
This represents '#pragma omp depobj' directive.
Definition: StmtOpenMP.h:2789
This represents '#pragma omp dispatch' directive.
Definition: StmtOpenMP.h:5755
This represents '#pragma omp distribute' directive.
Definition: StmtOpenMP.h:4370
This represents '#pragma omp distribute parallel for' composite directive.
Definition: StmtOpenMP.h:4492
This represents '#pragma omp distribute parallel for simd' composite directive.
Definition: StmtOpenMP.h:4588
This represents '#pragma omp distribute simd' composite directive.
Definition: StmtOpenMP.h:4653
This represents '#pragma omp error' directive.
Definition: StmtOpenMP.h:6230
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
This represents '#pragma omp flush' directive.
Definition: StmtOpenMP.h:2737
This represents '#pragma omp for' directive.
Definition: StmtOpenMP.h:1633
This represents '#pragma omp for simd' directive.
Definition: StmtOpenMP.h:1723
This represents '#pragma omp loop' directive.
Definition: StmtOpenMP.h:5910
This represents '#pragma omp interop' directive.
Definition: StmtOpenMP.h:5702
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition: ExprOpenMP.h:275
This represents '#pragma omp masked' directive.
Definition: StmtOpenMP.h:5820
This represents '#pragma omp masked taskloop' directive.
Definition: StmtOpenMP.h:3875
This represents '#pragma omp masked taskloop simd' directive.
Definition: StmtOpenMP.h:4016
This represents '#pragma omp master' directive.
Definition: StmtOpenMP.h:1976
This represents '#pragma omp master taskloop' directive.
Definition: StmtOpenMP.h:3799
This represents '#pragma omp master taskloop simd' directive.
Definition: StmtOpenMP.h:3951
This represents '#pragma omp metadirective' directive.
Definition: StmtOpenMP.h:5871
This represents '#pragma omp ordered' directive.
Definition: StmtOpenMP.h:2841
This represents '#pragma omp parallel' directive.
Definition: StmtOpenMP.h:612
This represents '#pragma omp parallel for' directive.
Definition: StmtOpenMP.h:2095
This represents '#pragma omp parallel for simd' directive.
Definition: StmtOpenMP.h:2192
This represents '#pragma omp parallel loop' directive.
Definition: StmtOpenMP.h:6103
This represents '#pragma omp parallel masked' directive.
Definition: StmtOpenMP.h:2320
This represents '#pragma omp parallel masked taskloop' directive.
Definition: StmtOpenMP.h:4160
This represents '#pragma omp parallel masked taskloop simd' directive.
Definition: StmtOpenMP.h:4305
This represents '#pragma omp parallel master' directive.
Definition: StmtOpenMP.h:2257
This represents '#pragma omp parallel master taskloop' directive.
Definition: StmtOpenMP.h:4082
This represents '#pragma omp parallel master taskloop simd' directive.
Definition: StmtOpenMP.h:4238
This represents '#pragma omp parallel sections' directive.
Definition: StmtOpenMP.h:2384
This represents '#pragma omp scan' directive.
Definition: StmtOpenMP.h:5649
This represents '#pragma omp section' directive.
Definition: StmtOpenMP.h:1863
This represents '#pragma omp sections' directive.
Definition: StmtOpenMP.h:1786
This represents '#pragma omp simd' directive.
Definition: StmtOpenMP.h:1570
This represents '#pragma omp single' directive.
Definition: StmtOpenMP.h:1925
This represents '#pragma omp target data' directive.
Definition: StmtOpenMP.h:3151
This represents '#pragma omp target' directive.
Definition: StmtOpenMP.h:3097
This represents '#pragma omp target enter data' directive.
Definition: StmtOpenMP.h:3205
This represents '#pragma omp target exit data' directive.
Definition: StmtOpenMP.h:3260
This represents '#pragma omp target parallel' directive.
Definition: StmtOpenMP.h:3314
This represents '#pragma omp target parallel for' directive.
Definition: StmtOpenMP.h:3394
This represents '#pragma omp target parallel for simd' directive.
Definition: StmtOpenMP.h:4719
This represents '#pragma omp target parallel loop' directive.
Definition: StmtOpenMP.h:6168
This represents '#pragma omp target simd' directive.
Definition: StmtOpenMP.h:4786
This represents '#pragma omp target teams' directive.
Definition: StmtOpenMP.h:5144
This represents '#pragma omp target teams distribute' combined directive.
Definition: StmtOpenMP.h:5200
This represents '#pragma omp target teams distribute parallel for' combined directive.
Definition: StmtOpenMP.h:5267
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
Definition: StmtOpenMP.h:5365
This represents '#pragma omp target teams distribute simd' combined directive.
Definition: StmtOpenMP.h:5435
This represents '#pragma omp target teams loop' directive.
Definition: StmtOpenMP.h:6037
This represents '#pragma omp target update' directive.
Definition: StmtOpenMP.h:4436
This represents '#pragma omp task' directive.
Definition: StmtOpenMP.h:2465
This represents '#pragma omp taskloop' directive.
Definition: StmtOpenMP.h:3660
This represents '#pragma omp taskloop simd' directive.
Definition: StmtOpenMP.h:3733
This represents '#pragma omp taskgroup' directive.
Definition: StmtOpenMP.h:2670
This represents '#pragma omp taskwait' directive.
Definition: StmtOpenMP.h:2619
This represents '#pragma omp taskyield' directive.
Definition: StmtOpenMP.h:2527
This represents '#pragma omp teams' directive.
Definition: StmtOpenMP.h:3489
This represents '#pragma omp teams distribute' directive.
Definition: StmtOpenMP.h:4851
This represents '#pragma omp teams distribute parallel for' composite directive.
Definition: StmtOpenMP.h:5051
This represents '#pragma omp teams distribute parallel for simd' composite directive.
Definition: StmtOpenMP.h:4985
This represents '#pragma omp teams distribute simd' combined directive.
Definition: StmtOpenMP.h:4917
This represents '#pragma omp teams loop' directive.
Definition: StmtOpenMP.h:5972
This represents the '#pragma omp tile' loop transformation directive.
Definition: StmtOpenMP.h:5493
This represents the '#pragma omp unroll' loop transformation directive.
Definition: StmtOpenMP.h:5575
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:191
child_range children()
Definition: ExprObjC.h:245
Represents Objective-C's @catch statement.
Definition: StmtObjC.h:77
Represents Objective-C's @finally statement.
Definition: StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition: StmtObjC.h:302
Represents Objective-C's @throw statement.
Definition: StmtObjC.h:357
Represents Objective-C's @try ... @catch ... @finally statement.
Definition: StmtObjC.h:167
Represents Objective-C's @autoreleasepool Statement.
Definition: StmtObjC.h:393
A runtime availability query.
Definition: ExprObjC.h:1685
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:87
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:127
Expr * getSubExpr()
Definition: ExprObjC.h:143
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition: ExprObjC.h:1626
StringRef getBridgeKindName() const
Retrieve the kind of bridge being performed as a string.
Definition: ExprObjC.cpp:341
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:309
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Definition: ExprObjC.h:359
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Definition: ExprObjC.h:361
ObjCEncodeExpr, used for @encode in Objective-C.
Definition: ExprObjC.h:409
Represents Objective-C's collection statement.
Definition: StmtObjC.h:23
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition: ExprObjC.h:1565
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition: ExprObjC.h:1481
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:548
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:942
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: ExprObjC.h:1385
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1250
Selector getSelector() const
Definition: ExprObjC.cpp:293
@ SuperInstance
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:1097
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:1091
@ SuperClass
The receiver is a superclass.
Definition: ExprObjC.h:1094
@ Class
The receiver is a class.
Definition: ExprObjC.h:1088
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Definition: ExprObjC.h:1269
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition: ExprObjC.h:1224
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition: ExprObjC.h:1372
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:614
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition: ExprObjC.h:504
ObjCSelectorExpr used for @selector in Objective-C.
Definition: ExprObjC.h:454
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:51
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition: ExprObjC.h:841
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2462
Helper class for OffsetOfExpr.
Definition: Expr.h:2356
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition: Expr.h:2414
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition: Expr.cpp:1673
@ Array
An index into an array.
Definition: Expr.h:2361
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2368
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:2410
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1145
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4126
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition: ExprCXX.h:4155
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2128
Represents a parameter to a function.
Definition: Decl.h:1722
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1971
StringRef getIdentKindName() const
Definition: Expr.h:2043
virtual bool handledStmt(Stmt *E, raw_ostream &OS)=0
virtual ~PrinterHelper()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6157
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition: Expr.h:6477
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:480
ArrayRef< concepts::Requirement * > getRequirements() const
Definition: ExprConcepts.h:521
ArrayRef< ParmVarDecl * > getLocalParameters() const
Definition: ExprConcepts.h:515
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:2835
Represents a __leave statement.
Definition: Stmt.h:3534
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
bool isUnarySelector() const
unsigned getNumArgs() const
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition: Expr.h:4410
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4204
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition: ExprCXX.h:4273
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4696
bool isValid() const
Return true if this is a valid SourceLocation object.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4362
CompoundStmt * getSubStmt()
Definition: Expr.h:4379
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Definition: StmtVisitor.h:43
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:184
Stmt - This represents one statement.
Definition: Stmt.h:72
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:325
void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1270
void dumpPretty(const ASTContext &Context) const
dumpPretty/printPretty - These two methods do a "pretty print" of the AST back to its original source...
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1780
void outputString(raw_ostream &OS) const
Definition: Expr.cpp:1208
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4320
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition: ExprCXX.h:4405
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2204
A template argument list.
Definition: DeclTemplate.h:240
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:298
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:283
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:292
Represents a template argument.
Definition: TemplateBase.h:60
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:392
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:99
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:263
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:428
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
A container of type source information.
Definition: Type.h:6635
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6646
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2742
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition: ExprCXX.h:2792
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition: ExprCXX.h:2789
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition: ExprCXX.h:2779
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7497
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
Definition: Expr.h:6422
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2565
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2181
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition: Expr.cpp:1390
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3151
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3889
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
Definition: ExprCXX.h:637
@ LOK_String
operator "" X (const CharT *, size_t)
Definition: ExprCXX.h:679
@ LOK_Raw
Raw form: operator "" X (const char *)
Definition: ExprCXX.h:667
@ LOK_Floating
operator "" X (long double)
Definition: ExprCXX.h:676
@ LOK_Integer
operator "" X (unsigned long long)
Definition: ExprCXX.h:673
@ LOK_Template
Raw form: operator "" X<cs...> ()
Definition: ExprCXX.h:670
@ LOK_Character
operator "" X (CharT)
Definition: ExprCXX.h:682
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4646
QualType getType() const
Definition: Decl.h:712
@ CInit
C-style initialization with assignment.
Definition: Decl.h:918
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:921
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2400
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:148
bool Call(InterpState &S, CodePtr OpPC, const Function *Func)
Definition: Interp.h:1585
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
@ LCK_ByCopy
Capturing by copy (a.k.a., by value)
Definition: Lambda.h:36
@ LCK_ByRef
Capturing by reference.
Definition: Lambda.h:37
@ LCK_VLAType
Capturing variable-length array type.
Definition: Lambda.h:38
@ LCK_StarThis
Capturing the *this object by copy.
Definition: Lambda.h:35
@ LCK_This
Capturing the *this object by reference.
Definition: Lambda.h:34
@ C
Languages that the frontend can parse and compile.
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
Definition: JsonSupport.h:28
@ LCD_ByRef
Definition: Lambda.h:25
@ LCD_None
Definition: Lambda.h:23
@ LCD_ByCopy
Definition: Lambda.h:24
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:670
const Expr * RHS
The original right-hand side.
Definition: ExprCXX.h:310
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition: ExprCXX.h:306
const Expr * LHS
The original left-hand side.
Definition: ExprCXX.h:308
Iterator range representation begin:end[:step].
Definition: ExprOpenMP.h:278
An element in an Objective-C dictionary literal.
Definition: ExprObjC.h:262
Expr * Value
The value of the dictionary element.
Definition: ExprObjC.h:267
bool isPackExpansion() const
Determines whether this dictionary element is a pack expansion.
Definition: ExprObjC.h:277
Expr * Key
The key for the dictionary element.
Definition: ExprObjC.h:264
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned Alignof
Whether we can use 'alignof' rather than '__alignof'.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned ConstantsAsWritten
Whether we should print the constant expressions as written in the sources.
unsigned IncludeNewlines
When true, include newlines after statements like "break", etc.
unsigned Indentation
The number of spaces to use to indent each line.
Definition: PrettyPrinter.h:92
unsigned TerseOutput
Provide a 'terse' output.
unsigned UnderscoreAlignof
Whether we can use '_Alignof' rather than '__alignof'.
unsigned SuppressImplicitBase
When true, don't print the implicit 'self' or 'this' expressions.
Iterator for iterating over Stmt * arrays that contain only T *.
Definition: Stmt.h:1139