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