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