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