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