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 llvm::omp::Version OpenMPVersion =
783 Context ? Context->getLangOpts().getOpenMPVersion()
784 : llvm::omp::FallbackVersion;
785 OMPClausePrinter Printer(OS, Policy, OpenMPVersion);
786 ArrayRef<OMPClause *> Clauses = S->clauses();
787 for (auto *Clause : Clauses)
788 if (Clause && !Clause->isImplicit()) {
789 OS << ' ';
790 Printer.Visit(Clause);
791 }
792 OS << NL;
793 if (!ForceNoStmt && S->hasAssociatedStmt())
794 PrintStmt(S->getRawStmt());
795}
796
797void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) {
798 Indent() << "#pragma omp metadirective";
799 PrintOMPExecutableDirective(Node);
800}
801
802void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
803 Indent() << "#pragma omp parallel";
804 PrintOMPExecutableDirective(Node);
805}
806
807void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
808 Indent() << "#pragma omp simd";
809 PrintOMPExecutableDirective(Node);
810}
811
812void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {
813 Indent() << "#pragma omp tile";
814 PrintOMPExecutableDirective(Node);
815}
816
817void StmtPrinter::VisitOMPStripeDirective(OMPStripeDirective *Node) {
818 Indent() << "#pragma omp stripe";
819 PrintOMPExecutableDirective(Node);
820}
821
822void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {
823 Indent() << "#pragma omp unroll";
824 PrintOMPExecutableDirective(Node);
825}
826
827void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) {
828 Indent() << "#pragma omp reverse";
829 PrintOMPExecutableDirective(Node);
830}
831
832void StmtPrinter::VisitOMPInterchangeDirective(OMPInterchangeDirective *Node) {
833 Indent() << "#pragma omp interchange";
834 PrintOMPExecutableDirective(Node);
835}
836
837void StmtPrinter::VisitOMPFlattenDirective(OMPFlattenDirective *Node) {
838 Indent() << "#pragma omp flatten";
839 PrintOMPExecutableDirective(Node);
840}
841
842void StmtPrinter::VisitOMPSplitDirective(OMPSplitDirective *Node) {
843 Indent() << "#pragma omp split";
844 PrintOMPExecutableDirective(Node);
845}
846
847void StmtPrinter::VisitOMPFuseDirective(OMPFuseDirective *Node) {
848 Indent() << "#pragma omp fuse";
849 PrintOMPExecutableDirective(Node);
850}
851
852void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
853 Indent() << "#pragma omp for";
854 PrintOMPExecutableDirective(Node);
855}
856
857void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
858 Indent() << "#pragma omp for simd";
859 PrintOMPExecutableDirective(Node);
860}
861
862void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
863 Indent() << "#pragma omp sections";
864 PrintOMPExecutableDirective(Node);
865}
866
867void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
868 Indent() << "#pragma omp section";
869 PrintOMPExecutableDirective(Node);
870}
871
872void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {
873 Indent() << "#pragma omp scope";
874 PrintOMPExecutableDirective(Node);
875}
876
877void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
878 Indent() << "#pragma omp single";
879 PrintOMPExecutableDirective(Node);
880}
881
882void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
883 Indent() << "#pragma omp master";
884 PrintOMPExecutableDirective(Node);
885}
886
887void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
888 Indent() << "#pragma omp critical";
889 if (Node->getDirectiveName().getName()) {
890 OS << " (";
891 Node->getDirectiveName().printName(OS, Policy);
892 OS << ")";
893 }
894 PrintOMPExecutableDirective(Node);
895}
896
897void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
898 Indent() << "#pragma omp parallel for";
899 PrintOMPExecutableDirective(Node);
900}
901
902void StmtPrinter::VisitOMPParallelForSimdDirective(
903 OMPParallelForSimdDirective *Node) {
904 Indent() << "#pragma omp parallel for simd";
905 PrintOMPExecutableDirective(Node);
906}
907
908void StmtPrinter::VisitOMPParallelMasterDirective(
909 OMPParallelMasterDirective *Node) {
910 Indent() << "#pragma omp parallel master";
911 PrintOMPExecutableDirective(Node);
912}
913
914void StmtPrinter::VisitOMPParallelMaskedDirective(
915 OMPParallelMaskedDirective *Node) {
916 Indent() << "#pragma omp parallel masked";
917 PrintOMPExecutableDirective(Node);
918}
919
920void StmtPrinter::VisitOMPParallelSectionsDirective(
921 OMPParallelSectionsDirective *Node) {
922 Indent() << "#pragma omp parallel sections";
923 PrintOMPExecutableDirective(Node);
924}
925
926void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
927 Indent() << "#pragma omp task";
928 PrintOMPExecutableDirective(Node);
929}
930
931void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
932 Indent() << "#pragma omp taskyield";
933 PrintOMPExecutableDirective(Node);
934}
935
936void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
937 Indent() << "#pragma omp barrier";
938 PrintOMPExecutableDirective(Node);
939}
940
941void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
942 Indent() << "#pragma omp taskwait";
943 PrintOMPExecutableDirective(Node);
944}
945
946void StmtPrinter::VisitOMPAssumeDirective(OMPAssumeDirective *Node) {
947 Indent() << "#pragma omp assume";
948 PrintOMPExecutableDirective(Node);
949}
950
951void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
952 Indent() << "#pragma omp error";
953 PrintOMPExecutableDirective(Node);
954}
955
956void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
957 Indent() << "#pragma omp taskgroup";
958 PrintOMPExecutableDirective(Node);
959}
960
961void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
962 Indent() << "#pragma omp flush";
963 PrintOMPExecutableDirective(Node);
964}
965
966void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
967 Indent() << "#pragma omp depobj";
968 PrintOMPExecutableDirective(Node);
969}
970
971void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
972 Indent() << "#pragma omp scan";
973 PrintOMPExecutableDirective(Node);
974}
975
976void StmtPrinter::VisitOMPOrderedStandaloneDirective(
977 OMPOrderedStandaloneDirective *Node) {
978 Indent() << "#pragma omp ordered";
979 PrintOMPExecutableDirective(Node, true);
980}
981
982void StmtPrinter::VisitOMPOrderedBlockAssocDirective(
983 OMPOrderedBlockAssocDirective *Node) {
984 Indent() << "#pragma omp ordered";
985 PrintOMPExecutableDirective(Node);
986}
987
988void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
989 Indent() << "#pragma omp atomic";
990 PrintOMPExecutableDirective(Node);
991}
992
993void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
994 Indent() << "#pragma omp target";
995 PrintOMPExecutableDirective(Node);
996}
997
998void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
999 Indent() << "#pragma omp target data";
1000 PrintOMPExecutableDirective(Node);
1001}
1002
1003void StmtPrinter::VisitOMPTargetEnterDataDirective(
1004 OMPTargetEnterDataDirective *Node) {
1005 Indent() << "#pragma omp target enter data";
1006 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1007}
1008
1009void StmtPrinter::VisitOMPTargetExitDataDirective(
1010 OMPTargetExitDataDirective *Node) {
1011 Indent() << "#pragma omp target exit data";
1012 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1013}
1014
1015void StmtPrinter::VisitOMPTargetParallelDirective(
1016 OMPTargetParallelDirective *Node) {
1017 Indent() << "#pragma omp target parallel";
1018 PrintOMPExecutableDirective(Node);
1019}
1020
1021void StmtPrinter::VisitOMPTargetParallelForDirective(
1022 OMPTargetParallelForDirective *Node) {
1023 Indent() << "#pragma omp target parallel for";
1024 PrintOMPExecutableDirective(Node);
1025}
1026
1027void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
1028 Indent() << "#pragma omp teams";
1029 PrintOMPExecutableDirective(Node);
1030}
1031
1032void StmtPrinter::VisitOMPCancellationPointDirective(
1033 OMPCancellationPointDirective *Node) {
1034 llvm::omp::Version OpenMPVersion =
1035 Context ? Context->getLangOpts().getOpenMPVersion()
1036 : llvm::omp::FallbackVersion;
1037 Indent() << "#pragma omp cancellation point "
1038 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);
1039 PrintOMPExecutableDirective(Node);
1040}
1041
1042void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
1043 llvm::omp::Version OpenMPVersion =
1044 Context ? Context->getLangOpts().getOpenMPVersion()
1045 : llvm::omp::FallbackVersion;
1046 Indent() << "#pragma omp cancel "
1047 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);
1048 PrintOMPExecutableDirective(Node);
1049}
1050
1051void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
1052 Indent() << "#pragma omp taskloop";
1053 PrintOMPExecutableDirective(Node);
1054}
1055
1056void StmtPrinter::VisitOMPTaskLoopSimdDirective(
1057 OMPTaskLoopSimdDirective *Node) {
1058 Indent() << "#pragma omp taskloop simd";
1059 PrintOMPExecutableDirective(Node);
1060}
1061
1062void StmtPrinter::VisitOMPMasterTaskLoopDirective(
1063 OMPMasterTaskLoopDirective *Node) {
1064 Indent() << "#pragma omp master taskloop";
1065 PrintOMPExecutableDirective(Node);
1066}
1067
1068void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
1069 OMPMaskedTaskLoopDirective *Node) {
1070 Indent() << "#pragma omp masked taskloop";
1071 PrintOMPExecutableDirective(Node);
1072}
1073
1074void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
1075 OMPMasterTaskLoopSimdDirective *Node) {
1076 Indent() << "#pragma omp master taskloop simd";
1077 PrintOMPExecutableDirective(Node);
1078}
1079
1080void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
1081 OMPMaskedTaskLoopSimdDirective *Node) {
1082 Indent() << "#pragma omp masked taskloop simd";
1083 PrintOMPExecutableDirective(Node);
1084}
1085
1086void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
1087 OMPParallelMasterTaskLoopDirective *Node) {
1088 Indent() << "#pragma omp parallel master taskloop";
1089 PrintOMPExecutableDirective(Node);
1090}
1091
1092void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
1093 OMPParallelMaskedTaskLoopDirective *Node) {
1094 Indent() << "#pragma omp parallel masked taskloop";
1095 PrintOMPExecutableDirective(Node);
1096}
1097
1098void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
1099 OMPParallelMasterTaskLoopSimdDirective *Node) {
1100 Indent() << "#pragma omp parallel master taskloop simd";
1101 PrintOMPExecutableDirective(Node);
1102}
1103
1104void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
1105 OMPParallelMaskedTaskLoopSimdDirective *Node) {
1106 Indent() << "#pragma omp parallel masked taskloop simd";
1107 PrintOMPExecutableDirective(Node);
1108}
1109
1110void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1111 Indent() << "#pragma omp distribute";
1112 PrintOMPExecutableDirective(Node);
1113}
1114
1115void StmtPrinter::VisitOMPTargetUpdateDirective(
1116 OMPTargetUpdateDirective *Node) {
1117 Indent() << "#pragma omp target update";
1118 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1119}
1120
1121void StmtPrinter::VisitOMPDistributeParallelForDirective(
1122 OMPDistributeParallelForDirective *Node) {
1123 Indent() << "#pragma omp distribute parallel for";
1124 PrintOMPExecutableDirective(Node);
1125}
1126
1127void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1128 OMPDistributeParallelForSimdDirective *Node) {
1129 Indent() << "#pragma omp distribute parallel for simd";
1130 PrintOMPExecutableDirective(Node);
1131}
1132
1133void StmtPrinter::VisitOMPDistributeSimdDirective(
1134 OMPDistributeSimdDirective *Node) {
1135 Indent() << "#pragma omp distribute simd";
1136 PrintOMPExecutableDirective(Node);
1137}
1138
1139void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1140 OMPTargetParallelForSimdDirective *Node) {
1141 Indent() << "#pragma omp target parallel for simd";
1142 PrintOMPExecutableDirective(Node);
1143}
1144
1145void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1146 Indent() << "#pragma omp target simd";
1147 PrintOMPExecutableDirective(Node);
1148}
1149
1150void StmtPrinter::VisitOMPTeamsDistributeDirective(
1151 OMPTeamsDistributeDirective *Node) {
1152 Indent() << "#pragma omp teams distribute";
1153 PrintOMPExecutableDirective(Node);
1154}
1155
1156void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1157 OMPTeamsDistributeSimdDirective *Node) {
1158 Indent() << "#pragma omp teams distribute simd";
1159 PrintOMPExecutableDirective(Node);
1160}
1161
1162void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1163 OMPTeamsDistributeParallelForSimdDirective *Node) {
1164 Indent() << "#pragma omp teams distribute parallel for simd";
1165 PrintOMPExecutableDirective(Node);
1166}
1167
1168void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1169 OMPTeamsDistributeParallelForDirective *Node) {
1170 Indent() << "#pragma omp teams distribute parallel for";
1171 PrintOMPExecutableDirective(Node);
1172}
1173
1174void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1175 Indent() << "#pragma omp target teams";
1176 PrintOMPExecutableDirective(Node);
1177}
1178
1179void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1180 OMPTargetTeamsDistributeDirective *Node) {
1181 Indent() << "#pragma omp target teams distribute";
1182 PrintOMPExecutableDirective(Node);
1183}
1184
1185void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1186 OMPTargetTeamsDistributeParallelForDirective *Node) {
1187 Indent() << "#pragma omp target teams distribute parallel for";
1188 PrintOMPExecutableDirective(Node);
1189}
1190
1191void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1192 OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
1193 Indent() << "#pragma omp target teams distribute parallel for simd";
1194 PrintOMPExecutableDirective(Node);
1195}
1196
1197void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1198 OMPTargetTeamsDistributeSimdDirective *Node) {
1199 Indent() << "#pragma omp target teams distribute simd";
1200 PrintOMPExecutableDirective(Node);
1201}
1202
1203void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1204 Indent() << "#pragma omp interop";
1205 PrintOMPExecutableDirective(Node);
1206}
1207
1208void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1209 Indent() << "#pragma omp dispatch";
1210 PrintOMPExecutableDirective(Node);
1211}
1212
1213void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1214 Indent() << "#pragma omp masked";
1215 PrintOMPExecutableDirective(Node);
1216}
1217
1218void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1219 Indent() << "#pragma omp loop";
1220 PrintOMPExecutableDirective(Node);
1221}
1222
1223void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1224 OMPTeamsGenericLoopDirective *Node) {
1225 Indent() << "#pragma omp teams loop";
1226 PrintOMPExecutableDirective(Node);
1227}
1228
1229void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1230 OMPTargetTeamsGenericLoopDirective *Node) {
1231 Indent() << "#pragma omp target teams loop";
1232 PrintOMPExecutableDirective(Node);
1233}
1234
1235void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1236 OMPParallelGenericLoopDirective *Node) {
1237 Indent() << "#pragma omp parallel loop";
1238 PrintOMPExecutableDirective(Node);
1239}
1240
1241void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1242 OMPTargetParallelGenericLoopDirective *Node) {
1243 Indent() << "#pragma omp target parallel loop";
1244 PrintOMPExecutableDirective(Node);
1245}
1246
1247//===----------------------------------------------------------------------===//
1248// OpenACC construct printing methods
1249//===----------------------------------------------------------------------===//
1250void StmtPrinter::PrintOpenACCClauseList(OpenACCConstructStmt *S) {
1251 if (!S->clauses().empty()) {
1252 OS << ' ';
1253 OpenACCClausePrinter Printer(OS, Policy);
1254 Printer.VisitClauseList(S->clauses());
1255 }
1256}
1257void StmtPrinter::PrintOpenACCConstruct(OpenACCConstructStmt *S) {
1258 Indent() << "#pragma acc " << S->getDirectiveKind();
1259 PrintOpenACCClauseList(S);
1260 OS << '\n';
1261}
1262void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
1263 PrintOpenACCConstruct(S);
1264 PrintStmt(S->getStructuredBlock());
1265}
1266
1267void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
1268 PrintOpenACCConstruct(S);
1269 PrintStmt(S->getLoop());
1270}
1271
1272void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {
1273 PrintOpenACCConstruct(S);
1274 PrintStmt(S->getLoop());
1275}
1276
1277void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {
1278 PrintOpenACCConstruct(S);
1279 PrintStmt(S->getStructuredBlock());
1280}
1281void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
1282 PrintOpenACCConstruct(S);
1283 PrintStmt(S->getStructuredBlock());
1284}
1285void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) {
1286 PrintOpenACCConstruct(S);
1287}
1288void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
1289 PrintOpenACCConstruct(S);
1290}
1291void StmtPrinter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
1292 PrintOpenACCConstruct(S);
1293}
1294void StmtPrinter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
1295 PrintOpenACCConstruct(S);
1296}
1297void StmtPrinter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {
1298 PrintOpenACCConstruct(S);
1299}
1300void StmtPrinter::VisitOpenACCUpdateConstruct(OpenACCUpdateConstruct *S) {
1301 PrintOpenACCConstruct(S);
1302}
1303
1304void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
1305 Indent() << "#pragma acc wait";
1306 if (!S->getLParenLoc().isInvalid()) {
1307 OS << "(";
1308 if (S->hasDevNumExpr()) {
1309 OS << "devnum: ";
1310 S->getDevNumExpr()->printPretty(OS, nullptr, Policy);
1311 OS << " : ";
1312 }
1313
1314 if (S->hasQueuesTag())
1315 OS << "queues: ";
1316
1317 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](const Expr *E) {
1318 E->printPretty(OS, nullptr, Policy);
1319 });
1320
1321 OS << ")";
1322 }
1323
1324 PrintOpenACCClauseList(S);
1325 OS << '\n';
1326}
1327
1328void StmtPrinter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) {
1329 Indent() << "#pragma acc atomic";
1330
1331 if (S->getAtomicKind() != OpenACCAtomicKind::None)
1332 OS << " " << S->getAtomicKind();
1333
1334 PrintOpenACCClauseList(S);
1335 OS << '\n';
1336 PrintStmt(S->getAssociatedStmt());
1337}
1338
1339void StmtPrinter::VisitOpenACCCacheConstruct(OpenACCCacheConstruct *S) {
1340 Indent() << "#pragma acc cache(";
1341 if (S->hasReadOnly())
1342 OS << "readonly: ";
1343
1344 llvm::interleaveComma(S->getVarList(), OS, [&](const Expr *E) {
1345 E->printPretty(OS, nullptr, Policy);
1346 });
1347
1348 OS << ")\n";
1349}
1350
1351//===----------------------------------------------------------------------===//
1352// Expr printing methods.
1353//===----------------------------------------------------------------------===//
1354
1355void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1356 OS << Node->getBuiltinStr() << "()";
1357}
1358
1359void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
1360 // FIXME: Embed parameters are not reflected in the AST, so there is no way to
1361 // print them yet.
1362 OS << "#embed ";
1363 OS << Node->getFileName();
1364 OS << NL;
1365}
1366
1367void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1368 PrintExpr(Node->getSubExpr());
1369}
1370
1371void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1372 ValueDecl *VD = Node->getDecl();
1373 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(VD)) {
1374 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1375 return;
1376 }
1377 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(VD)) {
1378 TPOD->printAsExpr(OS, Policy);
1379 return;
1380 }
1381 bool ForceAnonymous =
1382 Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm;
1383 bool CleanUglifiedParameter = Policy.CleanUglifiedParameters &&
1385
1386 if (Policy.FullyQualifiedName && !ForceAnonymous && !CleanUglifiedParameter &&
1387 !VD->isTemplateParameter()) {
1388 VD->printQualifiedName(OS, Policy);
1389 } else {
1390 Node->getQualifier().print(OS, Policy);
1391 if (Node->hasTemplateKeyword())
1392 OS << "template ";
1393
1394 DeclarationNameInfo NameInfo = Node->getNameInfo();
1395 if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
1396 !ForceAnonymous && (ID || NameInfo.getName().getNameKind() !=
1398 if (CleanUglifiedParameter && ID)
1399 OS << ID->deuglifiedName();
1400 else
1401 NameInfo.printName(OS, Policy);
1402 } else {
1403 switch (VD->getKind()) {
1404 case Decl::NonTypeTemplateParm: {
1405 auto *TD = cast<NonTypeTemplateParmDecl>(VD);
1406 OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex()
1407 << "";
1408 break;
1409 }
1410 case Decl::ParmVar: {
1411 auto *PD = cast<ParmVarDecl>(VD);
1412 OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
1413 << PD->getFunctionScopeIndex();
1414 break;
1415 }
1416 case Decl::Decomposition:
1417 OS << "decomposition";
1418 for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
1419 OS << '-' << I->getName();
1420 break;
1421 default:
1422 OS << "unhandled-anonymous-" << VD->getDeclKindName();
1423 break;
1424 }
1425 }
1426 }
1427 if (Node->hasExplicitTemplateArgs()) {
1428 const TemplateParameterList *TPL = nullptr;
1429 if (!Node->hadMultipleCandidates())
1430 if (auto *TD = dyn_cast<TemplateDecl>(VD))
1431 TPL = TD->getTemplateParameters();
1432 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1433 }
1434}
1435
1436void StmtPrinter::VisitDependentScopeDeclRefExpr(
1437 DependentScopeDeclRefExpr *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
1446void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1447 Node->getQualifier().print(OS, Policy);
1448 if (Node->hasTemplateKeyword())
1449 OS << "template ";
1450 OS << Node->getNameInfo();
1451 if (Node->hasExplicitTemplateArgs())
1452 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1453}
1454
1455static bool isImplicitSelf(const Expr *E) {
1456 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1457 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1458 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1459 DRE->getBeginLoc().isInvalid())
1460 return true;
1461 }
1462 }
1463 return false;
1464}
1465
1466void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1467 if (Node->getBase()) {
1468 if (!Policy.SuppressImplicitBase ||
1469 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1470 PrintExpr(Node->getBase());
1471 OS << (Node->isArrow() ? "->" : ".");
1472 }
1473 }
1474 OS << *Node->getDecl();
1475}
1476
1477void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1478 if (Node->isSuperReceiver())
1479 OS << "super.";
1480 else if (Node->isObjectReceiver() && Node->getBase()) {
1481 PrintExpr(Node->getBase());
1482 OS << ".";
1483 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1484 OS << Node->getClassReceiver()->getName() << ".";
1485 }
1486
1487 if (Node->isImplicitProperty()) {
1488 if (const auto *Getter = Node->getImplicitPropertyGetter())
1489 Getter->getSelector().print(OS);
1490 else
1493 } else
1494 OS << Node->getExplicitProperty()->getName();
1495}
1496
1497void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1498 PrintExpr(Node->getBaseExpr());
1499 OS << "[";
1500 PrintExpr(Node->getKeyExpr());
1501 OS << "]";
1502}
1503
1504void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1505 SYCLUniqueStableNameExpr *Node) {
1506 OS << "__builtin_sycl_unique_stable_name(";
1507 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1508 OS << ")";
1509}
1510
1511void StmtPrinter::VisitUnresolvedSYCLKernelCallStmt(
1512 UnresolvedSYCLKernelCallStmt *Node) {
1513 PrintStmt(Node->getOriginalStmt());
1514}
1515
1516void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1518}
1519
1520void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {
1521 OS << '*';
1522}
1523
1524void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1525 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1526}
1527
1528/// Prints the given expression using the original source text. Returns true on
1529/// success, false otherwise.
1530static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1531 const ASTContext *Context) {
1532 if (!Context)
1533 return false;
1534 bool Invalid = false;
1535 StringRef Source = Lexer::getSourceText(
1537 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1538 if (!Invalid) {
1539 OS << Source;
1540 return true;
1541 }
1542 return false;
1543}
1544
1545void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1546 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1547 return;
1548 bool isSigned = Node->getType()->isSignedIntegerType();
1549 OS << toString(Node->getValue(), 10, isSigned);
1550
1551 if (isa<BitIntType>(Node->getType())) {
1552 OS << (isSigned ? "wb" : "uwb");
1553 return;
1554 }
1555
1556 // Emit suffixes. Integer literals are always a builtin integer type.
1557 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1558 default: llvm_unreachable("Unexpected type for integer literal!");
1559 case BuiltinType::Char_S:
1560 case BuiltinType::Char_U: OS << "i8"; break;
1561 case BuiltinType::UChar: OS << "Ui8"; break;
1562 case BuiltinType::SChar: OS << "i8"; break;
1563 case BuiltinType::Short: OS << "i16"; break;
1564 case BuiltinType::UShort: OS << "Ui16"; break;
1565 case BuiltinType::Int: break; // no suffix.
1566 case BuiltinType::UInt: OS << 'U'; break;
1567 case BuiltinType::Long: OS << 'L'; break;
1568 case BuiltinType::ULong: OS << "UL"; break;
1569 case BuiltinType::LongLong: OS << "LL"; break;
1570 case BuiltinType::ULongLong: OS << "ULL"; break;
1571 case BuiltinType::Int128:
1572 break; // no suffix.
1573 case BuiltinType::UInt128:
1574 break; // no suffix.
1575 case BuiltinType::WChar_S:
1576 case BuiltinType::WChar_U:
1577 break; // no suffix
1578 }
1579}
1580
1581void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1582 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1583 return;
1584 OS << Node->getValueAsString(/*Radix=*/10);
1585
1586 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1587 default: llvm_unreachable("Unexpected type for fixed point literal!");
1588 case BuiltinType::ShortFract: OS << "hr"; break;
1589 case BuiltinType::ShortAccum: OS << "hk"; break;
1590 case BuiltinType::UShortFract: OS << "uhr"; break;
1591 case BuiltinType::UShortAccum: OS << "uhk"; break;
1592 case BuiltinType::Fract: OS << "r"; break;
1593 case BuiltinType::Accum: OS << "k"; break;
1594 case BuiltinType::UFract: OS << "ur"; break;
1595 case BuiltinType::UAccum: OS << "uk"; break;
1596 case BuiltinType::LongFract: OS << "lr"; break;
1597 case BuiltinType::LongAccum: OS << "lk"; break;
1598 case BuiltinType::ULongFract: OS << "ulr"; break;
1599 case BuiltinType::ULongAccum: OS << "ulk"; break;
1600 }
1601}
1602
1603static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1604 bool PrintSuffix) {
1605 SmallString<16> Str;
1606 Node->getValue().toString(Str);
1607 OS << Str;
1608 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1609 OS << '.'; // Trailing dot in order to separate from ints.
1610
1611 if (!PrintSuffix)
1612 return;
1613
1614 // Emit suffixes. Float literals are always a builtin float type.
1615 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1616 default: llvm_unreachable("Unexpected type for float literal!");
1617 case BuiltinType::Half: break; // FIXME: suffix?
1618 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1619 case BuiltinType::Double: break; // no suffix.
1620 case BuiltinType::Float16: OS << "F16"; break;
1621 case BuiltinType::Float: OS << 'F'; break;
1622 case BuiltinType::LongDouble: OS << 'L'; break;
1623 case BuiltinType::Float128: OS << 'Q'; break;
1624 }
1625}
1626
1627void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1628 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1629 return;
1630 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1631}
1632
1633void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1634 PrintExpr(Node->getSubExpr());
1635 OS << "i";
1636}
1637
1638void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1639 Str->outputString(OS);
1640}
1641
1642void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1643 OS << "(";
1644 PrintExpr(Node->getSubExpr());
1645 OS << ")";
1646}
1647
1648void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1649 if (!Node->isPostfix()) {
1651
1652 // Print a space if this is an "identifier operator" like __real, or if
1653 // it might be concatenated incorrectly like '+'.
1654 switch (Node->getOpcode()) {
1655 default: break;
1656 case UO_Real:
1657 case UO_Imag:
1658 case UO_Extension:
1659 OS << ' ';
1660 break;
1661 case UO_Plus:
1662 case UO_Minus:
1663 if (isa<UnaryOperator>(Node->getSubExpr()))
1664 OS << ' ';
1665 break;
1666 }
1667 }
1668 PrintExpr(Node->getSubExpr());
1669
1670 if (Node->isPostfix())
1672}
1673
1674void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1675 OS << "__builtin_offsetof(";
1676 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1677 OS << ", ";
1678 bool PrintedSomething = false;
1679 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1680 OffsetOfNode ON = Node->getComponent(i);
1681 if (ON.getKind() == OffsetOfNode::Array) {
1682 // Array node
1683 OS << "[";
1684 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1685 OS << "]";
1686 PrintedSomething = true;
1687 continue;
1688 }
1689
1690 // Skip implicit base indirections.
1691 if (ON.getKind() == OffsetOfNode::Base)
1692 continue;
1693
1694 // Field or identifier node.
1695 const IdentifierInfo *Id = ON.getFieldName();
1696 if (!Id)
1697 continue;
1698
1699 if (PrintedSomething)
1700 OS << ".";
1701 else
1702 PrintedSomething = true;
1703 OS << Id->getName();
1704 }
1705 OS << ")";
1706}
1707
1708void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1709 UnaryExprOrTypeTraitExpr *Node) {
1710 const char *Spelling = getTraitSpelling(Node->getKind());
1711 if (Node->getKind() == UETT_AlignOf) {
1712 if (Policy.Alignof)
1713 Spelling = "alignof";
1714 else if (Policy.UnderscoreAlignof)
1715 Spelling = "_Alignof";
1716 else
1717 Spelling = "__alignof";
1718 }
1719
1720 OS << Spelling;
1721
1722 if (Node->isArgumentType()) {
1723 OS << '(';
1724 Node->getArgumentType().print(OS, Policy);
1725 OS << ')';
1726 } else {
1727 OS << " ";
1728 PrintExpr(Node->getArgumentExpr());
1729 }
1730}
1731
1732void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1733 OS << "_Generic(";
1734 if (Node->isExprPredicate())
1735 PrintExpr(Node->getControllingExpr());
1736 else
1737 Node->getControllingType()->getType().print(OS, Policy);
1738
1739 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1740 OS << ", ";
1741 QualType T = Assoc.getType();
1742 if (T.isNull())
1743 OS << "default";
1744 else
1745 T.print(OS, Policy);
1746 OS << ": ";
1747 PrintExpr(Assoc.getAssociationExpr());
1748 }
1749 OS << ")";
1750}
1751
1752void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1753 PrintExpr(Node->getLHS());
1754 OS << "[";
1755 PrintExpr(Node->getRHS());
1756 OS << "]";
1757}
1758
1759void StmtPrinter::VisitMatrixSingleSubscriptExpr(
1760 MatrixSingleSubscriptExpr *Node) {
1761 PrintExpr(Node->getBase());
1762 OS << "[";
1763 PrintExpr(Node->getRowIdx());
1764 OS << "]";
1765}
1766
1767void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1768 PrintExpr(Node->getBase());
1769 OS << "[";
1770 PrintExpr(Node->getRowIdx());
1771 OS << "]";
1772 OS << "[";
1773 PrintExpr(Node->getColumnIdx());
1774 OS << "]";
1775}
1776
1777void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1778 PrintExpr(Node->getBase());
1779 OS << "[";
1780 if (Node->getLowerBound())
1781 PrintExpr(Node->getLowerBound());
1782 if (Node->getColonLocFirst().isValid()) {
1783 OS << ":";
1784 if (Node->getLength())
1785 PrintExpr(Node->getLength());
1786 }
1787 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1788 OS << ":";
1789 if (Node->getStride())
1790 PrintExpr(Node->getStride());
1791 }
1792 OS << "]";
1793}
1794
1795void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1796 OS << "(";
1797 for (Expr *E : Node->getDimensions()) {
1798 OS << "[";
1799 PrintExpr(E);
1800 OS << "]";
1801 }
1802 OS << ")";
1803 PrintExpr(Node->getBase());
1804}
1805
1806void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1807 OS << "iterator(";
1808 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1809 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1810 VD->getType().print(OS, Policy);
1811 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1812 OS << " " << VD->getName() << " = ";
1813 PrintExpr(Range.Begin);
1814 OS << ":";
1815 PrintExpr(Range.End);
1816 if (Range.Step) {
1817 OS << ":";
1818 PrintExpr(Range.Step);
1819 }
1820 if (I < E - 1)
1821 OS << ", ";
1822 }
1823 OS << ")";
1824}
1825
1826void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1827 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1828 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1829 // Don't print any defaulted arguments
1830 break;
1831 }
1832
1833 if (i) OS << ", ";
1834 PrintExpr(Call->getArg(i));
1835 }
1836}
1837
1838void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1839 PrintExpr(Call->getCallee());
1840 OS << "(";
1841 PrintCallArgs(Call);
1842 OS << ")";
1843}
1844
1845static bool isImplicitThis(const Expr *E) {
1846 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1847 return TE->isImplicit();
1848 return false;
1849}
1850
1851void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1852 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1853 PrintExpr(Node->getBase());
1854
1855 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1856 FieldDecl *ParentDecl =
1857 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1858 : nullptr;
1859
1860 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1861 OS << (Node->isArrow() ? "->" : ".");
1862 }
1863
1864 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1865 if (FD->isAnonymousStructOrUnion())
1866 return;
1867
1868 Node->getQualifier().print(OS, Policy);
1869 if (Node->hasTemplateKeyword())
1870 OS << "template ";
1871 OS << Node->getMemberNameInfo();
1872 const TemplateParameterList *TPL = nullptr;
1873 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1874 if (!Node->hadMultipleCandidates())
1875 if (auto *FTD = FD->getPrimaryTemplate())
1876 TPL = FTD->getTemplateParameters();
1877 } else if (auto *VTSD =
1878 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1879 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1880 if (Node->hasExplicitTemplateArgs())
1881 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1882}
1883
1884void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1885 PrintExpr(Node->getBase());
1886 OS << (Node->isArrow() ? "->isa" : ".isa");
1887}
1888
1889void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1890 PrintExpr(Node->getBase());
1891 OS << ".";
1892 OS << Node->getAccessor().getName();
1893}
1894
1895void StmtPrinter::VisitMatrixElementExpr(MatrixElementExpr *Node) {
1896 PrintExpr(Node->getBase());
1897 OS << ".";
1898 OS << Node->getAccessor().getName();
1899}
1900
1901void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1902 if (QualType T = Node->getType(); Policy.PrettyEnums && T->isEnumeralType()) {
1903 // special case enums to avoid producing cast expressions when naming
1904 // an enumerator would suffice
1905
1906 const auto *IL = dyn_cast<IntegerLiteral>(Node->getSubExpr());
1907 const auto *ED = T->getAsEnumDecl();
1908 if (IL && ED) {
1909 llvm::APInt Val = IL->getValue();
1910 const auto ECD =
1911 llvm::find_if(ED->enumerators(), [&](const EnumConstantDecl *ECD) {
1912 return llvm::APInt::isSameValue(ECD->getInitVal(), Val);
1913 });
1914 if (ECD != ED->enumerator_end()) {
1915 ECD->printQualifiedName(OS, Policy);
1916 return;
1917 }
1918 }
1919 }
1920 OS << '(';
1921 Node->getTypeAsWritten().print(OS, Policy);
1922 OS << ')';
1923 PrintExpr(Node->getSubExpr());
1924}
1925
1926void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1927 OS << '(';
1928 Node->getType().print(OS, Policy);
1929 OS << ')';
1930 PrintExpr(Node->getInitializer());
1931}
1932
1933void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1934 // No need to print anything, simply forward to the subexpression.
1935 PrintExpr(Node->getSubExpr());
1936}
1937
1938void StmtPrinter::VisitBinComma(BinaryOperator *Node) {
1939 PrintExpr(Node->getLHS());
1940 OS << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1941 PrintExpr(Node->getRHS());
1942}
1943
1944void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1945 PrintExpr(Node->getLHS());
1946 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1947 PrintExpr(Node->getRHS());
1948}
1949
1950void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1951 PrintExpr(Node->getLHS());
1952 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1953 PrintExpr(Node->getRHS());
1954}
1955
1956void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1957 PrintExpr(Node->getCond());
1958 OS << " ? ";
1959 PrintExpr(Node->getLHS());
1960 OS << " : ";
1961 PrintExpr(Node->getRHS());
1962}
1963
1964// GNU extensions.
1965
1966void
1967StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1968 PrintExpr(Node->getCommon());
1969 OS << " ?: ";
1970 PrintExpr(Node->getFalseExpr());
1971}
1972
1973void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1974 OS << "&&" << Node->getLabel()->getName();
1975}
1976
1977void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1978 OS << "(";
1979 PrintRawCompoundStmt(E->getSubStmt());
1980 OS << ")";
1981}
1982
1983void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1984 OS << "__builtin_choose_expr(";
1985 PrintExpr(Node->getCond());
1986 OS << ", ";
1987 PrintExpr(Node->getLHS());
1988 OS << ", ";
1989 PrintExpr(Node->getRHS());
1990 OS << ")";
1991}
1992
1993void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1994 OS << "__null";
1995}
1996
1997void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1998 OS << "__builtin_shufflevector(";
1999 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
2000 if (i) OS << ", ";
2001 PrintExpr(Node->getExpr(i));
2002 }
2003 OS << ")";
2004}
2005
2006void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
2007 OS << "__builtin_convertvector(";
2008 PrintExpr(Node->getSrcExpr());
2009 OS << ", ";
2010 Node->getType().print(OS, Policy);
2011 OS << ")";
2012}
2013
2014void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
2015 if (Node->getSyntacticForm()) {
2016 Visit(Node->getSyntacticForm());
2017 return;
2018 }
2019
2020 OS << "{";
2021 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
2022 if (i) OS << ", ";
2023 if (Node->getInit(i))
2024 PrintExpr(Node->getInit(i));
2025 else
2026 OS << "{}";
2027 }
2028 OS << "}";
2029}
2030
2031void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
2032 // There's no way to express this expression in any of our supported
2033 // languages, so just emit something terse and (hopefully) clear.
2034 OS << "{";
2035 PrintExpr(Node->getSubExpr());
2036 OS << "}";
2037}
2038
2039void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
2040 OS << "*";
2041}
2042
2043void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
2044 OS << "(";
2045 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
2046 if (i) OS << ", ";
2047 PrintExpr(Node->getExpr(i));
2048 }
2049 OS << ")";
2050}
2051
2052void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
2053 bool NeedsEquals = true;
2054 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
2055 if (D.isFieldDesignator()) {
2056 if (D.getDotLoc().isInvalid()) {
2057 if (const IdentifierInfo *II = D.getFieldName()) {
2058 OS << II->getName() << ":";
2059 NeedsEquals = false;
2060 }
2061 } else {
2062 OS << "." << D.getFieldName()->getName();
2063 }
2064 } else {
2065 OS << "[";
2066 if (D.isArrayDesignator()) {
2067 PrintExpr(Node->getArrayIndex(D));
2068 } else {
2069 PrintExpr(Node->getArrayRangeStart(D));
2070 OS << " ... ";
2071 PrintExpr(Node->getArrayRangeEnd(D));
2072 }
2073 OS << "]";
2074 }
2075 }
2076
2077 if (NeedsEquals)
2078 OS << " = ";
2079 else
2080 OS << " ";
2081 PrintExpr(Node->getInit());
2082}
2083
2084void StmtPrinter::VisitDesignatedInitUpdateExpr(
2085 DesignatedInitUpdateExpr *Node) {
2086 OS << "{";
2087 OS << "/*base*/";
2088 PrintExpr(Node->getBase());
2089 OS << ", ";
2090
2091 OS << "/*updater*/";
2092 PrintExpr(Node->getUpdater());
2093 OS << "}";
2094}
2095
2096void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
2097 OS << "/*no init*/";
2098}
2099
2100void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
2101 if (Node->getType()->getAsCXXRecordDecl()) {
2102 OS << "/*implicit*/";
2103 Node->getType().print(OS, Policy);
2104 OS << "()";
2105 } else {
2106 OS << "/*implicit*/(";
2107 Node->getType().print(OS, Policy);
2108 OS << ')';
2109 if (Node->getType()->isRecordType())
2110 OS << "{}";
2111 else
2112 OS << 0;
2113 }
2114}
2115
2116void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
2117 OS << "__builtin_va_arg(";
2118 PrintExpr(Node->getSubExpr());
2119 OS << ", ";
2120 Node->getType().print(OS, Policy);
2121 OS << ")";
2122}
2123
2124void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
2125 PrintExpr(Node->getSyntacticForm());
2126}
2127
2128void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
2129 const char *Name = nullptr;
2130 switch (Node->getOp()) {
2131#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2132 case AtomicExpr::AO ## ID: \
2133 Name = #ID "("; \
2134 break;
2135#include "clang/Basic/Builtins.inc"
2136 }
2137 OS << Name;
2138
2139 // AtomicExpr stores its subexpressions in a permuted order.
2140 PrintExpr(Node->getPtr());
2141 if (Node->hasVal1Operand()) {
2142 OS << ", ";
2143 PrintExpr(Node->getVal1());
2144 }
2145 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
2146 Node->isCmpXChg()) {
2147 OS << ", ";
2148 PrintExpr(Node->getVal2());
2149 }
2150 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
2151 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
2152 OS << ", ";
2153 PrintExpr(Node->getWeak());
2154 }
2155 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
2156 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
2157 OS << ", ";
2158 PrintExpr(Node->getOrder());
2159 }
2160 if (Node->isCmpXChg()) {
2161 OS << ", ";
2162 PrintExpr(Node->getOrderFail());
2163 }
2164 OS << ")";
2165}
2166
2167// C++
2168void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
2170 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
2171 if (Node->getNumArgs() == 1) {
2172 OS << getOperatorSpelling(Kind) << ' ';
2173 PrintExpr(Node->getArg(0));
2174 } else {
2175 PrintExpr(Node->getArg(0));
2176 OS << ' ' << getOperatorSpelling(Kind);
2177 }
2178 } else if (Kind == OO_Arrow) {
2179 PrintExpr(Node->getArg(0));
2180 } else if (Kind == OO_Call || Kind == OO_Subscript) {
2181 PrintExpr(Node->getArg(0));
2182 OS << (Kind == OO_Call ? '(' : '[');
2183 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
2184 if (ArgIdx > 1)
2185 OS << ", ";
2186 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
2187 PrintExpr(Node->getArg(ArgIdx));
2188 }
2189 OS << (Kind == OO_Call ? ')' : ']');
2190 } else if (Node->getNumArgs() == 1) {
2191 OS << getOperatorSpelling(Kind) << ' ';
2192 PrintExpr(Node->getArg(0));
2193 } else if (Node->getNumArgs() == 2) {
2194 PrintExpr(Node->getArg(0));
2195 OS << ' ' << getOperatorSpelling(Kind) << ' ';
2196 PrintExpr(Node->getArg(1));
2197 } else {
2198 llvm_unreachable("unknown overloaded operator");
2199 }
2200}
2201
2202void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2203 // If we have a conversion operator call only print the argument.
2204 CXXMethodDecl *MD = Node->getMethodDecl();
2205 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2206 PrintExpr(Node->getImplicitObjectArgument());
2207 return;
2208 }
2209 VisitCallExpr(cast<CallExpr>(Node));
2210}
2211
2212void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2213 PrintExpr(Node->getCallee());
2214 OS << "<<<";
2215 PrintCallArgs(Node->getConfig());
2216 OS << ">>>(";
2217 PrintCallArgs(Node);
2218 OS << ")";
2219}
2220
2221void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2222 CXXRewrittenBinaryOperator *Node) {
2223 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
2224 Node->getDecomposedForm();
2225 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
2226 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
2227 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
2228}
2229
2230void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2231 OS << Node->getCastName() << '<';
2232 Node->getTypeAsWritten().print(OS, Policy);
2233 OS << ">(";
2234 PrintExpr(Node->getSubExpr());
2235 OS << ")";
2236}
2237
2238void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2239 VisitCXXNamedCastExpr(Node);
2240}
2241
2242void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2243 VisitCXXNamedCastExpr(Node);
2244}
2245
2246void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2247 VisitCXXNamedCastExpr(Node);
2248}
2249
2250void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2251 VisitCXXNamedCastExpr(Node);
2252}
2253
2254void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2255 OS << "__builtin_bit_cast(";
2256 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2257 OS << ", ";
2258 PrintExpr(Node->getSubExpr());
2259 OS << ")";
2260}
2261
2262void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2263 VisitCXXNamedCastExpr(Node);
2264}
2265
2266void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2267 OS << "typeid(";
2268 if (Node->isTypeOperand()) {
2269 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2270 } else {
2271 PrintExpr(Node->getExprOperand());
2272 }
2273 OS << ")";
2274}
2275
2276void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2277 OS << "__uuidof(";
2278 if (Node->isTypeOperand()) {
2279 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2280 } else {
2281 PrintExpr(Node->getExprOperand());
2282 }
2283 OS << ")";
2284}
2285
2286void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2287 PrintExpr(Node->getBaseExpr());
2288 if (Node->isArrow())
2289 OS << "->";
2290 else
2291 OS << ".";
2292 Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);
2293 OS << Node->getPropertyDecl()->getDeclName();
2294}
2295
2296void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2297 PrintExpr(Node->getBase());
2298 OS << "[";
2299 PrintExpr(Node->getIdx());
2300 OS << "]";
2301}
2302
2303void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2304 switch (Node->getLiteralOperatorKind()) {
2306 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2307 break;
2309 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2310 const TemplateArgumentList *Args =
2311 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2312 assert(Args);
2313
2314 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2315 const TemplateParameterList *TPL = nullptr;
2316 if (!DRE->hadMultipleCandidates())
2317 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2318 TPL = TD->getTemplateParameters();
2319 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2320 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2321 OS << "()";
2322 return;
2323 }
2324
2325 const TemplateArgument &Pack = Args->get(0);
2326 for (const auto &P : Pack.pack_elements()) {
2327 char C = (char)P.getAsIntegral().getZExtValue();
2328 OS << C;
2329 }
2330 break;
2331 }
2333 // Print integer literal without suffix.
2334 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2335 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2336 break;
2337 }
2339 // Print floating literal without suffix.
2341 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2342 break;
2343 }
2346 PrintExpr(Node->getCookedLiteral());
2347 break;
2348 }
2349 OS << Node->getUDSuffix()->getName();
2350}
2351
2352void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2353 OS << (Node->getValue() ? "true" : "false");
2354}
2355
2356void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2357 OS << "nullptr";
2358}
2359
2360void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2361 OS << "this";
2362}
2363
2364void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2365 if (!Node->getSubExpr())
2366 OS << "throw";
2367 else {
2368 OS << "throw ";
2369 PrintExpr(Node->getSubExpr());
2370 }
2371}
2372
2373void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2374 // Nothing to print: we picked up the default argument.
2375}
2376
2377void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2378 // Nothing to print: we picked up the default initializer.
2379}
2380
2381void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2382 auto TargetType = Node->getType();
2383 auto *Auto = TargetType->getContainedDeducedType();
2384 bool Bare = Auto && Auto->isDeduced();
2385
2386 // Parenthesize deduced casts.
2387 if (Bare)
2388 OS << '(';
2389 TargetType.print(OS, Policy);
2390 if (Bare)
2391 OS << ')';
2392
2393 // No extra braces surrounding the inner construct.
2394 if (!Node->isListInitialization())
2395 OS << '(';
2396 PrintExpr(Node->getSubExpr());
2397 if (!Node->isListInitialization())
2398 OS << ')';
2399}
2400
2401void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2402 PrintExpr(Node->getSubExpr());
2403}
2404
2405void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2406 Node->getType().print(OS, Policy);
2407 if (Node->isStdInitListInitialization())
2408 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2409 else if (Node->isListInitialization())
2410 OS << "{";
2411 else
2412 OS << "(";
2413 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2414 ArgEnd = Node->arg_end();
2415 Arg != ArgEnd; ++Arg) {
2416 if ((*Arg)->isDefaultArgument())
2417 break;
2418 if (Arg != Node->arg_begin())
2419 OS << ", ";
2420 PrintExpr(*Arg);
2421 }
2422 if (Node->isStdInitListInitialization())
2423 /* See above. */;
2424 else if (Node->isListInitialization())
2425 OS << "}";
2426 else
2427 OS << ")";
2428}
2429
2430void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2431 OS << '[';
2432 bool NeedComma = false;
2433 switch (Node->getCaptureDefault()) {
2434 case LCD_None:
2435 break;
2436
2437 case LCD_ByCopy:
2438 OS << '=';
2439 NeedComma = true;
2440 break;
2441
2442 case LCD_ByRef:
2443 OS << '&';
2444 NeedComma = true;
2445 break;
2446 }
2448 CEnd = Node->explicit_capture_end();
2449 C != CEnd;
2450 ++C) {
2451 if (C->capturesVLAType())
2452 continue;
2453
2454 if (NeedComma)
2455 OS << ", ";
2456 NeedComma = true;
2457
2458 switch (C->getCaptureKind()) {
2459 case LCK_This:
2460 OS << "this";
2461 break;
2462
2463 case LCK_StarThis:
2464 OS << "*this";
2465 break;
2466
2467 case LCK_ByRef:
2468 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2469 OS << '&';
2470 OS << C->getCapturedVar()->getName();
2471 break;
2472
2473 case LCK_ByCopy:
2474 OS << C->getCapturedVar()->getName();
2475 break;
2476
2477 case LCK_VLAType:
2478 llvm_unreachable("VLA type in explicit captures.");
2479 }
2480
2481 if (C->isPackExpansion())
2482 OS << "...";
2483
2484 if (Node->isInitCapture(C)) {
2485 // Init captures are always VarDecl.
2486 auto *D = cast<VarDecl>(C->getCapturedVar());
2487
2488 llvm::StringRef Pre;
2489 llvm::StringRef Post;
2490 if (D->getInitStyle() == VarDecl::CallInit &&
2491 !isa<ParenListExpr>(D->getInit())) {
2492 Pre = "(";
2493 Post = ")";
2494 } else if (D->getInitStyle() == VarDecl::CInit) {
2495 Pre = " = ";
2496 }
2497
2498 OS << Pre;
2499 PrintExpr(D->getInit());
2500 OS << Post;
2501 }
2502 }
2503 OS << ']';
2504
2505 if (!Node->getExplicitTemplateParameters().empty()) {
2507 OS, Node->getLambdaClass()->getASTContext(),
2508 /*OmitTemplateKW*/true);
2509 }
2510
2511 if (Node->hasExplicitParameters()) {
2512 OS << '(';
2513 CXXMethodDecl *Method = Node->getCallOperator();
2514 NeedComma = false;
2515 for (const auto *P : Method->parameters()) {
2516 if (NeedComma) {
2517 OS << ", ";
2518 } else {
2519 NeedComma = true;
2520 }
2521 std::string ParamStr =
2522 (Policy.CleanUglifiedParameters && P->getIdentifier())
2523 ? P->getIdentifier()->deuglifiedName().str()
2524 : P->getNameAsString();
2525 P->getOriginalType().print(OS, Policy, ParamStr);
2526 }
2527 if (Method->isVariadic()) {
2528 if (NeedComma)
2529 OS << ", ";
2530 OS << "...";
2531 }
2532 OS << ')';
2533
2534 if (Node->isMutable())
2535 OS << " mutable";
2536
2537 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2538 Proto->printExceptionSpecification(OS, Policy);
2539
2540 // FIXME: Attributes
2541
2542 // Print the trailing return type if it was specified in the source.
2543 if (Node->hasExplicitResultType()) {
2544 OS << " -> ";
2545 Proto->getReturnType().print(OS, Policy);
2546 }
2547 }
2548
2549 // Print the body.
2550 OS << ' ';
2551 if (Policy.TerseOutput || Policy.SuppressLambdaBody)
2552 OS << "{}";
2553 else
2554 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2555}
2556
2557void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2558 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2559 TSInfo->getType().print(OS, Policy);
2560 else
2561 Node->getType().print(OS, Policy);
2562 OS << "()";
2563}
2564
2565void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2566 if (E->isGlobalNew())
2567 OS << "::";
2568 OS << "new ";
2569 unsigned NumPlace = E->getNumPlacementArgs();
2570 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2571 OS << "(";
2572 PrintExpr(E->getPlacementArg(0));
2573 for (unsigned i = 1; i < NumPlace; ++i) {
2575 break;
2576 OS << ", ";
2577 PrintExpr(E->getPlacementArg(i));
2578 }
2579 OS << ") ";
2580 }
2581 if (E->isParenTypeId())
2582 OS << "(";
2583 std::string TypeS;
2584 if (E->isArray()) {
2585 llvm::raw_string_ostream s(TypeS);
2586 s << '[';
2587 if (std::optional<Expr *> Size = E->getArraySize())
2588 (*Size)->printPretty(s, Helper, Policy);
2589 s << ']';
2590 }
2591 E->getAllocatedType().print(OS, Policy, TypeS);
2592 if (E->isParenTypeId())
2593 OS << ")";
2594
2596 if (InitStyle != CXXNewInitializationStyle::None) {
2597 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2599 if (Bare)
2600 OS << "(";
2601 PrintExpr(E->getInitializer());
2602 if (Bare)
2603 OS << ")";
2604 }
2605}
2606
2607void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2608 if (E->isGlobalDelete())
2609 OS << "::";
2610 OS << "delete ";
2611 if (E->isArrayForm())
2612 OS << "[] ";
2613 PrintExpr(E->getArgument());
2614}
2615
2616void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2617 PrintExpr(E->getBase());
2618 if (E->isArrow())
2619 OS << "->";
2620 else
2621 OS << '.';
2622 E->getQualifier().print(OS, Policy);
2623 OS << "~";
2624
2625 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2626 OS << II->getName();
2627 else
2628 E->getDestroyedType().print(OS, Policy);
2629}
2630
2631void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2633 OS << "{";
2634
2635 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2636 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2637 // Don't print any defaulted arguments
2638 break;
2639 }
2640
2641 if (i) OS << ", ";
2642 PrintExpr(E->getArg(i));
2643 }
2644
2646 OS << "}";
2647}
2648
2649void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2650 // Parens are printed by the surrounding context.
2651 OS << "<forwarded>";
2652}
2653
2654void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2655 PrintExpr(E->getSubExpr());
2656}
2657
2658void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2659 // Just forward to the subexpression.
2660 PrintExpr(E->getSubExpr());
2661}
2662
2663void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2664 CXXUnresolvedConstructExpr *Node) {
2665 Node->getTypeAsWritten().print(OS, Policy);
2666 if (!Node->isListInitialization())
2667 OS << '(';
2668 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2669 ++Arg) {
2670 if (Arg != Node->arg_begin())
2671 OS << ", ";
2672 PrintExpr(*Arg);
2673 }
2674 if (!Node->isListInitialization())
2675 OS << ')';
2676}
2677
2678void StmtPrinter::VisitCXXReflectExpr(CXXReflectExpr *S) {
2679 // TODO(Reflection): add support for the remaining reflection kinds.
2680 OS << "^^";
2681 switch (S->getKind()) {
2682 case ReflectionKind::Null:
2683 assert(false && "null reflection can't be constructed from parsing a "
2684 "reflection operand");
2685 break;
2686 case ReflectionKind::Type:
2687 S->getTypeSourceInfo()->getType().print(OS, Policy);
2688 break;
2689 }
2690}
2691
2692void StmtPrinter::VisitDependentTemplateIdExpr(DependentTemplateIdExpr *Node) {
2693 Node->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
2694 printTemplateArgumentList(OS, Node->template_arguments(), Policy,
2696}
2697
2698void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2699 CXXDependentScopeMemberExpr *Node) {
2700 if (!Node->isImplicitAccess()) {
2701 PrintExpr(Node->getBase());
2702 OS << (Node->isArrow() ? "->" : ".");
2703 }
2704 Node->getQualifier().print(OS, Policy);
2705 if (Node->hasTemplateKeyword())
2706 OS << "template ";
2707 OS << Node->getMemberNameInfo();
2708 if (Node->hasExplicitTemplateArgs())
2709 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2710}
2711
2712void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2713 if (!Node->isImplicitAccess()) {
2714 PrintExpr(Node->getBase());
2715 OS << (Node->isArrow() ? "->" : ".");
2716 }
2717 Node->getQualifier().print(OS, Policy);
2718 if (Node->hasTemplateKeyword())
2719 OS << "template ";
2720 OS << Node->getMemberNameInfo();
2721 if (Node->hasExplicitTemplateArgs())
2722 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2723}
2724
2725void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2726 OS << getTraitSpelling(E->getTrait()) << "(";
2727 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2728 if (I > 0)
2729 OS << ", ";
2730 E->getArg(I)->getType().print(OS, Policy);
2731 }
2732 OS << ")";
2733}
2734
2735void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2736 OS << getTraitSpelling(E->getTrait()) << '(';
2737 E->getQueriedType().print(OS, Policy);
2738 OS << ')';
2739}
2740
2741void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2742 OS << getTraitSpelling(E->getTrait()) << '(';
2743 PrintExpr(E->getQueriedExpression());
2744 OS << ')';
2745}
2746
2747void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2748 OS << "noexcept(";
2749 PrintExpr(E->getOperand());
2750 OS << ")";
2751}
2752
2753void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2754 PrintExpr(E->getPattern());
2755 OS << "...";
2756}
2757
2758void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2759 OS << "sizeof...(" << *E->getPack() << ")";
2760}
2761
2762void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2763 PrintExpr(E->getPackIdExpression());
2764 OS << "...[";
2765 PrintExpr(E->getIndexExpr());
2766 OS << "]";
2767}
2768
2769void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2770 SubstNonTypeTemplateParmPackExpr *Node) {
2771 OS << *Node->getParameterPack();
2772}
2773
2774void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2775 SubstNonTypeTemplateParmExpr *Node) {
2776 Visit(Node->getReplacement());
2777}
2778
2779void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2780 OS << *E->getParameterPack();
2781}
2782
2783void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2784 PrintExpr(Node->getSubExpr());
2785}
2786
2787void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2788 OS << "(";
2789 if (E->getLHS()) {
2790 PrintExpr(E->getLHS());
2791 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2792 }
2793 OS << "...";
2794 if (E->getRHS()) {
2795 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2796 PrintExpr(E->getRHS());
2797 }
2798 OS << ")";
2799}
2800
2801void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2802 llvm::interleaveComma(Node->getUserSpecifiedInitExprs(), OS,
2803 [&](Expr *E) { PrintExpr(E); });
2804}
2805
2806void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2807 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2808 NNS.getNestedNameSpecifier().print(OS, Policy);
2809 if (E->getTemplateKWLoc().isValid())
2810 OS << "template ";
2811 OS << E->getFoundDecl()->getName();
2812 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2813 Policy,
2815}
2816
2817void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2818 OS << "requires ";
2819 auto LocalParameters = E->getLocalParameters();
2820 if (!LocalParameters.empty()) {
2821 OS << "(";
2822 for (ParmVarDecl *LocalParam : LocalParameters) {
2823 PrintRawDecl(LocalParam);
2824 if (LocalParam != LocalParameters.back())
2825 OS << ", ";
2826 }
2827
2828 OS << ") ";
2829 }
2830 OS << "{ ";
2831 auto Requirements = E->getRequirements();
2832 for (concepts::Requirement *Req : Requirements) {
2833 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2834 if (TypeReq->isSubstitutionFailure())
2835 OS << "<<error-type>>";
2836 else
2837 TypeReq->getType()->getType().print(OS, Policy);
2838 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2839 if (ExprReq->isCompound())
2840 OS << "{ ";
2841 if (ExprReq->isExprSubstitutionFailure())
2842 OS << "<<error-expression>>";
2843 else
2844 PrintExpr(ExprReq->getExpr());
2845 if (ExprReq->isCompound()) {
2846 OS << " }";
2847 if (ExprReq->getNoexceptLoc().isValid())
2848 OS << " noexcept";
2849 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2850 if (!RetReq.isEmpty()) {
2851 OS << " -> ";
2852 if (RetReq.isSubstitutionFailure())
2853 OS << "<<error-type>>";
2854 else if (RetReq.isTypeConstraint())
2855 RetReq.getTypeConstraint()->print(OS, Policy);
2856 }
2857 }
2858 } else {
2859 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2860 OS << "requires ";
2861 if (NestedReq->hasInvalidConstraint())
2862 OS << "<<error-expression>>";
2863 else
2864 PrintExpr(NestedReq->getConstraintExpr());
2865 }
2866 OS << "; ";
2867 }
2868 OS << "}";
2869}
2870
2871// C++ Coroutines
2872
2873void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2874 Visit(S->getBody());
2875}
2876
2877void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2878 OS << "co_return";
2879 if (S->getOperand()) {
2880 OS << " ";
2881 Visit(S->getOperand());
2882 }
2883 OS << ";";
2884}
2885
2886void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2887 OS << "co_await ";
2888 PrintExpr(S->getOperand());
2889}
2890
2891void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2892 OS << "co_await ";
2893 PrintExpr(S->getOperand());
2894}
2895
2896void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2897 OS << "co_yield ";
2898 PrintExpr(S->getOperand());
2899}
2900
2901// Obj-C
2902
2903void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2904 OS << "@";
2905 VisitStringLiteral(Node->getString());
2906}
2907
2908void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2909 OS << "@";
2910 Visit(E->getSubExpr());
2911}
2912
2913void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2914 OS << "@[ ";
2915 ObjCArrayLiteral::child_range Ch = E->children();
2916 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2917 if (I != Ch.begin())
2918 OS << ", ";
2919 Visit(*I);
2920 }
2921 OS << " ]";
2922}
2923
2924void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2925 OS << "@{ ";
2926 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2927 if (I > 0)
2928 OS << ", ";
2929
2930 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2931 Visit(Element.Key);
2932 OS << " : ";
2933 Visit(Element.Value);
2934 if (Element.isPackExpansion())
2935 OS << "...";
2936 }
2937 OS << " }";
2938}
2939
2940void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2941 OS << "@encode(";
2942 Node->getEncodedType().print(OS, Policy);
2943 OS << ')';
2944}
2945
2946void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2947 OS << "@selector(";
2948 Node->getSelector().print(OS);
2949 OS << ')';
2950}
2951
2952void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2953 OS << "@protocol(" << *Node->getProtocol() << ')';
2954}
2955
2956void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2957 OS << "[";
2958 switch (Mess->getReceiverKind()) {
2960 PrintExpr(Mess->getInstanceReceiver());
2961 break;
2962
2964 Mess->getClassReceiver().print(OS, Policy);
2965 break;
2966
2969 OS << "Super";
2970 break;
2971 }
2972
2973 OS << ' ';
2974 Selector selector = Mess->getSelector();
2975 if (selector.isUnarySelector()) {
2976 OS << selector.getNameForSlot(0);
2977 } else {
2978 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2979 if (i < selector.getNumArgs()) {
2980 if (i > 0) OS << ' ';
2981 if (selector.getIdentifierInfoForSlot(i))
2982 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2983 else
2984 OS << ":";
2985 }
2986 else OS << ", "; // Handle variadic methods.
2987
2988 PrintExpr(Mess->getArg(i));
2989 }
2990 }
2991 OS << "]";
2992}
2993
2994void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2995 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2996}
2997
2998void
2999StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
3000 PrintExpr(E->getSubExpr());
3001}
3002
3003void
3004StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
3005 OS << '(' << E->getBridgeKindName();
3006 E->getType().print(OS, Policy);
3007 OS << ')';
3008 PrintExpr(E->getSubExpr());
3009}
3010
3011void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
3012 BlockDecl *BD = Node->getBlockDecl();
3013 OS << "^";
3014
3015 const FunctionType *AFT = Node->getFunctionType();
3016
3017 if (isa<FunctionNoProtoType>(AFT)) {
3018 OS << "()";
3019 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
3020 OS << '(';
3021 for (BlockDecl::param_iterator AI = BD->param_begin(),
3022 E = BD->param_end(); AI != E; ++AI) {
3023 if (AI != BD->param_begin()) OS << ", ";
3024 std::string ParamStr = (*AI)->getNameAsString();
3025 (*AI)->getType().print(OS, Policy, ParamStr);
3026 }
3027
3028 const auto *FT = cast<FunctionProtoType>(AFT);
3029 if (FT->isVariadic()) {
3030 if (!BD->param_empty()) OS << ", ";
3031 OS << "...";
3032 }
3033 OS << ')';
3034 }
3035 OS << "{ }";
3036}
3037
3038void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
3039 PrintExpr(Node->getSourceExpr());
3040}
3041
3042void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
3043 OS << "<recovery-expr>(";
3044 const char *Sep = "";
3045 for (Expr *E : Node->subExpressions()) {
3046 OS << Sep;
3047 PrintExpr(E);
3048 Sep = ", ";
3049 }
3050 OS << ')';
3051}
3052
3053void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
3054 OS << "__builtin_astype(";
3055 PrintExpr(Node->getSrcExpr());
3056 OS << ", ";
3057 Node->getType().print(OS, Policy);
3058 OS << ")";
3059}
3060
3061void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
3062 PrintExpr(Node->getArgLValue());
3063}
3064
3065//===----------------------------------------------------------------------===//
3066// Stmt method implementations
3067//===----------------------------------------------------------------------===//
3068
3069void Stmt::dumpPretty(const ASTContext &Context) const {
3070 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
3071}
3072
3073void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
3074 const PrintingPolicy &Policy, unsigned Indentation,
3075 StringRef NL, const ASTContext *Context) const {
3076 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
3077 P.Visit(const_cast<Stmt *>(this));
3078}
3079
3080void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
3081 const PrintingPolicy &Policy,
3082 unsigned Indentation, StringRef NL,
3083 const ASTContext *Context) const {
3084 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
3085 P.PrintControlledStmt(const_cast<Stmt *>(this));
3086}
3087
3088void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
3089 const PrintingPolicy &Policy, bool AddQuotes) const {
3090 std::string Buf;
3091 llvm::raw_string_ostream TempOut(Buf);
3092
3093 printPretty(TempOut, Helper, Policy);
3094
3095 Out << JsonFormat(TempOut.str(), AddQuotes);
3096}
3097
3098//===----------------------------------------------------------------------===//
3099// PrinterHelper
3100//===----------------------------------------------------------------------===//
3101
3102// 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.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
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:245
const LangOptions & getLangOpts() const
LabelDecl * getLabel() const
Definition Expr.h:4621
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition Expr.h:6042
Expr * getBase()
Get base of the array section.
Definition Expr.h:7351
Expr * getLength()
Get length of array section.
Definition Expr.h:7361
bool isOMPArraySection() const
Definition Expr.h:7347
Expr * getStride()
Get stride of array section.
Definition Expr.h:7365
SourceLocation getColonLocSecond() const
Definition Expr.h:7383
Expr * getLowerBound()
Get lower bound of array section.
Definition Expr.h:7355
SourceLocation getColonLocFirst() const
Definition Expr.h:7382
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2798
ArrayTypeTrait getTrait() const
Definition ExprCXX.h:3051
QualType getQueriedType() const
Definition ExprCXX.h:3055
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:6806
bool isVolatile() const
Definition Stmt.h:3325
unsigned getNumClobbers() const
Definition Stmt.h:3380
unsigned getNumOutputs() const
Definition Stmt.h:3348
unsigned getNumInputs() const
Definition Stmt.h:3370
Expr * getVal2() const
Definition Expr.h:7033
Expr * getOrder() const
Definition Expr.h:7016
bool isCmpXChg() const
Definition Expr.h:7066
AtomicOp getOp() const
Definition Expr.h:7045
Expr * getVal1() const
Definition Expr.h:7023
Expr * getPtr() const
Definition Expr.h:7013
Expr * getWeak() const
Definition Expr.h:7039
Expr * getOrderFail() const
Definition Expr.h:7029
bool hasVal1Operand() const
Definition Expr.h:7079
Stmt * getSubStmt()
Definition Stmt.h:2251
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2247
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
Definition Expr.h:4555
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
Definition Expr.h:4536
Expr * getLHS() const
Definition Expr.h:4136
StringRef getOpcodeStr() const
Definition Expr.h:4152
Expr * getRHS() const
Definition Expr.h:4138
Opcode getOpcode() const
Definition Expr.h:4131
param_iterator param_end()
Definition Decl.h:4913
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition Decl.h:4908
param_iterator param_begin()
Definition Decl.h:4912
bool param_empty() const
Definition Decl.h:4911
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Definition Expr.cpp:2571
const BlockDecl * getBlockDecl() const
Definition Expr.h:6738
This class is used for builtin types like 'int'.
Definition TypeBase.h:3245
Kind getKind() const
Definition TypeBase.h:3299
const CallExpr * getConfig() const
Definition ExprCXX.h:265
const Expr * getSubExpr() const
Definition ExprCXX.h:1520
bool getValue() const
Definition ExprCXX.h:745
Stmt * getHandlerBlock() const
Definition StmtCXX.h:52
VarDecl * getExceptionDecl() const
Definition StmtCXX.h:50
arg_iterator arg_begin()
Definition ExprCXX.h:1682
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1696
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition ExprCXX.h:1646
arg_iterator arg_end()
Definition ExprCXX.h:1683
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition ExprCXX.h:1635
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1693
bool isArrayForm() const
Definition ExprCXX.h:2657
bool isGlobalDelete() const
Definition ExprCXX.h:2656
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4023
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the member name.
Definition ExprCXX.h:4031
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4057
bool hasExplicitTemplateArgs() const
Determines whether this member expression actually had a C++ template argument list explicitly specif...
Definition ExprCXX.h:4097
Expr * getBase() const
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:4014
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition ExprCXX.h:4093
bool isImplicitAccess() const
True if this is an implicit access, i.e.
Definition ExprCXX.h:4006
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:4125
InitListExpr * getRangeExpr()
Definition ExprCXX.h:5632
DecompositionDecl * getDecompositionDecl()
Definition StmtCXX.cpp:212
const VarDecl * getRangeVar() const
Definition StmtCXX.h:830
Expr * getRHS() const
Definition ExprCXX.h:5112
Expr * getLHS() const
Definition ExprCXX.h:5111
BinaryOperatorKind getOperator() const
Definition ExprCXX.h:5131
VarDecl * getLoopVariable()
Definition StmtCXX.cpp:78
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:1879
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Definition ExprCXX.cpp:773
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition ExprCXX.cpp:754
const char * getCastName() const
getCastName - Get the name of the C++ cast being used, e.g., "static_cast", "dynamic_cast",...
Definition ExprCXX.cpp:800
bool isArray() const
Definition ExprCXX.h:2469
QualType getAllocatedType() const
Definition ExprCXX.h:2439
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:2474
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition ExprCXX.h:2532
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2508
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2499
bool isParenTypeId() const
Definition ExprCXX.h:2520
bool isGlobalNew() const
Definition ExprCXX.h:2526
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2538
Expr * getOperand() const
Definition ExprCXX.h:4380
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Definition ExprCXX.h:116
MutableArrayRef< Expr * > getUserSpecifiedInitExprs()
Definition ExprCXX.h:5241
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition ExprCXX.h:2814
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:392
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition ExprCXX.h:2808
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:2851
ReflectionKind getKind() const
Definition ExprCXX.h:5599
const TypeSourceInfo * getTypeSourceInfo() const
Definition ExprCXX.h:5601
DecomposedForm getDecomposedForm() const LLVM_READONLY
Decompose this operator into its syntactic form.
Definition ExprCXX.cpp:67
TypeSourceInfo * getTypeSourceInfo() const
Definition ExprCXX.h:2220
const Expr * getSubExpr() const
Definition ExprCXX.h:1233
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:889
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:896
Expr * getExprOperand() const
Definition ExprCXX.h:900
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:3853
QualType getTypeAsWritten() const
Retrieve the type that is being constructed, as specified in the source code.
Definition ExprCXX.h:3832
Expr * getExprOperand() const
Definition ExprCXX.h:1114
bool isTypeOperand() const
Definition ExprCXX.h:1103
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:1110
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3195
Expr * getCallee()
Definition Expr.h:3138
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3182
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:5782
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition Stmt.cpp:1493
Stmt * getSubStmt()
Definition Stmt.h:2045
Expr * getLHS()
Definition Stmt.h:2015
Expr * getRHS()
Definition Stmt.h:2027
Expr * getSubExpr()
Definition Expr.h:3774
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1030
unsigned getValue() const
Definition Expr.h:1653
CharacterLiteralKind getKind() const
Definition Expr.h:1646
Expr * getLHS() const
Definition Expr.h:4938
Expr * getRHS() const
Definition Expr.h:4940
Expr * getCond() const
Definition Expr.h:4936
const Expr * getInitializer() const
Definition Expr.h:3681
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1752
FPOptionsOverride getStoredFPFeatures() const
Get FPOptionsOverride from trailing storage.
Definition Stmt.h:1802
body_range body()
Definition Stmt.h:1815
bool hasStoredFPFeatures() const
Definition Stmt.h:1799
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
NamedDecl * getFoundDecl() const
ConceptDecl * getConceptDecl() const
SourceLocation getTemplateKWLoc() const
Expr * getLHS() const
Definition Expr.h:4473
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4462
Expr * getRHS() const
Definition Expr.h:4474
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4857
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:5378
bool hasExplicitTemplateArgs() const
Determines whether this declaration reference was followed by an explicit template argument list.
Definition Expr.h:1449
NestedNameSpecifier getQualifier() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name.
Definition Expr.h:1395
DeclarationNameInfo getNameInfo() const
Definition Expr.h:1366
ValueDecl * getDecl()
Definition Expr.h:1362
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:1475
bool hadMultipleCandidates() const
Returns true if this expression refers to a function that was resolved from an overloaded set having ...
Definition Expr.h:1481
bool hasTemplateKeyword() const
Determines whether the name in this declaration reference was preceded by the template keyword.
Definition Expr.h:1445
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition Stmt.h:1656
decl_range decls()
Definition Stmt.h:1691
const Decl * getSingleDecl() const
Definition Stmt.h:1658
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
bool isTemplateParameter() const
isTemplateParameter - Determines whether this declaration is a template parameter.
Definition DeclBase.h:2829
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:2093
Stmt * getBody()
Definition Stmt.h:3267
Expr * getOperand() const
Definition ExprCXX.h:5478
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3672
bool hasExplicitTemplateArgs() const
Determines whether this lookup had explicit template arguments.
Definition ExprCXX.h:3648
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3616
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3645
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3600
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3525
TemplateTemplateParmDecl * getParameter() const
Definition ExprCXX.h:3510
TemplateName getTemplateName() const
Definition ExprCXX.h:3508
Expr * getArrayRangeEnd(const Designator &D) const
Definition Expr.cpp:4944
Expr * getArrayRangeStart(const Designator &D) const
Definition Expr.cpp:4939
MutableArrayRef< Designator > designators()
Definition Expr.h:5838
Expr * getArrayIndex(const Designator &D) const
Definition Expr.cpp:4934
Expr * getInit() const
Retrieve the initializer value.
Definition Expr.h:5873
InitListExpr * getUpdater() const
Definition Expr.h:5990
Stmt * getBody()
Definition Stmt.h:2869
Expr * getCond()
Definition Stmt.h:2862
IdentifierInfo & getAccessor() const
Definition Expr.h:6639
const Expr * getBase() const
Definition Expr.h:6635
StringRef getFileName() const
Definition Expr.h:5201
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition Expr.h:3998
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:4003
This represents one expression.
Definition Expr.h:113
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3109
QualType getType() const
Definition Expr.h:145
Expr * getQueriedExpression() const
Definition ExprCXX.h:3123
ExpressionTrait getTrait() const
Definition ExprCXX.h:3119
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition Decl.cpp:4788
std::string getValueAsString(unsigned Radix) const
Definition Expr.cpp:1020
llvm::APFloat getValue() const
Definition Expr.h:1690
Stmt * getInit()
Definition Stmt.h:2915
Stmt * getBody()
Definition Stmt.h:2944
Expr * getInc()
Definition Stmt.h:2943
Expr * getCond()
Definition Stmt.h:2942
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Definition Stmt.h:2930
const Expr * getSubExpr() const
Definition Expr.h:1086
ValueDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition ExprCXX.h:4921
unsigned getNumLabels() const
Definition Stmt.h:3608
bool isAsmGoto() const
Definition Stmt.h:3604
const Expr * getOutputConstraintExpr(unsigned i) const
Definition Stmt.h:3560
StringRef getLabelName(unsigned i) const
Definition Stmt.cpp:605
StringRef getInputName(unsigned i) const
Definition Stmt.h:3577
StringRef getOutputName(unsigned i) const
Definition Stmt.h:3551
const Expr * getInputConstraintExpr(unsigned i) const
Definition Stmt.h:3586
const Expr * getAsmStringExpr() const
Definition Stmt.h:3485
Expr * getOutputExpr(unsigned i)
Definition Stmt.cpp:582
Expr * getClobberExpr(unsigned i)
Definition Stmt.h:3665
Expr * getInputExpr(unsigned i)
Definition Stmt.cpp:593
AssociationTy< false > Association
Definition Expr.h:6469
TypeSourceInfo * getControllingType()
Return the controlling type of this generic selection expression.
Definition Expr.h:6513
bool isExprPredicate() const
Whether this generic selection uses an expression as its controlling argument.
Definition Expr.h:6494
association_range associations()
Definition Expr.h:6569
Expr * getControllingExpr()
Return the controlling expression of this generic selection expression.
Definition Expr.h:6501
LabelDecl * getLabel() const
Definition Stmt.h:2994
const Expr * getArgLValue() const
Return the l-value expression that was written as the argument in source.
Definition Expr.h:7492
StringRef getName() const
Return the actual identifier string.
const Expr * getSubExpr() const
Definition Expr.h:1767
unsigned getNumInits() const
Definition Expr.h:5389
InitListExpr * getSyntacticForm() const
Definition Expr.h:5526
const Expr * getInit(unsigned Init) const
Definition Expr.h:5411
Stmt * getSubStmt()
Definition Stmt.h:2180
const char * getName() const
Definition Stmt.cpp:437
bool hasExplicitParameters() const
Determine whether this lambda has an explicit parameter list vs.
Definition ExprCXX.h:2176
bool isMutable() const
Determine whether the lambda is mutable, meaning that any captures values can be modified.
Definition ExprCXX.cpp:1460
bool isInitCapture(const LambdaCapture *Capture) const
Determine whether one of this lambda's captures is an init-capture.
Definition ExprCXX.cpp:1390
CXXMethodDecl * getCallOperator() const
Retrieve the function call operator associated with this lambda expression.
Definition ExprCXX.cpp:1436
const CompoundStmt * getCompoundStmtBody() const
Retrieve the CompoundStmt representing the body of the lambda.
Definition ExprCXX.cpp:1383
bool hasExplicitResultType() const
Whether this lambda had its result type explicitly specified.
Definition ExprCXX.h:2179
TemplateParameterList * getTemplateParameterList() const
If this is a generic lambda expression, retrieve the template parameter list associated with it,...
Definition ExprCXX.cpp:1446
ArrayRef< NamedDecl * > getExplicitTemplateParameters() const
Get the template parameters were explicitly specified (as opposed to being invented by use of an auto...
Definition ExprCXX.cpp:1451
capture_iterator explicit_capture_end() const
Retrieve an iterator pointing past the end of the sequence of explicit lambda captures.
Definition ExprCXX.cpp:1411
const LambdaCapture * capture_iterator
An iterator that walks over the captures of the lambda, both implicit and explicit.
Definition ExprCXX.h:2038
capture_iterator explicit_capture_begin() const
Retrieve an iterator pointing to the first explicit lambda capture.
Definition ExprCXX.cpp:1407
LambdaCaptureDefault getCaptureDefault() const
Determine the default capture kind for this lambda.
Definition ExprCXX.h:2026
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1432
llvm::omp::Version getOpenMPVersion() const
Return the OpenMP version.
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:3107
bool hasLabelTarget() const
Definition Stmt.h:3102
StringRef getAsmString() const
Definition Stmt.h:3711
bool hasBraces() const
Definition Stmt.h:3705
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:997
bool isArrow() const
Definition ExprCXX.h:995
MSPropertyDecl * getPropertyDecl() const
Definition ExprCXX.h:994
Expr * getBaseExpr() const
Definition ExprCXX.h:993
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4991
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:3584
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition Expr.h:3523
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3495
bool hasExplicitTemplateArgs() const
Determines whether the member name was followed by an explicit template argument list.
Definition Expr.h:3556
Expr * getBase() const
Definition Expr.h:3489
bool hadMultipleCandidates() const
Returns true if this member expression refers to a method that was resolved from an overloaded set ha...
Definition Expr.h:3616
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition Expr.h:3552
DeclarationNameInfo getMemberNameInfo() const
Retrieve the member declaration name info.
Definition Expr.h:3589
bool isArrow() const
Definition Expr.h:3596
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:302
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
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:1689
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:5611
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:5607
child_range children()
Definition ExprObjC.h:278
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:391
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Definition ExprObjC.h:393
QualType getEncodedType() const
Definition ExprObjC.h:459
Expr * getBase() const
Definition ExprObjC.h:1555
bool isArrow() const
Definition ExprObjC.h:1557
ObjCIvarDecl * getDecl()
Definition ExprObjC.h:611
bool isArrow() const
Definition ExprObjC.h:619
const Expr * getBase() const
Definition ExprObjC.h:615
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition ExprObjC.h:1435
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition ExprObjC.h:1300
Selector getSelector() const
Definition ExprObjC.cpp:301
@ SuperInstance
The receiver is the instance of the superclass object.
Definition ExprObjC.h:986
@ Instance
The receiver is an object instance.
Definition ExprObjC.h:980
@ SuperClass
The receiver is a superclass.
Definition ExprObjC.h:983
@ Class
The receiver is a class.
Definition ExprObjC.h:977
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Definition ExprObjC.h:1319
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition ExprObjC.h:1261
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition ExprObjC.h:1422
Selector getSelector() const
Definition DeclObjC.h:330
ObjCPropertyDecl * getExplicitProperty() const
Definition ExprObjC.h:738
ObjCMethodDecl * getImplicitPropertyGetter() const
Definition ExprObjC.h:743
const Expr * getBase() const
Definition ExprObjC.h:787
bool isObjectReceiver() const
Definition ExprObjC.h:802
bool isImplicitProperty() const
Definition ExprObjC.h:735
ObjCMethodDecl * getImplicitPropertySetter() const
Definition ExprObjC.h:748
ObjCInterfaceDecl * getClassReceiver() const
Definition ExprObjC.h:798
bool isClassReceiver() const
Definition ExprObjC.h:804
bool isSuperReceiver() const
Definition ExprObjC.h:803
ObjCProtocolDecl * getProtocol() const
Definition ExprObjC.h:554
Selector getSelector() const
Definition ExprObjC.h:499
StringLiteral * getString()
Definition ExprObjC.h:95
Expr * getKeyExpr() const
Definition ExprObjC.h:913
Expr * getBaseExpr() const
Definition ExprObjC.h:910
Expr * getIndexExpr(unsigned Idx)
Definition Expr.h:2634
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2622
TypeSourceInfo * getTypeSourceInfo() const
Definition Expr.h:2615
unsigned getNumComponents() const
Definition Expr.h:2630
const IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1725
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2527
@ Array
An index into an array.
Definition Expr.h:2474
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition Expr.h:2481
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2523
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1252
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:3295
NestedNameSpecifier getQualifier() const
Fetches the nested-name qualifier, if one was given.
Definition ExprCXX.h:3259
const DeclarationNameInfo & getNameInfo() const
Gets the full name info.
Definition ExprCXX.h:3250
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3292
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3320
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition ExprCXX.h:4446
Expr * getIndexExpr() const
Definition ExprCXX.h:4682
Expr * getPackIdExpression() const
Definition ExprCXX.h:4678
const Expr * getSubExpr() const
Definition Expr.h:2247
Expr * getExpr(unsigned Init)
Definition Expr.h:6166
unsigned getNumExprs() const
Return the number of expressions in this paren list.
Definition Expr.h:6164
StringRef getIdentKindName() const
Definition Expr.h:2110
PredefinedIdentKind getIdentKind() const
Definition Expr.h:2088
virtual ~PrinterHelper()
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition Expr.h:6895
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
ArrayRef< Expr * > subExpressions()
Definition Expr.h:7564
ArrayRef< concepts::Requirement * > getRequirements() const
ArrayRef< ParmVarDecl * > getLocalParameters() const
Expr * getRetValue()
Definition Stmt.h:3199
CompoundStmt * getBlock() const
Definition Stmt.h:3805
Expr * getFilterExpr() const
Definition Stmt.h:3801
CompoundStmt * getBlock() const
Definition Stmt.h:3842
CompoundStmt * getTryBlock() const
Definition Stmt.h:3886
bool getIsCXXTry() const
Definition Stmt.h:3884
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:2191
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:4724
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4730
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition ExprCXX.h:4563
StringRef getBuiltinStr() const
Return a string representing the name of the specific builtin function.
Definition Expr.cpp:2299
bool isValid() const
Return true if this is a valid SourceLocation object.
CompoundStmt * getSubStmt()
Definition Expr.h:4660
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:1487
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
Prints the contents of the string to OS.
Definition Expr.cpp:1219
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Definition ExprCXX.cpp:1810
Expr * getCond()
Definition Stmt.h:2584
Stmt * getBody()
Definition Stmt.h:2596
Stmt * getInit()
Definition Stmt.h:2601
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition Stmt.h:2635
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 &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
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:8428
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition ExprCXX.h:2976
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition ExprCXX.h:2973
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition ExprCXX.h:2950
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2392
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:9366
bool isEnumeralType() const
Definition TypeBase.h:8814
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
Definition Type.cpp:2235
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
bool isRecordType() const
Definition TypeBase.h:8810
QualType getArgumentType() const
Definition Expr.h:2716
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2705
static bool isPostfix(Opcode Op)
isPostfix - Return true if this is a postfix operation, like x++.
Definition Expr.h:2362
Expr * getSubExpr() const
Definition Expr.h:2333
Opcode getOpcode() const
Definition Expr.h:2328
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition Expr.cpp:1438
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4272
Expr * getBase()
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:4253
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:1675
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the full name info for the member that this expression refers to.
Definition ExprCXX.h:4285
LiteralOperatorKind getLiteralOperatorKind() const
Returns the kind of literal operator invocation which this expression represents.
Definition ExprCXX.cpp:1031
const IdentifierInfo * getUDSuffix() const
Returns the ud-suffix specified for this literal.
Definition ExprCXX.cpp:1060
Expr * getCookedLiteral()
If this is not a raw user-defined literal, get the underlying cooked literal (representing the litera...
Definition ExprCXX.cpp:1052
@ LOK_String
operator "" X (const CharT *, size_t)
Definition ExprCXX.h:687
@ LOK_Raw
Raw form: operator "" X (const char *)
Definition ExprCXX.h:675
@ LOK_Floating
operator "" X (long double)
Definition ExprCXX.h:684
@ LOK_Integer
operator "" X (unsigned long long)
Definition ExprCXX.h:681
@ LOK_Template
Raw form: operator "" X<cs...> ()
Definition ExprCXX.h:678
@ LOK_Character
operator "" X (CharT)
Definition ExprCXX.h:690
const Expr * getSubExpr() const
Definition Expr.h:5025
QualType getType() const
Definition Decl.h:724
@ CInit
C-style initialization with assignment.
Definition Decl.h:938
@ CallInit
Call-style initialization (C++98)
Definition Decl.h:941
const Expr * getInit() const
Definition Decl.h:1392
Expr * getCond()
Definition Stmt.h:2761
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
Definition Stmt.h:2797
Stmt * getBody()
Definition Stmt.h:2773
@ 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:1757
CXXNewInitializationStyle
Definition ExprCXX.h:2245
ArrayRef< TemplateArgumentLoc > arguments() const
const Expr * RHS
The original right-hand side.
Definition ExprCXX.h:318
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition ExprCXX.h:314
const Expr * LHS
The original left-hand side.
Definition ExprCXX.h:316
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:299
bool isPackExpansion() const
Determines whether this dictionary element is a pack expansion.
Definition ExprObjC.h:309
Expr * Key
The key for the dictionary element.
Definition ExprObjC.h:296
Describes how types, statements, expressions, and declarations should be printed.
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 IncludeNewlines
When true, include newlines after statements like "break", etc.
unsigned TerseOutput
Provide a 'terse' output.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
unsigned UnderscoreAlignof
Whether we can use '_Alignof' rather than '__alignof'.