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): Implement this.
2680 assert(false && "not implemented yet");
2681}
2682
2683void StmtPrinter::VisitDependentTemplateIdExpr(DependentTemplateIdExpr *Node) {
2684 Node->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
2685 printTemplateArgumentList(OS, Node->template_arguments(), Policy,
2687}
2688
2689void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2690 CXXDependentScopeMemberExpr *Node) {
2691 if (!Node->isImplicitAccess()) {
2692 PrintExpr(Node->getBase());
2693 OS << (Node->isArrow() ? "->" : ".");
2694 }
2695 Node->getQualifier().print(OS, Policy);
2696 if (Node->hasTemplateKeyword())
2697 OS << "template ";
2698 OS << Node->getMemberNameInfo();
2699 if (Node->hasExplicitTemplateArgs())
2700 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2701}
2702
2703void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2704 if (!Node->isImplicitAccess()) {
2705 PrintExpr(Node->getBase());
2706 OS << (Node->isArrow() ? "->" : ".");
2707 }
2708 Node->getQualifier().print(OS, Policy);
2709 if (Node->hasTemplateKeyword())
2710 OS << "template ";
2711 OS << Node->getMemberNameInfo();
2712 if (Node->hasExplicitTemplateArgs())
2713 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2714}
2715
2716void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2717 OS << getTraitSpelling(E->getTrait()) << "(";
2718 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2719 if (I > 0)
2720 OS << ", ";
2721 E->getArg(I)->getType().print(OS, Policy);
2722 }
2723 OS << ")";
2724}
2725
2726void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2727 OS << getTraitSpelling(E->getTrait()) << '(';
2728 E->getQueriedType().print(OS, Policy);
2729 OS << ')';
2730}
2731
2732void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2733 OS << getTraitSpelling(E->getTrait()) << '(';
2734 PrintExpr(E->getQueriedExpression());
2735 OS << ')';
2736}
2737
2738void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2739 OS << "noexcept(";
2740 PrintExpr(E->getOperand());
2741 OS << ")";
2742}
2743
2744void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2745 PrintExpr(E->getPattern());
2746 OS << "...";
2747}
2748
2749void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2750 OS << "sizeof...(" << *E->getPack() << ")";
2751}
2752
2753void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2754 PrintExpr(E->getPackIdExpression());
2755 OS << "...[";
2756 PrintExpr(E->getIndexExpr());
2757 OS << "]";
2758}
2759
2760void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2761 SubstNonTypeTemplateParmPackExpr *Node) {
2762 OS << *Node->getParameterPack();
2763}
2764
2765void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2766 SubstNonTypeTemplateParmExpr *Node) {
2767 Visit(Node->getReplacement());
2768}
2769
2770void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2771 OS << *E->getParameterPack();
2772}
2773
2774void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2775 PrintExpr(Node->getSubExpr());
2776}
2777
2778void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2779 OS << "(";
2780 if (E->getLHS()) {
2781 PrintExpr(E->getLHS());
2782 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2783 }
2784 OS << "...";
2785 if (E->getRHS()) {
2786 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2787 PrintExpr(E->getRHS());
2788 }
2789 OS << ")";
2790}
2791
2792void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2793 llvm::interleaveComma(Node->getUserSpecifiedInitExprs(), OS,
2794 [&](Expr *E) { PrintExpr(E); });
2795}
2796
2797void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2798 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2799 NNS.getNestedNameSpecifier().print(OS, Policy);
2800 if (E->getTemplateKWLoc().isValid())
2801 OS << "template ";
2802 OS << E->getFoundDecl()->getName();
2803 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2804 Policy,
2806}
2807
2808void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2809 OS << "requires ";
2810 auto LocalParameters = E->getLocalParameters();
2811 if (!LocalParameters.empty()) {
2812 OS << "(";
2813 for (ParmVarDecl *LocalParam : LocalParameters) {
2814 PrintRawDecl(LocalParam);
2815 if (LocalParam != LocalParameters.back())
2816 OS << ", ";
2817 }
2818
2819 OS << ") ";
2820 }
2821 OS << "{ ";
2822 auto Requirements = E->getRequirements();
2823 for (concepts::Requirement *Req : Requirements) {
2824 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2825 if (TypeReq->isSubstitutionFailure())
2826 OS << "<<error-type>>";
2827 else
2828 TypeReq->getType()->getType().print(OS, Policy);
2829 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2830 if (ExprReq->isCompound())
2831 OS << "{ ";
2832 if (ExprReq->isExprSubstitutionFailure())
2833 OS << "<<error-expression>>";
2834 else
2835 PrintExpr(ExprReq->getExpr());
2836 if (ExprReq->isCompound()) {
2837 OS << " }";
2838 if (ExprReq->getNoexceptLoc().isValid())
2839 OS << " noexcept";
2840 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2841 if (!RetReq.isEmpty()) {
2842 OS << " -> ";
2843 if (RetReq.isSubstitutionFailure())
2844 OS << "<<error-type>>";
2845 else if (RetReq.isTypeConstraint())
2846 RetReq.getTypeConstraint()->print(OS, Policy);
2847 }
2848 }
2849 } else {
2850 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2851 OS << "requires ";
2852 if (NestedReq->hasInvalidConstraint())
2853 OS << "<<error-expression>>";
2854 else
2855 PrintExpr(NestedReq->getConstraintExpr());
2856 }
2857 OS << "; ";
2858 }
2859 OS << "}";
2860}
2861
2862// C++ Coroutines
2863
2864void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2865 Visit(S->getBody());
2866}
2867
2868void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2869 OS << "co_return";
2870 if (S->getOperand()) {
2871 OS << " ";
2872 Visit(S->getOperand());
2873 }
2874 OS << ";";
2875}
2876
2877void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2878 OS << "co_await ";
2879 PrintExpr(S->getOperand());
2880}
2881
2882void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2883 OS << "co_await ";
2884 PrintExpr(S->getOperand());
2885}
2886
2887void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2888 OS << "co_yield ";
2889 PrintExpr(S->getOperand());
2890}
2891
2892// Obj-C
2893
2894void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2895 OS << "@";
2896 VisitStringLiteral(Node->getString());
2897}
2898
2899void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2900 OS << "@";
2901 Visit(E->getSubExpr());
2902}
2903
2904void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2905 OS << "@[ ";
2906 ObjCArrayLiteral::child_range Ch = E->children();
2907 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2908 if (I != Ch.begin())
2909 OS << ", ";
2910 Visit(*I);
2911 }
2912 OS << " ]";
2913}
2914
2915void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2916 OS << "@{ ";
2917 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2918 if (I > 0)
2919 OS << ", ";
2920
2921 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2922 Visit(Element.Key);
2923 OS << " : ";
2924 Visit(Element.Value);
2925 if (Element.isPackExpansion())
2926 OS << "...";
2927 }
2928 OS << " }";
2929}
2930
2931void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2932 OS << "@encode(";
2933 Node->getEncodedType().print(OS, Policy);
2934 OS << ')';
2935}
2936
2937void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2938 OS << "@selector(";
2939 Node->getSelector().print(OS);
2940 OS << ')';
2941}
2942
2943void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2944 OS << "@protocol(" << *Node->getProtocol() << ')';
2945}
2946
2947void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2948 OS << "[";
2949 switch (Mess->getReceiverKind()) {
2951 PrintExpr(Mess->getInstanceReceiver());
2952 break;
2953
2955 Mess->getClassReceiver().print(OS, Policy);
2956 break;
2957
2960 OS << "Super";
2961 break;
2962 }
2963
2964 OS << ' ';
2965 Selector selector = Mess->getSelector();
2966 if (selector.isUnarySelector()) {
2967 OS << selector.getNameForSlot(0);
2968 } else {
2969 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2970 if (i < selector.getNumArgs()) {
2971 if (i > 0) OS << ' ';
2972 if (selector.getIdentifierInfoForSlot(i))
2973 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2974 else
2975 OS << ":";
2976 }
2977 else OS << ", "; // Handle variadic methods.
2978
2979 PrintExpr(Mess->getArg(i));
2980 }
2981 }
2982 OS << "]";
2983}
2984
2985void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2986 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2987}
2988
2989void
2990StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2991 PrintExpr(E->getSubExpr());
2992}
2993
2994void
2995StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2996 OS << '(' << E->getBridgeKindName();
2997 E->getType().print(OS, Policy);
2998 OS << ')';
2999 PrintExpr(E->getSubExpr());
3000}
3001
3002void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
3003 BlockDecl *BD = Node->getBlockDecl();
3004 OS << "^";
3005
3006 const FunctionType *AFT = Node->getFunctionType();
3007
3008 if (isa<FunctionNoProtoType>(AFT)) {
3009 OS << "()";
3010 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
3011 OS << '(';
3012 for (BlockDecl::param_iterator AI = BD->param_begin(),
3013 E = BD->param_end(); AI != E; ++AI) {
3014 if (AI != BD->param_begin()) OS << ", ";
3015 std::string ParamStr = (*AI)->getNameAsString();
3016 (*AI)->getType().print(OS, Policy, ParamStr);
3017 }
3018
3019 const auto *FT = cast<FunctionProtoType>(AFT);
3020 if (FT->isVariadic()) {
3021 if (!BD->param_empty()) OS << ", ";
3022 OS << "...";
3023 }
3024 OS << ')';
3025 }
3026 OS << "{ }";
3027}
3028
3029void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
3030 PrintExpr(Node->getSourceExpr());
3031}
3032
3033void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
3034 OS << "<recovery-expr>(";
3035 const char *Sep = "";
3036 for (Expr *E : Node->subExpressions()) {
3037 OS << Sep;
3038 PrintExpr(E);
3039 Sep = ", ";
3040 }
3041 OS << ')';
3042}
3043
3044void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
3045 OS << "__builtin_astype(";
3046 PrintExpr(Node->getSrcExpr());
3047 OS << ", ";
3048 Node->getType().print(OS, Policy);
3049 OS << ")";
3050}
3051
3052void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
3053 PrintExpr(Node->getArgLValue());
3054}
3055
3056//===----------------------------------------------------------------------===//
3057// Stmt method implementations
3058//===----------------------------------------------------------------------===//
3059
3060void Stmt::dumpPretty(const ASTContext &Context) const {
3061 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
3062}
3063
3064void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
3065 const PrintingPolicy &Policy, unsigned Indentation,
3066 StringRef NL, const ASTContext *Context) const {
3067 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
3068 P.Visit(const_cast<Stmt *>(this));
3069}
3070
3071void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
3072 const PrintingPolicy &Policy,
3073 unsigned Indentation, StringRef NL,
3074 const ASTContext *Context) const {
3075 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
3076 P.PrintControlledStmt(const_cast<Stmt *>(this));
3077}
3078
3079void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
3080 const PrintingPolicy &Policy, bool AddQuotes) const {
3081 std::string Buf;
3082 llvm::raw_string_ostream TempOut(Buf);
3083
3084 printPretty(TempOut, Helper, Policy);
3085
3086 Out << JsonFormat(TempOut.str(), AddQuotes);
3087}
3088
3089//===----------------------------------------------------------------------===//
3090// PrinterHelper
3091//===----------------------------------------------------------------------===//
3092
3093// 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:239
const LangOptions & getLangOpts() const
LabelDecl * getLabel() const
Definition Expr.h:4617
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition Expr.h:6038
Expr * getBase()
Get base of the array section.
Definition Expr.h:7347
Expr * getLength()
Get length of array section.
Definition Expr.h:7357
bool isOMPArraySection() const
Definition Expr.h:7343
Expr * getStride()
Get stride of array section.
Definition Expr.h:7361
SourceLocation getColonLocSecond() const
Definition Expr.h:7379
Expr * getLowerBound()
Get lower bound of array section.
Definition Expr.h:7351
SourceLocation getColonLocFirst() const
Definition Expr.h:7378
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2794
ArrayTypeTrait getTrait() const
Definition ExprCXX.h:3050
QualType getQueriedType() const
Definition ExprCXX.h:3054
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:6802
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:7029
Expr * getOrder() const
Definition Expr.h:7012
bool isCmpXChg() const
Definition Expr.h:7062
AtomicOp getOp() const
Definition Expr.h:7041
Expr * getVal1() const
Definition Expr.h:7019
Expr * getPtr() const
Definition Expr.h:7009
Expr * getWeak() const
Definition Expr.h:7035
Expr * getOrderFail() const
Definition Expr.h:7025
bool hasVal1Operand() const
Definition Expr.h:7075
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:4551
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
Definition Expr.h:4532
Expr * getLHS() const
Definition Expr.h:4132
StringRef getOpcodeStr() const
Definition Expr.h:4148
Expr * getRHS() const
Definition Expr.h:4134
Opcode getOpcode() const
Definition Expr.h:4127
param_iterator param_end()
Definition Decl.h:4909
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition Decl.h:4904
param_iterator param_begin()
Definition Decl.h:4908
bool param_empty() const
Definition Decl.h:4907
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Definition Expr.cpp:2565
const BlockDecl * getBlockDecl() const
Definition Expr.h:6734
This class is used for builtin types like 'int'.
Definition TypeBase.h:3241
Kind getKind() const
Definition TypeBase.h:3292
const CallExpr * getConfig() const
Definition ExprCXX.h:264
const Expr * getSubExpr() const
Definition ExprCXX.h:1519
bool getValue() const
Definition ExprCXX.h:744
Stmt * getHandlerBlock() const
Definition StmtCXX.h:52
VarDecl * getExceptionDecl() const
Definition StmtCXX.h:50
arg_iterator arg_begin()
Definition ExprCXX.h:1681
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition ExprCXX.h:1645
arg_iterator arg_end()
Definition ExprCXX.h:1682
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition ExprCXX.h:1634
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1692
bool isArrayForm() const
Definition ExprCXX.h:2656
bool isGlobalDelete() const
Definition ExprCXX.h:2655
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4022
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the member name.
Definition ExprCXX.h:4030
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4056
bool hasExplicitTemplateArgs() const
Determines whether this member expression actually had a C++ template argument list explicitly specif...
Definition ExprCXX.h:4096
Expr * getBase() const
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:4013
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition ExprCXX.h:4092
bool isImplicitAccess() const
True if this is an implicit access, i.e.
Definition ExprCXX.h:4005
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:4124
InitListExpr * getRangeExpr()
Definition ExprCXX.h:5621
DecompositionDecl * getDecompositionDecl()
Definition StmtCXX.cpp:212
const VarDecl * getRangeVar() const
Definition StmtCXX.h:830
Expr * getRHS() const
Definition ExprCXX.h:5111
Expr * getLHS() const
Definition ExprCXX.h:5110
BinaryOperatorKind getOperator() const
Definition ExprCXX.h:5130
VarDecl * getLoopVariable()
Definition StmtCXX.cpp:78
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:1878
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Definition ExprCXX.cpp:774
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition ExprCXX.cpp:755
const char * getCastName() const
getCastName - Get the name of the C++ cast being used, e.g., "static_cast", "dynamic_cast",...
Definition ExprCXX.cpp:801
bool isArray() const
Definition ExprCXX.h:2468
QualType getAllocatedType() const
Definition ExprCXX.h:2438
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:2473
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition ExprCXX.h:2531
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2507
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2498
bool isParenTypeId() const
Definition ExprCXX.h:2519
bool isGlobalNew() const
Definition ExprCXX.h:2525
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
Expr * getOperand() const
Definition ExprCXX.h:4379
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Definition ExprCXX.h:115
MutableArrayRef< Expr * > getUserSpecifiedInitExprs()
Definition ExprCXX.h:5240
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition ExprCXX.h:2813
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:391
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition ExprCXX.h:2807
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:2850
DecomposedForm getDecomposedForm() const LLVM_READONLY
Decompose this operator into its syntactic form.
Definition ExprCXX.cpp:66
TypeSourceInfo * getTypeSourceInfo() const
Definition ExprCXX.h:2219
const Expr * getSubExpr() const
Definition ExprCXX.h:1232
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:888
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:895
Expr * getExprOperand() const
Definition ExprCXX.h:899
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:3852
QualType getTypeAsWritten() const
Retrieve the type that is being constructed, as specified in the source code.
Definition ExprCXX.h:3831
Expr * getExprOperand() const
Definition ExprCXX.h:1113
bool isTypeOperand() const
Definition ExprCXX.h:1102
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:1109
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3191
Expr * getCallee()
Definition Expr.h:3134
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3178
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:5768
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:3770
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1026
unsigned getValue() const
Definition Expr.h:1649
CharacterLiteralKind getKind() const
Definition Expr.h:1642
Expr * getLHS() const
Definition Expr.h:4934
Expr * getRHS() const
Definition Expr.h:4936
Expr * getCond() const
Definition Expr.h:4932
const Expr * getInitializer() const
Definition Expr.h:3677
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:4469
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4458
Expr * getRHS() const
Definition Expr.h:4470
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4853
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:5377
bool hasExplicitTemplateArgs() const
Determines whether this declaration reference was followed by an explicit template argument list.
Definition Expr.h:1445
NestedNameSpecifier getQualifier() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name.
Definition Expr.h:1391
DeclarationNameInfo getNameInfo() const
Definition Expr.h:1362
ValueDecl * getDecl()
Definition Expr.h:1358
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:1471
bool hadMultipleCandidates() const
Returns true if this expression refers to a function that was resolved from an overloaded set having ...
Definition Expr.h:1477
bool hasTemplateKeyword() const
Determines whether the name in this declaration reference was preceded by the template keyword.
Definition Expr.h:1441
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:2843
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:5477
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3671
bool hasExplicitTemplateArgs() const
Determines whether this lookup had explicit template arguments.
Definition ExprCXX.h:3647
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3615
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3644
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3599
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3524
TemplateTemplateParmDecl * getParameter() const
Definition ExprCXX.h:3509
TemplateName getTemplateName() const
Definition ExprCXX.h:3507
Expr * getArrayRangeEnd(const Designator &D) const
Definition Expr.cpp:4938
Expr * getArrayRangeStart(const Designator &D) const
Definition Expr.cpp:4933
MutableArrayRef< Designator > designators()
Definition Expr.h:5834
Expr * getArrayIndex(const Designator &D) const
Definition Expr.cpp:4928
Expr * getInit() const
Retrieve the initializer value.
Definition Expr.h:5869
InitListExpr * getUpdater() const
Definition Expr.h:5986
Stmt * getBody()
Definition Stmt.h:2869
Expr * getCond()
Definition Stmt.h:2862
IdentifierInfo & getAccessor() const
Definition Expr.h:6635
const Expr * getBase() const
Definition Expr.h:6631
StringRef getFileName() const
Definition Expr.h:5197
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition Expr.h:3994
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:3999
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:3103
QualType getType() const
Definition Expr.h:145
Expr * getQueriedExpression() const
Definition ExprCXX.h:3122
ExpressionTrait getTrait() const
Definition ExprCXX.h:3118
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition Decl.cpp:4780
std::string getValueAsString(unsigned Radix) const
Definition Expr.cpp:1016
llvm::APFloat getValue() const
Definition Expr.h:1686
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:1082
ValueDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition ExprCXX.h:4920
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:6465
TypeSourceInfo * getControllingType()
Return the controlling type of this generic selection expression.
Definition Expr.h:6509
bool isExprPredicate() const
Whether this generic selection uses an expression as its controlling argument.
Definition Expr.h:6490
association_range associations()
Definition Expr.h:6565
Expr * getControllingExpr()
Return the controlling expression of this generic selection expression.
Definition Expr.h:6497
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:7488
StringRef getName() const
Return the actual identifier string.
const Expr * getSubExpr() const
Definition Expr.h:1763
unsigned getNumInits() const
Definition Expr.h:5385
InitListExpr * getSyntacticForm() const
Definition Expr.h:5522
const Expr * getInit(unsigned Init) const
Definition Expr.h:5407
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:2175
bool isMutable() const
Determine whether the lambda is mutable, meaning that any captures values can be modified.
Definition ExprCXX.cpp:1461
bool isInitCapture(const LambdaCapture *Capture) const
Determine whether one of this lambda's captures is an init-capture.
Definition ExprCXX.cpp:1391
CXXMethodDecl * getCallOperator() const
Retrieve the function call operator associated with this lambda expression.
Definition ExprCXX.cpp:1437
const CompoundStmt * getCompoundStmtBody() const
Retrieve the CompoundStmt representing the body of the lambda.
Definition ExprCXX.cpp:1384
bool hasExplicitResultType() const
Whether this lambda had its result type explicitly specified.
Definition ExprCXX.h:2178
TemplateParameterList * getTemplateParameterList() const
If this is a generic lambda expression, retrieve the template parameter list associated with it,...
Definition ExprCXX.cpp:1447
ArrayRef< NamedDecl * > getExplicitTemplateParameters() const
Get the template parameters were explicitly specified (as opposed to being invented by use of an auto...
Definition ExprCXX.cpp:1452
capture_iterator explicit_capture_end() const
Retrieve an iterator pointing past the end of the sequence of explicit lambda captures.
Definition ExprCXX.cpp:1412
const LambdaCapture * capture_iterator
An iterator that walks over the captures of the lambda, both implicit and explicit.
Definition ExprCXX.h:2037
capture_iterator explicit_capture_begin() const
Retrieve an iterator pointing to the first explicit lambda capture.
Definition ExprCXX.cpp:1408
LambdaCaptureDefault getCaptureDefault() const
Determine the default capture kind for this lambda.
Definition ExprCXX.h:2025
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1433
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:996
bool isArrow() const
Definition ExprCXX.h:994
MSPropertyDecl * getPropertyDecl() const
Definition ExprCXX.h:993
Expr * getBaseExpr() const
Definition ExprCXX.h:992
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4990
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:3580
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition Expr.h:3519
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3491
bool hasExplicitTemplateArgs() const
Determines whether the member name was followed by an explicit template argument list.
Definition Expr.h:3552
Expr * getBase() const
Definition Expr.h:3485
bool hadMultipleCandidates() const
Returns true if this member expression refers to a method that was resolved from an overloaded set ha...
Definition Expr.h:3612
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition Expr.h:3548
DeclarationNameInfo getMemberNameInfo() const
Retrieve the member declaration name info.
Definition Expr.h:3585
bool isArrow() const
Definition Expr.h:3592
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:5605
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:5601
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:2630
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2618
TypeSourceInfo * getTypeSourceInfo() const
Definition Expr.h:2611
unsigned getNumComponents() const
Definition Expr.h:2626
const IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1718
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2523
@ Array
An index into an array.
Definition Expr.h:2470
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition Expr.h:2477
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2519
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1248
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:3294
NestedNameSpecifier getQualifier() const
Fetches the nested-name qualifier, if one was given.
Definition ExprCXX.h:3258
const DeclarationNameInfo & getNameInfo() const
Gets the full name info.
Definition ExprCXX.h:3249
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3291
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3319
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition ExprCXX.h:4445
Expr * getIndexExpr() const
Definition ExprCXX.h:4681
Expr * getPackIdExpression() const
Definition ExprCXX.h:4677
const Expr * getSubExpr() const
Definition Expr.h:2243
Expr * getExpr(unsigned Init)
Definition Expr.h:6162
unsigned getNumExprs() const
Return the number of expressions in this paren list.
Definition Expr.h:6160
StringRef getIdentKindName() const
Definition Expr.h:2106
PredefinedIdentKind getIdentKind() const
Definition Expr.h:2084
virtual ~PrinterHelper()
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition Expr.h:6891
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
ArrayRef< Expr * > subExpressions()
Definition Expr.h:7560
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:2187
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:4720
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4726
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition ExprCXX.h:4562
StringRef getBuiltinStr() const
Return a string representing the name of the specific builtin function.
Definition Expr.cpp:2293
bool isValid() const
Return true if this is a valid SourceLocation object.
CompoundStmt * getSubStmt()
Definition Expr.h:4656
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:1215
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Definition ExprCXX.cpp:1812
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:8410
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition ExprCXX.h:2975
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition ExprCXX.h:2972
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition ExprCXX.h:2949
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2388
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:9331
bool isEnumeralType() const
Definition TypeBase.h:8796
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
Definition Type.cpp:2231
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
bool isRecordType() const
Definition TypeBase.h:8792
QualType getArgumentType() const
Definition Expr.h:2712
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2701
static bool isPostfix(Opcode Op)
isPostfix - Return true if this is a postfix operation, like x++.
Definition Expr.h:2358
Expr * getSubExpr() const
Definition Expr.h:2329
Opcode getOpcode() const
Definition Expr.h:2324
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition Expr.cpp:1434
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4271
Expr * getBase()
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:4252
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:1677
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the full name info for the member that this expression refers to.
Definition ExprCXX.h:4284
LiteralOperatorKind getLiteralOperatorKind() const
Returns the kind of literal operator invocation which this expression represents.
Definition ExprCXX.cpp:1032
const IdentifierInfo * getUDSuffix() const
Returns the ud-suffix specified for this literal.
Definition ExprCXX.cpp:1061
Expr * getCookedLiteral()
If this is not a raw user-defined literal, get the underlying cooked literal (representing the litera...
Definition ExprCXX.cpp:1053
@ LOK_String
operator "" X (const CharT *, size_t)
Definition ExprCXX.h:686
@ LOK_Raw
Raw form: operator "" X (const char *)
Definition ExprCXX.h:674
@ LOK_Floating
operator "" X (long double)
Definition ExprCXX.h:683
@ LOK_Integer
operator "" X (unsigned long long)
Definition ExprCXX.h:680
@ LOK_Template
Raw form: operator "" X<cs...> ()
Definition ExprCXX.h:677
@ LOK_Character
operator "" X (CharT)
Definition ExprCXX.h:689
const Expr * getSubExpr() const
Definition Expr.h:5021
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:2244
ArrayRef< TemplateArgumentLoc > arguments() const
const Expr * RHS
The original right-hand side.
Definition ExprCXX.h:317
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition ExprCXX.h:313
const Expr * LHS
The original left-hand side.
Definition ExprCXX.h:315
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'.