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