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::VisitOMPSplitDirective(OMPSplitDirective *Node) {
804 Indent() << "#pragma omp split";
805 PrintOMPExecutableDirective(Node);
806}
807
808void StmtPrinter::VisitOMPFuseDirective(OMPFuseDirective *Node) {
809 Indent() << "#pragma omp fuse";
810 PrintOMPExecutableDirective(Node);
811}
812
813void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
814 Indent() << "#pragma omp for";
815 PrintOMPExecutableDirective(Node);
816}
817
818void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
819 Indent() << "#pragma omp for simd";
820 PrintOMPExecutableDirective(Node);
821}
822
823void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
824 Indent() << "#pragma omp sections";
825 PrintOMPExecutableDirective(Node);
826}
827
828void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
829 Indent() << "#pragma omp section";
830 PrintOMPExecutableDirective(Node);
831}
832
833void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {
834 Indent() << "#pragma omp scope";
835 PrintOMPExecutableDirective(Node);
836}
837
838void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
839 Indent() << "#pragma omp single";
840 PrintOMPExecutableDirective(Node);
841}
842
843void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
844 Indent() << "#pragma omp master";
845 PrintOMPExecutableDirective(Node);
846}
847
848void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
849 Indent() << "#pragma omp critical";
850 if (Node->getDirectiveName().getName()) {
851 OS << " (";
852 Node->getDirectiveName().printName(OS, Policy);
853 OS << ")";
854 }
855 PrintOMPExecutableDirective(Node);
856}
857
858void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
859 Indent() << "#pragma omp parallel for";
860 PrintOMPExecutableDirective(Node);
861}
862
863void StmtPrinter::VisitOMPParallelForSimdDirective(
864 OMPParallelForSimdDirective *Node) {
865 Indent() << "#pragma omp parallel for simd";
866 PrintOMPExecutableDirective(Node);
867}
868
869void StmtPrinter::VisitOMPParallelMasterDirective(
870 OMPParallelMasterDirective *Node) {
871 Indent() << "#pragma omp parallel master";
872 PrintOMPExecutableDirective(Node);
873}
874
875void StmtPrinter::VisitOMPParallelMaskedDirective(
876 OMPParallelMaskedDirective *Node) {
877 Indent() << "#pragma omp parallel masked";
878 PrintOMPExecutableDirective(Node);
879}
880
881void StmtPrinter::VisitOMPParallelSectionsDirective(
882 OMPParallelSectionsDirective *Node) {
883 Indent() << "#pragma omp parallel sections";
884 PrintOMPExecutableDirective(Node);
885}
886
887void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
888 Indent() << "#pragma omp task";
889 PrintOMPExecutableDirective(Node);
890}
891
892void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
893 Indent() << "#pragma omp taskyield";
894 PrintOMPExecutableDirective(Node);
895}
896
897void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
898 Indent() << "#pragma omp barrier";
899 PrintOMPExecutableDirective(Node);
900}
901
902void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
903 Indent() << "#pragma omp taskwait";
904 PrintOMPExecutableDirective(Node);
905}
906
907void StmtPrinter::VisitOMPAssumeDirective(OMPAssumeDirective *Node) {
908 Indent() << "#pragma omp assume";
909 PrintOMPExecutableDirective(Node);
910}
911
912void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
913 Indent() << "#pragma omp error";
914 PrintOMPExecutableDirective(Node);
915}
916
917void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
918 Indent() << "#pragma omp taskgroup";
919 PrintOMPExecutableDirective(Node);
920}
921
922void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
923 Indent() << "#pragma omp flush";
924 PrintOMPExecutableDirective(Node);
925}
926
927void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
928 Indent() << "#pragma omp depobj";
929 PrintOMPExecutableDirective(Node);
930}
931
932void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
933 Indent() << "#pragma omp scan";
934 PrintOMPExecutableDirective(Node);
935}
936
937void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
938 Indent() << "#pragma omp ordered";
939 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
940}
941
942void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
943 Indent() << "#pragma omp atomic";
944 PrintOMPExecutableDirective(Node);
945}
946
947void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
948 Indent() << "#pragma omp target";
949 PrintOMPExecutableDirective(Node);
950}
951
952void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
953 Indent() << "#pragma omp target data";
954 PrintOMPExecutableDirective(Node);
955}
956
957void StmtPrinter::VisitOMPTargetEnterDataDirective(
958 OMPTargetEnterDataDirective *Node) {
959 Indent() << "#pragma omp target enter data";
960 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
961}
962
963void StmtPrinter::VisitOMPTargetExitDataDirective(
964 OMPTargetExitDataDirective *Node) {
965 Indent() << "#pragma omp target exit data";
966 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
967}
968
969void StmtPrinter::VisitOMPTargetParallelDirective(
970 OMPTargetParallelDirective *Node) {
971 Indent() << "#pragma omp target parallel";
972 PrintOMPExecutableDirective(Node);
973}
974
975void StmtPrinter::VisitOMPTargetParallelForDirective(
976 OMPTargetParallelForDirective *Node) {
977 Indent() << "#pragma omp target parallel for";
978 PrintOMPExecutableDirective(Node);
979}
980
981void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
982 Indent() << "#pragma omp teams";
983 PrintOMPExecutableDirective(Node);
984}
985
986void StmtPrinter::VisitOMPCancellationPointDirective(
987 OMPCancellationPointDirective *Node) {
988 unsigned OpenMPVersion =
989 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;
990 Indent() << "#pragma omp cancellation point "
991 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);
992 PrintOMPExecutableDirective(Node);
993}
994
995void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
996 unsigned OpenMPVersion =
997 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;
998 Indent() << "#pragma omp cancel "
999 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);
1000 PrintOMPExecutableDirective(Node);
1001}
1002
1003void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
1004 Indent() << "#pragma omp taskloop";
1005 PrintOMPExecutableDirective(Node);
1006}
1007
1008void StmtPrinter::VisitOMPTaskLoopSimdDirective(
1009 OMPTaskLoopSimdDirective *Node) {
1010 Indent() << "#pragma omp taskloop simd";
1011 PrintOMPExecutableDirective(Node);
1012}
1013
1014void StmtPrinter::VisitOMPMasterTaskLoopDirective(
1015 OMPMasterTaskLoopDirective *Node) {
1016 Indent() << "#pragma omp master taskloop";
1017 PrintOMPExecutableDirective(Node);
1018}
1019
1020void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
1021 OMPMaskedTaskLoopDirective *Node) {
1022 Indent() << "#pragma omp masked taskloop";
1023 PrintOMPExecutableDirective(Node);
1024}
1025
1026void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
1027 OMPMasterTaskLoopSimdDirective *Node) {
1028 Indent() << "#pragma omp master taskloop simd";
1029 PrintOMPExecutableDirective(Node);
1030}
1031
1032void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
1033 OMPMaskedTaskLoopSimdDirective *Node) {
1034 Indent() << "#pragma omp masked taskloop simd";
1035 PrintOMPExecutableDirective(Node);
1036}
1037
1038void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
1039 OMPParallelMasterTaskLoopDirective *Node) {
1040 Indent() << "#pragma omp parallel master taskloop";
1041 PrintOMPExecutableDirective(Node);
1042}
1043
1044void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
1045 OMPParallelMaskedTaskLoopDirective *Node) {
1046 Indent() << "#pragma omp parallel masked taskloop";
1047 PrintOMPExecutableDirective(Node);
1048}
1049
1050void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
1051 OMPParallelMasterTaskLoopSimdDirective *Node) {
1052 Indent() << "#pragma omp parallel master taskloop simd";
1053 PrintOMPExecutableDirective(Node);
1054}
1055
1056void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
1057 OMPParallelMaskedTaskLoopSimdDirective *Node) {
1058 Indent() << "#pragma omp parallel masked taskloop simd";
1059 PrintOMPExecutableDirective(Node);
1060}
1061
1062void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1063 Indent() << "#pragma omp distribute";
1064 PrintOMPExecutableDirective(Node);
1065}
1066
1067void StmtPrinter::VisitOMPTargetUpdateDirective(
1068 OMPTargetUpdateDirective *Node) {
1069 Indent() << "#pragma omp target update";
1070 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1071}
1072
1073void StmtPrinter::VisitOMPDistributeParallelForDirective(
1074 OMPDistributeParallelForDirective *Node) {
1075 Indent() << "#pragma omp distribute parallel for";
1076 PrintOMPExecutableDirective(Node);
1077}
1078
1079void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1080 OMPDistributeParallelForSimdDirective *Node) {
1081 Indent() << "#pragma omp distribute parallel for simd";
1082 PrintOMPExecutableDirective(Node);
1083}
1084
1085void StmtPrinter::VisitOMPDistributeSimdDirective(
1086 OMPDistributeSimdDirective *Node) {
1087 Indent() << "#pragma omp distribute simd";
1088 PrintOMPExecutableDirective(Node);
1089}
1090
1091void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1092 OMPTargetParallelForSimdDirective *Node) {
1093 Indent() << "#pragma omp target parallel for simd";
1094 PrintOMPExecutableDirective(Node);
1095}
1096
1097void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1098 Indent() << "#pragma omp target simd";
1099 PrintOMPExecutableDirective(Node);
1100}
1101
1102void StmtPrinter::VisitOMPTeamsDistributeDirective(
1103 OMPTeamsDistributeDirective *Node) {
1104 Indent() << "#pragma omp teams distribute";
1105 PrintOMPExecutableDirective(Node);
1106}
1107
1108void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1109 OMPTeamsDistributeSimdDirective *Node) {
1110 Indent() << "#pragma omp teams distribute simd";
1111 PrintOMPExecutableDirective(Node);
1112}
1113
1114void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1115 OMPTeamsDistributeParallelForSimdDirective *Node) {
1116 Indent() << "#pragma omp teams distribute parallel for simd";
1117 PrintOMPExecutableDirective(Node);
1118}
1119
1120void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1121 OMPTeamsDistributeParallelForDirective *Node) {
1122 Indent() << "#pragma omp teams distribute parallel for";
1123 PrintOMPExecutableDirective(Node);
1124}
1125
1126void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1127 Indent() << "#pragma omp target teams";
1128 PrintOMPExecutableDirective(Node);
1129}
1130
1131void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1132 OMPTargetTeamsDistributeDirective *Node) {
1133 Indent() << "#pragma omp target teams distribute";
1134 PrintOMPExecutableDirective(Node);
1135}
1136
1137void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1138 OMPTargetTeamsDistributeParallelForDirective *Node) {
1139 Indent() << "#pragma omp target teams distribute parallel for";
1140 PrintOMPExecutableDirective(Node);
1141}
1142
1143void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1144 OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
1145 Indent() << "#pragma omp target teams distribute parallel for simd";
1146 PrintOMPExecutableDirective(Node);
1147}
1148
1149void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1150 OMPTargetTeamsDistributeSimdDirective *Node) {
1151 Indent() << "#pragma omp target teams distribute simd";
1152 PrintOMPExecutableDirective(Node);
1153}
1154
1155void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1156 Indent() << "#pragma omp interop";
1157 PrintOMPExecutableDirective(Node);
1158}
1159
1160void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1161 Indent() << "#pragma omp dispatch";
1162 PrintOMPExecutableDirective(Node);
1163}
1164
1165void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1166 Indent() << "#pragma omp masked";
1167 PrintOMPExecutableDirective(Node);
1168}
1169
1170void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1171 Indent() << "#pragma omp loop";
1172 PrintOMPExecutableDirective(Node);
1173}
1174
1175void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1176 OMPTeamsGenericLoopDirective *Node) {
1177 Indent() << "#pragma omp teams loop";
1178 PrintOMPExecutableDirective(Node);
1179}
1180
1181void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1182 OMPTargetTeamsGenericLoopDirective *Node) {
1183 Indent() << "#pragma omp target teams loop";
1184 PrintOMPExecutableDirective(Node);
1185}
1186
1187void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1188 OMPParallelGenericLoopDirective *Node) {
1189 Indent() << "#pragma omp parallel loop";
1190 PrintOMPExecutableDirective(Node);
1191}
1192
1193void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1194 OMPTargetParallelGenericLoopDirective *Node) {
1195 Indent() << "#pragma omp target parallel loop";
1196 PrintOMPExecutableDirective(Node);
1197}
1198
1199//===----------------------------------------------------------------------===//
1200// OpenACC construct printing methods
1201//===----------------------------------------------------------------------===//
1202void StmtPrinter::PrintOpenACCClauseList(OpenACCConstructStmt *S) {
1203 if (!S->clauses().empty()) {
1204 OS << ' ';
1205 OpenACCClausePrinter Printer(OS, Policy);
1206 Printer.VisitClauseList(S->clauses());
1207 }
1208}
1209void StmtPrinter::PrintOpenACCConstruct(OpenACCConstructStmt *S) {
1210 Indent() << "#pragma acc " << S->getDirectiveKind();
1211 PrintOpenACCClauseList(S);
1212 OS << '\n';
1213}
1214void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
1215 PrintOpenACCConstruct(S);
1216 PrintStmt(S->getStructuredBlock());
1217}
1218
1219void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
1220 PrintOpenACCConstruct(S);
1221 PrintStmt(S->getLoop());
1222}
1223
1224void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {
1225 PrintOpenACCConstruct(S);
1226 PrintStmt(S->getLoop());
1227}
1228
1229void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {
1230 PrintOpenACCConstruct(S);
1231 PrintStmt(S->getStructuredBlock());
1232}
1233void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
1234 PrintOpenACCConstruct(S);
1235 PrintStmt(S->getStructuredBlock());
1236}
1237void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) {
1238 PrintOpenACCConstruct(S);
1239}
1240void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
1241 PrintOpenACCConstruct(S);
1242}
1243void StmtPrinter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
1244 PrintOpenACCConstruct(S);
1245}
1246void StmtPrinter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
1247 PrintOpenACCConstruct(S);
1248}
1249void StmtPrinter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {
1250 PrintOpenACCConstruct(S);
1251}
1252void StmtPrinter::VisitOpenACCUpdateConstruct(OpenACCUpdateConstruct *S) {
1253 PrintOpenACCConstruct(S);
1254}
1255
1256void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
1257 Indent() << "#pragma acc wait";
1258 if (!S->getLParenLoc().isInvalid()) {
1259 OS << "(";
1260 if (S->hasDevNumExpr()) {
1261 OS << "devnum: ";
1262 S->getDevNumExpr()->printPretty(OS, nullptr, Policy);
1263 OS << " : ";
1264 }
1265
1266 if (S->hasQueuesTag())
1267 OS << "queues: ";
1268
1269 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](const Expr *E) {
1270 E->printPretty(OS, nullptr, Policy);
1271 });
1272
1273 OS << ")";
1274 }
1275
1276 PrintOpenACCClauseList(S);
1277 OS << '\n';
1278}
1279
1280void StmtPrinter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) {
1281 Indent() << "#pragma acc atomic";
1282
1283 if (S->getAtomicKind() != OpenACCAtomicKind::None)
1284 OS << " " << S->getAtomicKind();
1285
1286 PrintOpenACCClauseList(S);
1287 OS << '\n';
1288 PrintStmt(S->getAssociatedStmt());
1289}
1290
1291void StmtPrinter::VisitOpenACCCacheConstruct(OpenACCCacheConstruct *S) {
1292 Indent() << "#pragma acc cache(";
1293 if (S->hasReadOnly())
1294 OS << "readonly: ";
1295
1296 llvm::interleaveComma(S->getVarList(), OS, [&](const Expr *E) {
1297 E->printPretty(OS, nullptr, Policy);
1298 });
1299
1300 OS << ")\n";
1301}
1302
1303//===----------------------------------------------------------------------===//
1304// Expr printing methods.
1305//===----------------------------------------------------------------------===//
1306
1307void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1308 OS << Node->getBuiltinStr() << "()";
1309}
1310
1311void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
1312 // FIXME: Embed parameters are not reflected in the AST, so there is no way to
1313 // print them yet.
1314 OS << "#embed ";
1315 OS << Node->getFileName();
1316 OS << NL;
1317}
1318
1319void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1320 PrintExpr(Node->getSubExpr());
1321}
1322
1323void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1324 ValueDecl *VD = Node->getDecl();
1325 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(VD)) {
1326 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1327 return;
1328 }
1329 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(VD)) {
1330 TPOD->printAsExpr(OS, Policy);
1331 return;
1332 }
1333 bool ForceAnonymous =
1334 Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm;
1335 bool CleanUglifiedParameter = Policy.CleanUglifiedParameters &&
1337
1338 if (Policy.FullyQualifiedName && !ForceAnonymous && !CleanUglifiedParameter) {
1339 VD->printQualifiedName(OS, Policy);
1340 } else {
1341 Node->getQualifier().print(OS, Policy);
1342 if (Node->hasTemplateKeyword())
1343 OS << "template ";
1344
1345 DeclarationNameInfo NameInfo = Node->getNameInfo();
1346 if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
1347 !ForceAnonymous && (ID || NameInfo.getName().getNameKind() !=
1349 if (CleanUglifiedParameter && ID)
1350 OS << ID->deuglifiedName();
1351 else
1352 NameInfo.printName(OS, Policy);
1353 } else {
1354 switch (VD->getKind()) {
1355 case Decl::NonTypeTemplateParm: {
1356 auto *TD = cast<NonTypeTemplateParmDecl>(VD);
1357 OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex()
1358 << "";
1359 break;
1360 }
1361 case Decl::ParmVar: {
1362 auto *PD = cast<ParmVarDecl>(VD);
1363 OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
1364 << PD->getFunctionScopeIndex();
1365 break;
1366 }
1367 case Decl::Decomposition:
1368 OS << "decomposition";
1369 for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
1370 OS << '-' << I->getName();
1371 break;
1372 default:
1373 OS << "unhandled-anonymous-" << VD->getDeclKindName();
1374 break;
1375 }
1376 }
1377 }
1378 if (Node->hasExplicitTemplateArgs()) {
1379 const TemplateParameterList *TPL = nullptr;
1380 if (!Node->hadMultipleCandidates())
1381 if (auto *TD = dyn_cast<TemplateDecl>(VD))
1382 TPL = TD->getTemplateParameters();
1383 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1384 }
1385}
1386
1387void StmtPrinter::VisitDependentScopeDeclRefExpr(
1388 DependentScopeDeclRefExpr *Node) {
1389 Node->getQualifier().print(OS, Policy);
1390 if (Node->hasTemplateKeyword())
1391 OS << "template ";
1392 OS << Node->getNameInfo();
1393 if (Node->hasExplicitTemplateArgs())
1394 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1395}
1396
1397void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1398 Node->getQualifier().print(OS, Policy);
1399 if (Node->hasTemplateKeyword())
1400 OS << "template ";
1401 OS << Node->getNameInfo();
1402 if (Node->hasExplicitTemplateArgs())
1403 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1404}
1405
1406static bool isImplicitSelf(const Expr *E) {
1407 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1408 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1409 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1410 DRE->getBeginLoc().isInvalid())
1411 return true;
1412 }
1413 }
1414 return false;
1415}
1416
1417void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1418 if (Node->getBase()) {
1419 if (!Policy.SuppressImplicitBase ||
1420 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1421 PrintExpr(Node->getBase());
1422 OS << (Node->isArrow() ? "->" : ".");
1423 }
1424 }
1425 OS << *Node->getDecl();
1426}
1427
1428void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1429 if (Node->isSuperReceiver())
1430 OS << "super.";
1431 else if (Node->isObjectReceiver() && Node->getBase()) {
1432 PrintExpr(Node->getBase());
1433 OS << ".";
1434 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1435 OS << Node->getClassReceiver()->getName() << ".";
1436 }
1437
1438 if (Node->isImplicitProperty()) {
1439 if (const auto *Getter = Node->getImplicitPropertyGetter())
1440 Getter->getSelector().print(OS);
1441 else
1444 } else
1445 OS << Node->getExplicitProperty()->getName();
1446}
1447
1448void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1449 PrintExpr(Node->getBaseExpr());
1450 OS << "[";
1451 PrintExpr(Node->getKeyExpr());
1452 OS << "]";
1453}
1454
1455void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1456 SYCLUniqueStableNameExpr *Node) {
1457 OS << "__builtin_sycl_unique_stable_name(";
1458 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1459 OS << ")";
1460}
1461
1462void StmtPrinter::VisitUnresolvedSYCLKernelCallStmt(
1463 UnresolvedSYCLKernelCallStmt *Node) {
1464 PrintStmt(Node->getOriginalStmt());
1465}
1466
1467void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1469}
1470
1471void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {
1472 OS << '*';
1473}
1474
1475void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1476 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1477}
1478
1479/// Prints the given expression using the original source text. Returns true on
1480/// success, false otherwise.
1481static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1482 const ASTContext *Context) {
1483 if (!Context)
1484 return false;
1485 bool Invalid = false;
1486 StringRef Source = Lexer::getSourceText(
1488 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1489 if (!Invalid) {
1490 OS << Source;
1491 return true;
1492 }
1493 return false;
1494}
1495
1496void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1497 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1498 return;
1499 bool isSigned = Node->getType()->isSignedIntegerType();
1500 OS << toString(Node->getValue(), 10, isSigned);
1501
1502 if (isa<BitIntType>(Node->getType())) {
1503 OS << (isSigned ? "wb" : "uwb");
1504 return;
1505 }
1506
1507 // Emit suffixes. Integer literals are always a builtin integer type.
1508 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1509 default: llvm_unreachable("Unexpected type for integer literal!");
1510 case BuiltinType::Char_S:
1511 case BuiltinType::Char_U: OS << "i8"; break;
1512 case BuiltinType::UChar: OS << "Ui8"; break;
1513 case BuiltinType::SChar: OS << "i8"; break;
1514 case BuiltinType::Short: OS << "i16"; break;
1515 case BuiltinType::UShort: OS << "Ui16"; break;
1516 case BuiltinType::Int: break; // no suffix.
1517 case BuiltinType::UInt: OS << 'U'; break;
1518 case BuiltinType::Long: OS << 'L'; break;
1519 case BuiltinType::ULong: OS << "UL"; break;
1520 case BuiltinType::LongLong: OS << "LL"; break;
1521 case BuiltinType::ULongLong: OS << "ULL"; break;
1522 case BuiltinType::Int128:
1523 break; // no suffix.
1524 case BuiltinType::UInt128:
1525 break; // no suffix.
1526 case BuiltinType::WChar_S:
1527 case BuiltinType::WChar_U:
1528 break; // no suffix
1529 }
1530}
1531
1532void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1533 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1534 return;
1535 OS << Node->getValueAsString(/*Radix=*/10);
1536
1537 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1538 default: llvm_unreachable("Unexpected type for fixed point literal!");
1539 case BuiltinType::ShortFract: OS << "hr"; break;
1540 case BuiltinType::ShortAccum: OS << "hk"; break;
1541 case BuiltinType::UShortFract: OS << "uhr"; break;
1542 case BuiltinType::UShortAccum: OS << "uhk"; break;
1543 case BuiltinType::Fract: OS << "r"; break;
1544 case BuiltinType::Accum: OS << "k"; break;
1545 case BuiltinType::UFract: OS << "ur"; break;
1546 case BuiltinType::UAccum: OS << "uk"; break;
1547 case BuiltinType::LongFract: OS << "lr"; break;
1548 case BuiltinType::LongAccum: OS << "lk"; break;
1549 case BuiltinType::ULongFract: OS << "ulr"; break;
1550 case BuiltinType::ULongAccum: OS << "ulk"; break;
1551 }
1552}
1553
1554static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1555 bool PrintSuffix) {
1556 SmallString<16> Str;
1557 Node->getValue().toString(Str);
1558 OS << Str;
1559 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1560 OS << '.'; // Trailing dot in order to separate from ints.
1561
1562 if (!PrintSuffix)
1563 return;
1564
1565 // Emit suffixes. Float literals are always a builtin float type.
1566 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1567 default: llvm_unreachable("Unexpected type for float literal!");
1568 case BuiltinType::Half: break; // FIXME: suffix?
1569 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1570 case BuiltinType::Double: break; // no suffix.
1571 case BuiltinType::Float16: OS << "F16"; break;
1572 case BuiltinType::Float: OS << 'F'; break;
1573 case BuiltinType::LongDouble: OS << 'L'; break;
1574 case BuiltinType::Float128: OS << 'Q'; break;
1575 }
1576}
1577
1578void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1579 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1580 return;
1581 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1582}
1583
1584void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1585 PrintExpr(Node->getSubExpr());
1586 OS << "i";
1587}
1588
1589void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1590 Str->outputString(OS);
1591}
1592
1593void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1594 OS << "(";
1595 PrintExpr(Node->getSubExpr());
1596 OS << ")";
1597}
1598
1599void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1600 if (!Node->isPostfix()) {
1602
1603 // Print a space if this is an "identifier operator" like __real, or if
1604 // it might be concatenated incorrectly like '+'.
1605 switch (Node->getOpcode()) {
1606 default: break;
1607 case UO_Real:
1608 case UO_Imag:
1609 case UO_Extension:
1610 OS << ' ';
1611 break;
1612 case UO_Plus:
1613 case UO_Minus:
1614 if (isa<UnaryOperator>(Node->getSubExpr()))
1615 OS << ' ';
1616 break;
1617 }
1618 }
1619 PrintExpr(Node->getSubExpr());
1620
1621 if (Node->isPostfix())
1623}
1624
1625void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1626 OS << "__builtin_offsetof(";
1627 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1628 OS << ", ";
1629 bool PrintedSomething = false;
1630 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1631 OffsetOfNode ON = Node->getComponent(i);
1632 if (ON.getKind() == OffsetOfNode::Array) {
1633 // Array node
1634 OS << "[";
1635 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1636 OS << "]";
1637 PrintedSomething = true;
1638 continue;
1639 }
1640
1641 // Skip implicit base indirections.
1642 if (ON.getKind() == OffsetOfNode::Base)
1643 continue;
1644
1645 // Field or identifier node.
1646 const IdentifierInfo *Id = ON.getFieldName();
1647 if (!Id)
1648 continue;
1649
1650 if (PrintedSomething)
1651 OS << ".";
1652 else
1653 PrintedSomething = true;
1654 OS << Id->getName();
1655 }
1656 OS << ")";
1657}
1658
1659void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1660 UnaryExprOrTypeTraitExpr *Node) {
1661 const char *Spelling = getTraitSpelling(Node->getKind());
1662 if (Node->getKind() == UETT_AlignOf) {
1663 if (Policy.Alignof)
1664 Spelling = "alignof";
1665 else if (Policy.UnderscoreAlignof)
1666 Spelling = "_Alignof";
1667 else
1668 Spelling = "__alignof";
1669 }
1670
1671 OS << Spelling;
1672
1673 if (Node->isArgumentType()) {
1674 OS << '(';
1675 Node->getArgumentType().print(OS, Policy);
1676 OS << ')';
1677 } else {
1678 OS << " ";
1679 PrintExpr(Node->getArgumentExpr());
1680 }
1681}
1682
1683void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1684 OS << "_Generic(";
1685 if (Node->isExprPredicate())
1686 PrintExpr(Node->getControllingExpr());
1687 else
1688 Node->getControllingType()->getType().print(OS, Policy);
1689
1690 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1691 OS << ", ";
1692 QualType T = Assoc.getType();
1693 if (T.isNull())
1694 OS << "default";
1695 else
1696 T.print(OS, Policy);
1697 OS << ": ";
1698 PrintExpr(Assoc.getAssociationExpr());
1699 }
1700 OS << ")";
1701}
1702
1703void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1704 PrintExpr(Node->getLHS());
1705 OS << "[";
1706 PrintExpr(Node->getRHS());
1707 OS << "]";
1708}
1709
1710void StmtPrinter::VisitMatrixSingleSubscriptExpr(
1711 MatrixSingleSubscriptExpr *Node) {
1712 PrintExpr(Node->getBase());
1713 OS << "[";
1714 PrintExpr(Node->getRowIdx());
1715 OS << "]";
1716}
1717
1718void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1719 PrintExpr(Node->getBase());
1720 OS << "[";
1721 PrintExpr(Node->getRowIdx());
1722 OS << "]";
1723 OS << "[";
1724 PrintExpr(Node->getColumnIdx());
1725 OS << "]";
1726}
1727
1728void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1729 PrintExpr(Node->getBase());
1730 OS << "[";
1731 if (Node->getLowerBound())
1732 PrintExpr(Node->getLowerBound());
1733 if (Node->getColonLocFirst().isValid()) {
1734 OS << ":";
1735 if (Node->getLength())
1736 PrintExpr(Node->getLength());
1737 }
1738 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1739 OS << ":";
1740 if (Node->getStride())
1741 PrintExpr(Node->getStride());
1742 }
1743 OS << "]";
1744}
1745
1746void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1747 OS << "(";
1748 for (Expr *E : Node->getDimensions()) {
1749 OS << "[";
1750 PrintExpr(E);
1751 OS << "]";
1752 }
1753 OS << ")";
1754 PrintExpr(Node->getBase());
1755}
1756
1757void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1758 OS << "iterator(";
1759 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1760 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1761 VD->getType().print(OS, Policy);
1762 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1763 OS << " " << VD->getName() << " = ";
1764 PrintExpr(Range.Begin);
1765 OS << ":";
1766 PrintExpr(Range.End);
1767 if (Range.Step) {
1768 OS << ":";
1769 PrintExpr(Range.Step);
1770 }
1771 if (I < E - 1)
1772 OS << ", ";
1773 }
1774 OS << ")";
1775}
1776
1777void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1778 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1779 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1780 // Don't print any defaulted arguments
1781 break;
1782 }
1783
1784 if (i) OS << ", ";
1785 PrintExpr(Call->getArg(i));
1786 }
1787}
1788
1789void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1790 PrintExpr(Call->getCallee());
1791 OS << "(";
1792 PrintCallArgs(Call);
1793 OS << ")";
1794}
1795
1796static bool isImplicitThis(const Expr *E) {
1797 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1798 return TE->isImplicit();
1799 return false;
1800}
1801
1802void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1803 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1804 PrintExpr(Node->getBase());
1805
1806 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1807 FieldDecl *ParentDecl =
1808 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1809 : nullptr;
1810
1811 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1812 OS << (Node->isArrow() ? "->" : ".");
1813 }
1814
1815 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1816 if (FD->isAnonymousStructOrUnion())
1817 return;
1818
1819 Node->getQualifier().print(OS, Policy);
1820 if (Node->hasTemplateKeyword())
1821 OS << "template ";
1822 OS << Node->getMemberNameInfo();
1823 const TemplateParameterList *TPL = nullptr;
1824 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1825 if (!Node->hadMultipleCandidates())
1826 if (auto *FTD = FD->getPrimaryTemplate())
1827 TPL = FTD->getTemplateParameters();
1828 } else if (auto *VTSD =
1829 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1830 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1831 if (Node->hasExplicitTemplateArgs())
1832 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1833}
1834
1835void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1836 PrintExpr(Node->getBase());
1837 OS << (Node->isArrow() ? "->isa" : ".isa");
1838}
1839
1840void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1841 PrintExpr(Node->getBase());
1842 OS << ".";
1843 OS << Node->getAccessor().getName();
1844}
1845
1846void StmtPrinter::VisitMatrixElementExpr(MatrixElementExpr *Node) {
1847 PrintExpr(Node->getBase());
1848 OS << ".";
1849 OS << Node->getAccessor().getName();
1850}
1851
1852void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1853 OS << '(';
1854 Node->getTypeAsWritten().print(OS, Policy);
1855 OS << ')';
1856 PrintExpr(Node->getSubExpr());
1857}
1858
1859void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1860 OS << '(';
1861 Node->getType().print(OS, Policy);
1862 OS << ')';
1863 PrintExpr(Node->getInitializer());
1864}
1865
1866void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1867 // No need to print anything, simply forward to the subexpression.
1868 PrintExpr(Node->getSubExpr());
1869}
1870
1871void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1872 PrintExpr(Node->getLHS());
1873 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1874 PrintExpr(Node->getRHS());
1875}
1876
1877void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1878 PrintExpr(Node->getLHS());
1879 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1880 PrintExpr(Node->getRHS());
1881}
1882
1883void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1884 PrintExpr(Node->getCond());
1885 OS << " ? ";
1886 PrintExpr(Node->getLHS());
1887 OS << " : ";
1888 PrintExpr(Node->getRHS());
1889}
1890
1891// GNU extensions.
1892
1893void
1894StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1895 PrintExpr(Node->getCommon());
1896 OS << " ?: ";
1897 PrintExpr(Node->getFalseExpr());
1898}
1899
1900void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1901 OS << "&&" << Node->getLabel()->getName();
1902}
1903
1904void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1905 OS << "(";
1906 PrintRawCompoundStmt(E->getSubStmt());
1907 OS << ")";
1908}
1909
1910void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1911 OS << "__builtin_choose_expr(";
1912 PrintExpr(Node->getCond());
1913 OS << ", ";
1914 PrintExpr(Node->getLHS());
1915 OS << ", ";
1916 PrintExpr(Node->getRHS());
1917 OS << ")";
1918}
1919
1920void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1921 OS << "__null";
1922}
1923
1924void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1925 OS << "__builtin_shufflevector(";
1926 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1927 if (i) OS << ", ";
1928 PrintExpr(Node->getExpr(i));
1929 }
1930 OS << ")";
1931}
1932
1933void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1934 OS << "__builtin_convertvector(";
1935 PrintExpr(Node->getSrcExpr());
1936 OS << ", ";
1937 Node->getType().print(OS, Policy);
1938 OS << ")";
1939}
1940
1941void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1942 if (Node->getSyntacticForm()) {
1943 Visit(Node->getSyntacticForm());
1944 return;
1945 }
1946
1947 OS << "{";
1948 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1949 if (i) OS << ", ";
1950 if (Node->getInit(i))
1951 PrintExpr(Node->getInit(i));
1952 else
1953 OS << "{}";
1954 }
1955 OS << "}";
1956}
1957
1958void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1959 // There's no way to express this expression in any of our supported
1960 // languages, so just emit something terse and (hopefully) clear.
1961 OS << "{";
1962 PrintExpr(Node->getSubExpr());
1963 OS << "}";
1964}
1965
1966void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1967 OS << "*";
1968}
1969
1970void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1971 OS << "(";
1972 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1973 if (i) OS << ", ";
1974 PrintExpr(Node->getExpr(i));
1975 }
1976 OS << ")";
1977}
1978
1979void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1980 bool NeedsEquals = true;
1981 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1982 if (D.isFieldDesignator()) {
1983 if (D.getDotLoc().isInvalid()) {
1984 if (const IdentifierInfo *II = D.getFieldName()) {
1985 OS << II->getName() << ":";
1986 NeedsEquals = false;
1987 }
1988 } else {
1989 OS << "." << D.getFieldName()->getName();
1990 }
1991 } else {
1992 OS << "[";
1993 if (D.isArrayDesignator()) {
1994 PrintExpr(Node->getArrayIndex(D));
1995 } else {
1996 PrintExpr(Node->getArrayRangeStart(D));
1997 OS << " ... ";
1998 PrintExpr(Node->getArrayRangeEnd(D));
1999 }
2000 OS << "]";
2001 }
2002 }
2003
2004 if (NeedsEquals)
2005 OS << " = ";
2006 else
2007 OS << " ";
2008 PrintExpr(Node->getInit());
2009}
2010
2011void StmtPrinter::VisitDesignatedInitUpdateExpr(
2012 DesignatedInitUpdateExpr *Node) {
2013 OS << "{";
2014 OS << "/*base*/";
2015 PrintExpr(Node->getBase());
2016 OS << ", ";
2017
2018 OS << "/*updater*/";
2019 PrintExpr(Node->getUpdater());
2020 OS << "}";
2021}
2022
2023void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
2024 OS << "/*no init*/";
2025}
2026
2027void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
2028 if (Node->getType()->getAsCXXRecordDecl()) {
2029 OS << "/*implicit*/";
2030 Node->getType().print(OS, Policy);
2031 OS << "()";
2032 } else {
2033 OS << "/*implicit*/(";
2034 Node->getType().print(OS, Policy);
2035 OS << ')';
2036 if (Node->getType()->isRecordType())
2037 OS << "{}";
2038 else
2039 OS << 0;
2040 }
2041}
2042
2043void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
2044 OS << "__builtin_va_arg(";
2045 PrintExpr(Node->getSubExpr());
2046 OS << ", ";
2047 Node->getType().print(OS, Policy);
2048 OS << ")";
2049}
2050
2051void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
2052 PrintExpr(Node->getSyntacticForm());
2053}
2054
2055void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
2056 const char *Name = nullptr;
2057 switch (Node->getOp()) {
2058#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2059 case AtomicExpr::AO ## ID: \
2060 Name = #ID "("; \
2061 break;
2062#include "clang/Basic/Builtins.inc"
2063 }
2064 OS << Name;
2065
2066 // AtomicExpr stores its subexpressions in a permuted order.
2067 PrintExpr(Node->getPtr());
2068 if (Node->hasVal1Operand()) {
2069 OS << ", ";
2070 PrintExpr(Node->getVal1());
2071 }
2072 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
2073 Node->isCmpXChg()) {
2074 OS << ", ";
2075 PrintExpr(Node->getVal2());
2076 }
2077 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
2078 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
2079 OS << ", ";
2080 PrintExpr(Node->getWeak());
2081 }
2082 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
2083 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
2084 OS << ", ";
2085 PrintExpr(Node->getOrder());
2086 }
2087 if (Node->isCmpXChg()) {
2088 OS << ", ";
2089 PrintExpr(Node->getOrderFail());
2090 }
2091 OS << ")";
2092}
2093
2094// C++
2095void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
2097 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
2098 if (Node->getNumArgs() == 1) {
2099 OS << getOperatorSpelling(Kind) << ' ';
2100 PrintExpr(Node->getArg(0));
2101 } else {
2102 PrintExpr(Node->getArg(0));
2103 OS << ' ' << getOperatorSpelling(Kind);
2104 }
2105 } else if (Kind == OO_Arrow) {
2106 PrintExpr(Node->getArg(0));
2107 } else if (Kind == OO_Call || Kind == OO_Subscript) {
2108 PrintExpr(Node->getArg(0));
2109 OS << (Kind == OO_Call ? '(' : '[');
2110 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
2111 if (ArgIdx > 1)
2112 OS << ", ";
2113 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
2114 PrintExpr(Node->getArg(ArgIdx));
2115 }
2116 OS << (Kind == OO_Call ? ')' : ']');
2117 } else if (Node->getNumArgs() == 1) {
2118 OS << getOperatorSpelling(Kind) << ' ';
2119 PrintExpr(Node->getArg(0));
2120 } else if (Node->getNumArgs() == 2) {
2121 PrintExpr(Node->getArg(0));
2122 OS << ' ' << getOperatorSpelling(Kind) << ' ';
2123 PrintExpr(Node->getArg(1));
2124 } else {
2125 llvm_unreachable("unknown overloaded operator");
2126 }
2127}
2128
2129void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2130 // If we have a conversion operator call only print the argument.
2131 CXXMethodDecl *MD = Node->getMethodDecl();
2132 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2133 PrintExpr(Node->getImplicitObjectArgument());
2134 return;
2135 }
2136 VisitCallExpr(cast<CallExpr>(Node));
2137}
2138
2139void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2140 PrintExpr(Node->getCallee());
2141 OS << "<<<";
2142 PrintCallArgs(Node->getConfig());
2143 OS << ">>>(";
2144 PrintCallArgs(Node);
2145 OS << ")";
2146}
2147
2148void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2149 CXXRewrittenBinaryOperator *Node) {
2150 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
2151 Node->getDecomposedForm();
2152 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
2153 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
2154 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
2155}
2156
2157void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2158 OS << Node->getCastName() << '<';
2159 Node->getTypeAsWritten().print(OS, Policy);
2160 OS << ">(";
2161 PrintExpr(Node->getSubExpr());
2162 OS << ")";
2163}
2164
2165void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2166 VisitCXXNamedCastExpr(Node);
2167}
2168
2169void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2170 VisitCXXNamedCastExpr(Node);
2171}
2172
2173void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2174 VisitCXXNamedCastExpr(Node);
2175}
2176
2177void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2178 VisitCXXNamedCastExpr(Node);
2179}
2180
2181void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2182 OS << "__builtin_bit_cast(";
2183 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2184 OS << ", ";
2185 PrintExpr(Node->getSubExpr());
2186 OS << ")";
2187}
2188
2189void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2190 VisitCXXNamedCastExpr(Node);
2191}
2192
2193void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2194 OS << "typeid(";
2195 if (Node->isTypeOperand()) {
2196 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2197 } else {
2198 PrintExpr(Node->getExprOperand());
2199 }
2200 OS << ")";
2201}
2202
2203void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2204 OS << "__uuidof(";
2205 if (Node->isTypeOperand()) {
2206 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2207 } else {
2208 PrintExpr(Node->getExprOperand());
2209 }
2210 OS << ")";
2211}
2212
2213void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2214 PrintExpr(Node->getBaseExpr());
2215 if (Node->isArrow())
2216 OS << "->";
2217 else
2218 OS << ".";
2219 Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);
2220 OS << Node->getPropertyDecl()->getDeclName();
2221}
2222
2223void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2224 PrintExpr(Node->getBase());
2225 OS << "[";
2226 PrintExpr(Node->getIdx());
2227 OS << "]";
2228}
2229
2230void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2231 switch (Node->getLiteralOperatorKind()) {
2233 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2234 break;
2236 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2237 const TemplateArgumentList *Args =
2238 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2239 assert(Args);
2240
2241 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2242 const TemplateParameterList *TPL = nullptr;
2243 if (!DRE->hadMultipleCandidates())
2244 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2245 TPL = TD->getTemplateParameters();
2246 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2247 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2248 OS << "()";
2249 return;
2250 }
2251
2252 const TemplateArgument &Pack = Args->get(0);
2253 for (const auto &P : Pack.pack_elements()) {
2254 char C = (char)P.getAsIntegral().getZExtValue();
2255 OS << C;
2256 }
2257 break;
2258 }
2260 // Print integer literal without suffix.
2261 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2262 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2263 break;
2264 }
2266 // Print floating literal without suffix.
2268 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2269 break;
2270 }
2273 PrintExpr(Node->getCookedLiteral());
2274 break;
2275 }
2276 OS << Node->getUDSuffix()->getName();
2277}
2278
2279void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2280 OS << (Node->getValue() ? "true" : "false");
2281}
2282
2283void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2284 OS << "nullptr";
2285}
2286
2287void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2288 OS << "this";
2289}
2290
2291void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2292 if (!Node->getSubExpr())
2293 OS << "throw";
2294 else {
2295 OS << "throw ";
2296 PrintExpr(Node->getSubExpr());
2297 }
2298}
2299
2300void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2301 // Nothing to print: we picked up the default argument.
2302}
2303
2304void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2305 // Nothing to print: we picked up the default initializer.
2306}
2307
2308void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2309 auto TargetType = Node->getType();
2310 auto *Auto = TargetType->getContainedDeducedType();
2311 bool Bare = Auto && Auto->isDeduced();
2312
2313 // Parenthesize deduced casts.
2314 if (Bare)
2315 OS << '(';
2316 TargetType.print(OS, Policy);
2317 if (Bare)
2318 OS << ')';
2319
2320 // No extra braces surrounding the inner construct.
2321 if (!Node->isListInitialization())
2322 OS << '(';
2323 PrintExpr(Node->getSubExpr());
2324 if (!Node->isListInitialization())
2325 OS << ')';
2326}
2327
2328void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2329 PrintExpr(Node->getSubExpr());
2330}
2331
2332void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2333 Node->getType().print(OS, Policy);
2334 if (Node->isStdInitListInitialization())
2335 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2336 else if (Node->isListInitialization())
2337 OS << "{";
2338 else
2339 OS << "(";
2340 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2341 ArgEnd = Node->arg_end();
2342 Arg != ArgEnd; ++Arg) {
2343 if ((*Arg)->isDefaultArgument())
2344 break;
2345 if (Arg != Node->arg_begin())
2346 OS << ", ";
2347 PrintExpr(*Arg);
2348 }
2349 if (Node->isStdInitListInitialization())
2350 /* See above. */;
2351 else if (Node->isListInitialization())
2352 OS << "}";
2353 else
2354 OS << ")";
2355}
2356
2357void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2358 OS << '[';
2359 bool NeedComma = false;
2360 switch (Node->getCaptureDefault()) {
2361 case LCD_None:
2362 break;
2363
2364 case LCD_ByCopy:
2365 OS << '=';
2366 NeedComma = true;
2367 break;
2368
2369 case LCD_ByRef:
2370 OS << '&';
2371 NeedComma = true;
2372 break;
2373 }
2375 CEnd = Node->explicit_capture_end();
2376 C != CEnd;
2377 ++C) {
2378 if (C->capturesVLAType())
2379 continue;
2380
2381 if (NeedComma)
2382 OS << ", ";
2383 NeedComma = true;
2384
2385 switch (C->getCaptureKind()) {
2386 case LCK_This:
2387 OS << "this";
2388 break;
2389
2390 case LCK_StarThis:
2391 OS << "*this";
2392 break;
2393
2394 case LCK_ByRef:
2395 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2396 OS << '&';
2397 OS << C->getCapturedVar()->getName();
2398 break;
2399
2400 case LCK_ByCopy:
2401 OS << C->getCapturedVar()->getName();
2402 break;
2403
2404 case LCK_VLAType:
2405 llvm_unreachable("VLA type in explicit captures.");
2406 }
2407
2408 if (C->isPackExpansion())
2409 OS << "...";
2410
2411 if (Node->isInitCapture(C)) {
2412 // Init captures are always VarDecl.
2413 auto *D = cast<VarDecl>(C->getCapturedVar());
2414
2415 llvm::StringRef Pre;
2416 llvm::StringRef Post;
2417 if (D->getInitStyle() == VarDecl::CallInit &&
2418 !isa<ParenListExpr>(D->getInit())) {
2419 Pre = "(";
2420 Post = ")";
2421 } else if (D->getInitStyle() == VarDecl::CInit) {
2422 Pre = " = ";
2423 }
2424
2425 OS << Pre;
2426 PrintExpr(D->getInit());
2427 OS << Post;
2428 }
2429 }
2430 OS << ']';
2431
2432 if (!Node->getExplicitTemplateParameters().empty()) {
2434 OS, Node->getLambdaClass()->getASTContext(),
2435 /*OmitTemplateKW*/true);
2436 }
2437
2438 if (Node->hasExplicitParameters()) {
2439 OS << '(';
2440 CXXMethodDecl *Method = Node->getCallOperator();
2441 NeedComma = false;
2442 for (const auto *P : Method->parameters()) {
2443 if (NeedComma) {
2444 OS << ", ";
2445 } else {
2446 NeedComma = true;
2447 }
2448 std::string ParamStr =
2449 (Policy.CleanUglifiedParameters && P->getIdentifier())
2450 ? P->getIdentifier()->deuglifiedName().str()
2451 : P->getNameAsString();
2452 P->getOriginalType().print(OS, Policy, ParamStr);
2453 }
2454 if (Method->isVariadic()) {
2455 if (NeedComma)
2456 OS << ", ";
2457 OS << "...";
2458 }
2459 OS << ')';
2460
2461 if (Node->isMutable())
2462 OS << " mutable";
2463
2464 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2465 Proto->printExceptionSpecification(OS, Policy);
2466
2467 // FIXME: Attributes
2468
2469 // Print the trailing return type if it was specified in the source.
2470 if (Node->hasExplicitResultType()) {
2471 OS << " -> ";
2472 Proto->getReturnType().print(OS, Policy);
2473 }
2474 }
2475
2476 // Print the body.
2477 OS << ' ';
2478 if (Policy.TerseOutput || Policy.SuppressLambdaBody)
2479 OS << "{}";
2480 else
2481 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2482}
2483
2484void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2485 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2486 TSInfo->getType().print(OS, Policy);
2487 else
2488 Node->getType().print(OS, Policy);
2489 OS << "()";
2490}
2491
2492void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2493 if (E->isGlobalNew())
2494 OS << "::";
2495 OS << "new ";
2496 unsigned NumPlace = E->getNumPlacementArgs();
2497 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2498 OS << "(";
2499 PrintExpr(E->getPlacementArg(0));
2500 for (unsigned i = 1; i < NumPlace; ++i) {
2502 break;
2503 OS << ", ";
2504 PrintExpr(E->getPlacementArg(i));
2505 }
2506 OS << ") ";
2507 }
2508 if (E->isParenTypeId())
2509 OS << "(";
2510 std::string TypeS;
2511 if (E->isArray()) {
2512 llvm::raw_string_ostream s(TypeS);
2513 s << '[';
2514 if (std::optional<Expr *> Size = E->getArraySize())
2515 (*Size)->printPretty(s, Helper, Policy);
2516 s << ']';
2517 }
2518 E->getAllocatedType().print(OS, Policy, TypeS);
2519 if (E->isParenTypeId())
2520 OS << ")";
2521
2523 if (InitStyle != CXXNewInitializationStyle::None) {
2524 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2526 if (Bare)
2527 OS << "(";
2528 PrintExpr(E->getInitializer());
2529 if (Bare)
2530 OS << ")";
2531 }
2532}
2533
2534void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2535 if (E->isGlobalDelete())
2536 OS << "::";
2537 OS << "delete ";
2538 if (E->isArrayForm())
2539 OS << "[] ";
2540 PrintExpr(E->getArgument());
2541}
2542
2543void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2544 PrintExpr(E->getBase());
2545 if (E->isArrow())
2546 OS << "->";
2547 else
2548 OS << '.';
2549 E->getQualifier().print(OS, Policy);
2550 OS << "~";
2551
2552 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2553 OS << II->getName();
2554 else
2555 E->getDestroyedType().print(OS, Policy);
2556}
2557
2558void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2560 OS << "{";
2561
2562 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2563 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2564 // Don't print any defaulted arguments
2565 break;
2566 }
2567
2568 if (i) OS << ", ";
2569 PrintExpr(E->getArg(i));
2570 }
2571
2573 OS << "}";
2574}
2575
2576void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2577 // Parens are printed by the surrounding context.
2578 OS << "<forwarded>";
2579}
2580
2581void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2582 PrintExpr(E->getSubExpr());
2583}
2584
2585void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2586 // Just forward to the subexpression.
2587 PrintExpr(E->getSubExpr());
2588}
2589
2590void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2591 CXXUnresolvedConstructExpr *Node) {
2592 Node->getTypeAsWritten().print(OS, Policy);
2593 if (!Node->isListInitialization())
2594 OS << '(';
2595 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2596 ++Arg) {
2597 if (Arg != Node->arg_begin())
2598 OS << ", ";
2599 PrintExpr(*Arg);
2600 }
2601 if (!Node->isListInitialization())
2602 OS << ')';
2603}
2604
2605void StmtPrinter::VisitCXXReflectExpr(CXXReflectExpr *S) {
2606 // TODO(Reflection): Implement this.
2607 assert(false && "not implemented yet");
2608}
2609
2610void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2611 CXXDependentScopeMemberExpr *Node) {
2612 if (!Node->isImplicitAccess()) {
2613 PrintExpr(Node->getBase());
2614 OS << (Node->isArrow() ? "->" : ".");
2615 }
2616 Node->getQualifier().print(OS, Policy);
2617 if (Node->hasTemplateKeyword())
2618 OS << "template ";
2619 OS << Node->getMemberNameInfo();
2620 if (Node->hasExplicitTemplateArgs())
2621 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2622}
2623
2624void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2625 if (!Node->isImplicitAccess()) {
2626 PrintExpr(Node->getBase());
2627 OS << (Node->isArrow() ? "->" : ".");
2628 }
2629 Node->getQualifier().print(OS, Policy);
2630 if (Node->hasTemplateKeyword())
2631 OS << "template ";
2632 OS << Node->getMemberNameInfo();
2633 if (Node->hasExplicitTemplateArgs())
2634 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2635}
2636
2637void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2638 OS << getTraitSpelling(E->getTrait()) << "(";
2639 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2640 if (I > 0)
2641 OS << ", ";
2642 E->getArg(I)->getType().print(OS, Policy);
2643 }
2644 OS << ")";
2645}
2646
2647void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2648 OS << getTraitSpelling(E->getTrait()) << '(';
2649 E->getQueriedType().print(OS, Policy);
2650 OS << ')';
2651}
2652
2653void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2654 OS << getTraitSpelling(E->getTrait()) << '(';
2655 PrintExpr(E->getQueriedExpression());
2656 OS << ')';
2657}
2658
2659void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2660 OS << "noexcept(";
2661 PrintExpr(E->getOperand());
2662 OS << ")";
2663}
2664
2665void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2666 PrintExpr(E->getPattern());
2667 OS << "...";
2668}
2669
2670void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2671 OS << "sizeof...(" << *E->getPack() << ")";
2672}
2673
2674void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2675 PrintExpr(E->getPackIdExpression());
2676 OS << "...[";
2677 PrintExpr(E->getIndexExpr());
2678 OS << "]";
2679}
2680
2681void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2682 SubstNonTypeTemplateParmPackExpr *Node) {
2683 OS << *Node->getParameterPack();
2684}
2685
2686void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2687 SubstNonTypeTemplateParmExpr *Node) {
2688 Visit(Node->getReplacement());
2689}
2690
2691void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2692 OS << *E->getParameterPack();
2693}
2694
2695void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2696 PrintExpr(Node->getSubExpr());
2697}
2698
2699void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2700 OS << "(";
2701 if (E->getLHS()) {
2702 PrintExpr(E->getLHS());
2703 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2704 }
2705 OS << "...";
2706 if (E->getRHS()) {
2707 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2708 PrintExpr(E->getRHS());
2709 }
2710 OS << ")";
2711}
2712
2713void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2714 llvm::interleaveComma(Node->getUserSpecifiedInitExprs(), OS,
2715 [&](Expr *E) { PrintExpr(E); });
2716}
2717
2718void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2719 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2720 NNS.getNestedNameSpecifier().print(OS, Policy);
2721 if (E->getTemplateKWLoc().isValid())
2722 OS << "template ";
2723 OS << E->getFoundDecl()->getName();
2724 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2725 Policy,
2727}
2728
2729void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2730 OS << "requires ";
2731 auto LocalParameters = E->getLocalParameters();
2732 if (!LocalParameters.empty()) {
2733 OS << "(";
2734 for (ParmVarDecl *LocalParam : LocalParameters) {
2735 PrintRawDecl(LocalParam);
2736 if (LocalParam != LocalParameters.back())
2737 OS << ", ";
2738 }
2739
2740 OS << ") ";
2741 }
2742 OS << "{ ";
2743 auto Requirements = E->getRequirements();
2744 for (concepts::Requirement *Req : Requirements) {
2745 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2746 if (TypeReq->isSubstitutionFailure())
2747 OS << "<<error-type>>";
2748 else
2749 TypeReq->getType()->getType().print(OS, Policy);
2750 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2751 if (ExprReq->isCompound())
2752 OS << "{ ";
2753 if (ExprReq->isExprSubstitutionFailure())
2754 OS << "<<error-expression>>";
2755 else
2756 PrintExpr(ExprReq->getExpr());
2757 if (ExprReq->isCompound()) {
2758 OS << " }";
2759 if (ExprReq->getNoexceptLoc().isValid())
2760 OS << " noexcept";
2761 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2762 if (!RetReq.isEmpty()) {
2763 OS << " -> ";
2764 if (RetReq.isSubstitutionFailure())
2765 OS << "<<error-type>>";
2766 else if (RetReq.isTypeConstraint())
2767 RetReq.getTypeConstraint()->print(OS, Policy);
2768 }
2769 }
2770 } else {
2771 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2772 OS << "requires ";
2773 if (NestedReq->hasInvalidConstraint())
2774 OS << "<<error-expression>>";
2775 else
2776 PrintExpr(NestedReq->getConstraintExpr());
2777 }
2778 OS << "; ";
2779 }
2780 OS << "}";
2781}
2782
2783// C++ Coroutines
2784
2785void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2786 Visit(S->getBody());
2787}
2788
2789void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2790 OS << "co_return";
2791 if (S->getOperand()) {
2792 OS << " ";
2793 Visit(S->getOperand());
2794 }
2795 OS << ";";
2796}
2797
2798void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2799 OS << "co_await ";
2800 PrintExpr(S->getOperand());
2801}
2802
2803void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2804 OS << "co_await ";
2805 PrintExpr(S->getOperand());
2806}
2807
2808void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2809 OS << "co_yield ";
2810 PrintExpr(S->getOperand());
2811}
2812
2813// Obj-C
2814
2815void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2816 OS << "@";
2817 VisitStringLiteral(Node->getString());
2818}
2819
2820void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2821 OS << "@";
2822 Visit(E->getSubExpr());
2823}
2824
2825void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2826 OS << "@[ ";
2827 ObjCArrayLiteral::child_range Ch = E->children();
2828 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2829 if (I != Ch.begin())
2830 OS << ", ";
2831 Visit(*I);
2832 }
2833 OS << " ]";
2834}
2835
2836void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2837 OS << "@{ ";
2838 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2839 if (I > 0)
2840 OS << ", ";
2841
2842 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2843 Visit(Element.Key);
2844 OS << " : ";
2845 Visit(Element.Value);
2846 if (Element.isPackExpansion())
2847 OS << "...";
2848 }
2849 OS << " }";
2850}
2851
2852void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2853 OS << "@encode(";
2854 Node->getEncodedType().print(OS, Policy);
2855 OS << ')';
2856}
2857
2858void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2859 OS << "@selector(";
2860 Node->getSelector().print(OS);
2861 OS << ')';
2862}
2863
2864void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2865 OS << "@protocol(" << *Node->getProtocol() << ')';
2866}
2867
2868void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2869 OS << "[";
2870 switch (Mess->getReceiverKind()) {
2872 PrintExpr(Mess->getInstanceReceiver());
2873 break;
2874
2876 Mess->getClassReceiver().print(OS, Policy);
2877 break;
2878
2881 OS << "Super";
2882 break;
2883 }
2884
2885 OS << ' ';
2886 Selector selector = Mess->getSelector();
2887 if (selector.isUnarySelector()) {
2888 OS << selector.getNameForSlot(0);
2889 } else {
2890 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2891 if (i < selector.getNumArgs()) {
2892 if (i > 0) OS << ' ';
2893 if (selector.getIdentifierInfoForSlot(i))
2894 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2895 else
2896 OS << ":";
2897 }
2898 else OS << ", "; // Handle variadic methods.
2899
2900 PrintExpr(Mess->getArg(i));
2901 }
2902 }
2903 OS << "]";
2904}
2905
2906void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2907 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2908}
2909
2910void
2911StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2912 PrintExpr(E->getSubExpr());
2913}
2914
2915void
2916StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2917 OS << '(' << E->getBridgeKindName();
2918 E->getType().print(OS, Policy);
2919 OS << ')';
2920 PrintExpr(E->getSubExpr());
2921}
2922
2923void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2924 BlockDecl *BD = Node->getBlockDecl();
2925 OS << "^";
2926
2927 const FunctionType *AFT = Node->getFunctionType();
2928
2929 if (isa<FunctionNoProtoType>(AFT)) {
2930 OS << "()";
2931 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2932 OS << '(';
2933 for (BlockDecl::param_iterator AI = BD->param_begin(),
2934 E = BD->param_end(); AI != E; ++AI) {
2935 if (AI != BD->param_begin()) OS << ", ";
2936 std::string ParamStr = (*AI)->getNameAsString();
2937 (*AI)->getType().print(OS, Policy, ParamStr);
2938 }
2939
2940 const auto *FT = cast<FunctionProtoType>(AFT);
2941 if (FT->isVariadic()) {
2942 if (!BD->param_empty()) OS << ", ";
2943 OS << "...";
2944 }
2945 OS << ')';
2946 }
2947 OS << "{ }";
2948}
2949
2950void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2951 PrintExpr(Node->getSourceExpr());
2952}
2953
2954void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2955 OS << "<recovery-expr>(";
2956 const char *Sep = "";
2957 for (Expr *E : Node->subExpressions()) {
2958 OS << Sep;
2959 PrintExpr(E);
2960 Sep = ", ";
2961 }
2962 OS << ')';
2963}
2964
2965void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2966 OS << "__builtin_astype(";
2967 PrintExpr(Node->getSrcExpr());
2968 OS << ", ";
2969 Node->getType().print(OS, Policy);
2970 OS << ")";
2971}
2972
2973void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
2974 PrintExpr(Node->getArgLValue());
2975}
2976
2977//===----------------------------------------------------------------------===//
2978// Stmt method implementations
2979//===----------------------------------------------------------------------===//
2980
2981void Stmt::dumpPretty(const ASTContext &Context) const {
2982 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2983}
2984
2985void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2986 const PrintingPolicy &Policy, unsigned Indentation,
2987 StringRef NL, const ASTContext *Context) const {
2988 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2989 P.Visit(const_cast<Stmt *>(this));
2990}
2991
2992void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2993 const PrintingPolicy &Policy,
2994 unsigned Indentation, StringRef NL,
2995 const ASTContext *Context) const {
2996 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2997 P.PrintControlledStmt(const_cast<Stmt *>(this));
2998}
2999
3000void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
3001 const PrintingPolicy &Policy, bool AddQuotes) const {
3002 std::string Buf;
3003 llvm::raw_string_ostream TempOut(Buf);
3004
3005 printPretty(TempOut, Helper, Policy);
3006
3007 Out << JsonFormat(TempOut.str(), AddQuotes);
3008}
3009
3010//===----------------------------------------------------------------------===//
3011// PrinterHelper
3012//===----------------------------------------------------------------------===//
3013
3014// Implement virtual destructor.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenACC nodes for declarative directives.
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines enumerations for expression traits intrinsics.
unsigned IndentLevel
The indent level of this token. Copied from the surrounding line.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines several types used to describe C++ lambda expressions that are shared between the parser and ...
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
Defines an enumeration for C++ overloaded operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Defines enumerations for the type traits support.
C Language Family Type Representation.
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
const Stmt * getAssociatedStmt() const
OpenACCAtomicKind getAtomicKind() const
bool hasReadOnly() const
ArrayRef< Expr * > getVarList() const
Stmt * getStructuredBlock()
bool hasQueuesTag() const
bool hasDevNumExpr() const
ArrayRef< Expr * > getQueueIdExprs() const
SourceLocation getLParenLoc() const
Expr * getDevNumExpr() const
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
const LangOptions & getLangOpts() const
Definition ASTContext.h:962
LabelDecl * getLabel() const
Definition Expr.h:4579
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:7300
Expr * getLength()
Get length of array section.
Definition Expr.h:7310
bool isOMPArraySection() const
Definition Expr.h:7296
Expr * getStride()
Get stride of array section.
Definition Expr.h:7314
SourceLocation getColonLocSecond() const
Definition Expr.h:7332
Expr * getLowerBound()
Get lower bound of array section.
Definition Expr.h:7304
SourceLocation getColonLocFirst() const
Definition Expr.h:7331
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2756
ArrayTypeTrait getTrait() const
Definition ExprCXX.h:3040
QualType getQueriedType() const
Definition ExprCXX.h:3044
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:6755
bool isVolatile() const
Definition Stmt.h:3323
unsigned getNumClobbers() const
Definition Stmt.h:3378
unsigned getNumOutputs() const
Definition Stmt.h:3346
unsigned getNumInputs() const
Definition Stmt.h:3368
Expr * getVal2() const
Definition Expr.h:6982
Expr * getOrder() const
Definition Expr.h:6965
bool isCmpXChg() const
Definition Expr.h:7015
AtomicOp getOp() const
Definition Expr.h:6994
Expr * getVal1() const
Definition Expr.h:6972
Expr * getPtr() const
Definition Expr.h:6962
Expr * getWeak() const
Definition Expr.h:6988
Expr * getOrderFail() const
Definition Expr.h:6978
bool hasVal1Operand() const
Definition Expr.h:7028
Stmt * getSubStmt()
Definition Stmt.h:2249
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2245
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
Definition Expr.h:4513
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
Definition Expr.h:4494
Expr * getLHS() const
Definition Expr.h:4094
StringRef getOpcodeStr() const
Definition Expr.h:4110
Expr * getRHS() const
Definition Expr.h:4096
Opcode getOpcode() const
Definition Expr.h:4089
param_iterator param_end()
Definition Decl.h:4790
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition Decl.h:4785
param_iterator param_begin()
Definition Decl.h:4789
bool param_empty() const
Definition Decl.h:4788
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Definition Expr.cpp:2541
const BlockDecl * getBlockDecl() const
Definition Expr.h:6687
This class is used for builtin types like 'int'.
Definition TypeBase.h:3228
Kind getKind() const
Definition TypeBase.h:3276
const CallExpr * getConfig() const
Definition ExprCXX.h:264
const Expr * getSubExpr() const
Definition ExprCXX.h:1519
bool getValue() const
Definition ExprCXX.h:744
Stmt * getHandlerBlock() const
Definition StmtCXX.h:51
VarDecl * getExceptionDecl() const
Definition StmtCXX.h:49
arg_iterator arg_begin()
Definition ExprCXX.h:1681
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition ExprCXX.h:1645
arg_iterator arg_end()
Definition ExprCXX.h:1682
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition ExprCXX.h:1634
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1692
bool isArrayForm() const
Definition ExprCXX.h:2656
bool isGlobalDelete() const
Definition ExprCXX.h:2655
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:3969
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the member name.
Definition ExprCXX.h:3977
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4003
bool hasExplicitTemplateArgs() const
Determines whether this member expression actually had a C++ template argument list explicitly specif...
Definition ExprCXX.h:4043
Expr * getBase() const
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:3960
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition ExprCXX.h:4039
bool isImplicitAccess() const
True if this is an implicit access, i.e.
Definition ExprCXX.h:3952
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:4071
Expr * getRHS() const
Definition ExprCXX.h:5058
Expr * getLHS() const
Definition ExprCXX.h:5057
BinaryOperatorKind getOperator() const
Definition ExprCXX.h:5077
VarDecl * getLoopVariable()
Definition StmtCXX.cpp:77
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:1878
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Definition ExprCXX.cpp:748
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition ExprCXX.cpp:729
const char * getCastName() const
getCastName - Get the name of the C++ cast being used, e.g., "static_cast", "dynamic_cast",...
Definition ExprCXX.cpp:775
bool isArray() const
Definition ExprCXX.h:2468
QualType getAllocatedType() const
Definition ExprCXX.h:2438
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Definition ExprCXX.h:2473
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition ExprCXX.h:2531
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2507
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2498
bool isParenTypeId() const
Definition ExprCXX.h:2519
bool isGlobalNew() const
Definition ExprCXX.h:2525
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
Expr * getOperand() const
Definition ExprCXX.h:4326
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Definition ExprCXX.h:115
ArrayRef< Expr * > getUserSpecifiedInitExprs() const
Definition ExprCXX.h:5187
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition ExprCXX.h:2813
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:390
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition ExprCXX.h:2807
const IdentifierInfo * getDestroyedTypeIdentifier() const
In a dependent pseudo-destructor expression for which we do not have full type information on the des...
Definition ExprCXX.h:2850
DecomposedForm getDecomposedForm() const LLVM_READONLY
Decompose this operator into its syntactic form.
Definition ExprCXX.cpp:65
TypeSourceInfo * getTypeSourceInfo() const
Definition ExprCXX.h:2219
const Expr * getSubExpr() const
Definition ExprCXX.h:1232
CXXCatchStmt * getHandler(unsigned i)
Definition StmtCXX.h:108
unsigned getNumHandlers() const
Definition StmtCXX.h:107
CompoundStmt * getTryBlock()
Definition StmtCXX.h:100
bool isTypeOperand() const
Definition ExprCXX.h:888
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:895
Expr * getExprOperand() const
Definition ExprCXX.h:899
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:3799
QualType getTypeAsWritten() const
Retrieve the type that is being constructed, as specified in the source code.
Definition ExprCXX.h:3778
Expr * getExprOperand() const
Definition ExprCXX.h:1113
bool isTypeOperand() const
Definition ExprCXX.h:1102
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:1109
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3153
Expr * getCallee()
Definition Expr.h:3096
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3140
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition Decl.cpp:5727
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition Stmt.cpp:1493
Stmt * getSubStmt()
Definition Stmt.h:2043
Expr * getLHS()
Definition Stmt.h:2013
Expr * getRHS()
Definition Stmt.h:2025
Expr * getSubExpr()
Definition Expr.h:3732
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1026
unsigned getValue() const
Definition Expr.h:1635
CharacterLiteralKind getKind() const
Definition Expr.h:1628
Expr * getLHS() const
Definition Expr.h:4896
Expr * getRHS() const
Definition Expr.h:4898
Expr * getCond() const
Definition Expr.h:4894
const Expr * getInitializer() const
Definition Expr.h:3639
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1750
FPOptionsOverride getStoredFPFeatures() const
Get FPOptionsOverride from trailing storage.
Definition Stmt.h:1800
body_range body()
Definition Stmt.h:1813
bool hasStoredFPFeatures() const
Definition Stmt.h:1797
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
NamedDecl * getFoundDecl() const
SourceLocation getTemplateKWLoc() const
ConceptDecl * getNamedConcept() const
Expr * getLHS() const
Definition Expr.h:4431
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4420
Expr * getRHS() const
Definition Expr.h:4432
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4815
Expr * getOperand() const
Retrieve the operand of the 'co_return' statement.
Definition StmtCXX.h:497
CompoundStmt * getBody() const
Retrieve the body of the coroutine as written.
Definition StmtCXX.h:380
Expr * getOperand() const
Definition ExprCXX.h:5320
bool hasExplicitTemplateArgs() const
Determines whether this declaration reference was followed by an explicit template argument list.
Definition Expr.h:1431
NestedNameSpecifier getQualifier() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name.
Definition Expr.h:1377
DeclarationNameInfo getNameInfo() const
Definition Expr.h:1348
ValueDecl * getDecl()
Definition Expr.h:1344
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:1457
bool hadMultipleCandidates() const
Returns true if this expression refers to a function that was resolved from an overloaded set having ...
Definition Expr.h:1463
bool hasTemplateKeyword() const
Determines whether the name in this declaration reference was preceded by the template keyword.
Definition Expr.h:1427
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition Stmt.h:1654
decl_range decls()
Definition Stmt.h:1689
const Decl * getSingleDecl() const
Definition Stmt.h:1656
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
const char * getDeclKindName() const
Definition DeclBase.cpp:169
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Kind getKind() const
Definition DeclBase.h:450
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
NameKind getNameKind() const
Determine what kind of name this is.
Stmt * getSubStmt()
Definition Stmt.h:2091
Stmt * getBody()
Definition Stmt.h:3265
Expr * getOperand() const
Definition ExprCXX.h:5420
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3618
bool hasExplicitTemplateArgs() const
Determines whether this lookup had explicit template arguments.
Definition ExprCXX.h:3594
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3562
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3591
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3546
Expr * getArrayRangeEnd(const Designator &D) const
Definition Expr.cpp:4904
Expr * getArrayRangeStart(const Designator &D) const
Definition Expr.cpp:4899
MutableArrayRef< Designator > designators()
Definition Expr.h:5787
Expr * getArrayIndex(const Designator &D) const
Definition Expr.cpp:4894
Expr * getInit() const
Retrieve the initializer value.
Definition Expr.h:5822
InitListExpr * getUpdater() const
Definition Expr.h:5939
Stmt * getBody()
Definition Stmt.h:2867
Expr * getCond()
Definition Stmt.h:2860
IdentifierInfo & getAccessor() const
Definition Expr.h:6588
const Expr * getBase() const
Definition Expr.h:6584
StringRef getFileName() const
Definition Expr.h:5150
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition Expr.h:3956
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:3961
This represents one expression.
Definition Expr.h:112
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3079
QualType getType() const
Definition Expr.h:144
Expr * getQueriedExpression() const
Definition ExprCXX.h:3112
ExpressionTrait getTrait() const
Definition ExprCXX.h:3108
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition Decl.cpp:4739
std::string getValueAsString(unsigned Radix) const
Definition Expr.cpp:1016
llvm::APFloat getValue() const
Definition Expr.h:1672
Stmt * getInit()
Definition Stmt.h:2913
Stmt * getBody()
Definition Stmt.h:2942
Expr * getInc()
Definition Stmt.h:2941
Expr * getCond()
Definition Stmt.h:2940
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Definition Stmt.h:2928
const Expr * getSubExpr() const
Definition Expr.h:1068
ValueDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition ExprCXX.h:4867
unsigned getNumLabels() const
Definition Stmt.h:3606
bool isAsmGoto() const
Definition Stmt.h:3602
const Expr * getOutputConstraintExpr(unsigned i) const
Definition Stmt.h:3558
StringRef getLabelName(unsigned i) const
Definition Stmt.cpp:605
StringRef getInputName(unsigned i) const
Definition Stmt.h:3575
StringRef getOutputName(unsigned i) const
Definition Stmt.h:3549
const Expr * getInputConstraintExpr(unsigned i) const
Definition Stmt.h:3584
const Expr * getAsmStringExpr() const
Definition Stmt.h:3483
Expr * getOutputExpr(unsigned i)
Definition Stmt.cpp:582
Expr * getClobberExpr(unsigned i)
Definition Stmt.h:3663
Expr * getInputExpr(unsigned i)
Definition Stmt.cpp:593
AssociationTy< false > Association
Definition Expr.h:6418
TypeSourceInfo * getControllingType()
Return the controlling type of this generic selection expression.
Definition Expr.h:6462
bool isExprPredicate() const
Whether this generic selection uses an expression as its controlling argument.
Definition Expr.h:6443
association_range associations()
Definition Expr.h:6518
Expr * getControllingExpr()
Return the controlling expression of this generic selection expression.
Definition Expr.h:6450
LabelDecl * getLabel() const
Definition Stmt.h:2992
const Expr * getArgLValue() const
Return the l-value expression that was written as the argument in source.
Definition Expr.h:7441
StringRef getName() const
Return the actual identifier string.
const Expr * getSubExpr() const
Definition Expr.h:1749
unsigned getNumInits() const
Definition Expr.h:5338
InitListExpr * getSyntacticForm() const
Definition Expr.h:5475
const Expr * getInit(unsigned Init) const
Definition Expr.h:5360
Stmt * getSubStmt()
Definition Stmt.h:2178
const char * getName() const
Definition Stmt.cpp:437
bool hasExplicitParameters() const
Determine whether this lambda has an explicit parameter list vs.
Definition ExprCXX.h:2175
bool isMutable() const
Determine whether the lambda is mutable, meaning that any captures values can be modified.
Definition ExprCXX.cpp:1435
bool isInitCapture(const LambdaCapture *Capture) const
Determine whether one of this lambda's captures is an init-capture.
Definition ExprCXX.cpp:1365
CXXMethodDecl * getCallOperator() const
Retrieve the function call operator associated with this lambda expression.
Definition ExprCXX.cpp:1411
const CompoundStmt * getCompoundStmtBody() const
Retrieve the CompoundStmt representing the body of the lambda.
Definition ExprCXX.cpp:1358
bool hasExplicitResultType() const
Whether this lambda had its result type explicitly specified.
Definition ExprCXX.h:2178
TemplateParameterList * getTemplateParameterList() const
If this is a generic lambda expression, retrieve the template parameter list associated with it,...
Definition ExprCXX.cpp:1421
ArrayRef< NamedDecl * > getExplicitTemplateParameters() const
Get the template parameters were explicitly specified (as opposed to being invented by use of an auto...
Definition ExprCXX.cpp:1426
capture_iterator explicit_capture_end() const
Retrieve an iterator pointing past the end of the sequence of explicit lambda captures.
Definition ExprCXX.cpp:1386
const LambdaCapture * capture_iterator
An iterator that walks over the captures of the lambda, both implicit and explicit.
Definition ExprCXX.h:2037
capture_iterator explicit_capture_begin() const
Retrieve an iterator pointing to the first explicit lambda capture.
Definition ExprCXX.cpp:1382
LambdaCaptureDefault getCaptureDefault() const
Determine the default capture kind for this lambda.
Definition ExprCXX.h:2025
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1407
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Definition Lexer.cpp:1074
LabelDecl * getLabelDecl()
Definition Stmt.h:3105
bool hasLabelTarget() const
Definition Stmt.h:3100
StringRef getAsmString() const
Definition Stmt.h:3709
bool hasBraces() const
Definition Stmt.h:3703
bool isIfExists() const
Determine whether this is an __if_exists statement.
Definition StmtCXX.h: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:996
bool isArrow() const
Definition ExprCXX.h:994
MSPropertyDecl * getPropertyDecl() const
Definition ExprCXX.h:993
Expr * getBaseExpr() const
Definition ExprCXX.h:992
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4937
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:3542
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition Expr.h:3481
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3453
bool hasExplicitTemplateArgs() const
Determines whether the member name was followed by an explicit template argument list.
Definition Expr.h:3514
Expr * getBase() const
Definition Expr.h:3447
bool hadMultipleCandidates() const
Returns true if this member expression refers to a method that was resolved from an overloaded set ha...
Definition Expr.h:3574
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition Expr.h:3510
DeclarationNameInfo getMemberNameInfo() const
Retrieve the member declaration name info.
Definition Expr.h:3547
bool isArrow() const
Definition Expr.h:3554
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition Decl.cpp:1689
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
Expr * getBase()
Fetches base expression of array shaping expression.
Definition ExprOpenMP.h:90
ArrayRef< Expr * > getDimensions() const
Fetches the dimensions for array shaping expression.
Definition ExprOpenMP.h:80
IteratorRange getIteratorRange(unsigned I)
Gets the iterator range for the given iterator.
Definition Expr.cpp:5571
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:5567
child_range children()
Definition ExprObjC.h:279
const Expr * getSynchExpr() const
Definition StmtObjC.h:331
const CompoundStmt * getSynchBody() const
Definition StmtObjC.h:323
const Expr * getThrowExpr() const
Definition StmtObjC.h:370
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
Definition StmtObjC.h:241
const Stmt * getTryBody() const
Retrieve the @try body.
Definition StmtObjC.h:214
catch_range catch_stmts()
Definition StmtObjC.h:282
const Stmt * getSubStmt() const
Definition StmtObjC.h:405
StringRef getBridgeKindName() const
Retrieve the kind of bridge being performed as a string.
Definition ExprObjC.cpp:348
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Definition ExprObjC.h:392
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Definition ExprObjC.h:394
QualType getEncodedType() const
Definition ExprObjC.h:460
Expr * getBase() const
Definition ExprObjC.h:1554
bool isArrow() const
Definition ExprObjC.h:1556
ObjCIvarDecl * getDecl()
Definition ExprObjC.h:610
bool isArrow() const
Definition ExprObjC.h:618
const Expr * getBase() const
Definition ExprObjC.h:614
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition ExprObjC.h:1434
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition ExprObjC.h:1299
Selector getSelector() const
Definition ExprObjC.cpp:301
@ SuperInstance
The receiver is the instance of the superclass object.
Definition ExprObjC.h:985
@ Instance
The receiver is an object instance.
Definition ExprObjC.h:979
@ SuperClass
The receiver is a superclass.
Definition ExprObjC.h:982
@ Class
The receiver is a class.
Definition ExprObjC.h:976
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Definition ExprObjC.h:1318
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition ExprObjC.h:1260
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition ExprObjC.h:1421
Selector getSelector() const
Definition DeclObjC.h:327
ObjCPropertyDecl * getExplicitProperty() const
Definition ExprObjC.h:737
ObjCMethodDecl * getImplicitPropertyGetter() const
Definition ExprObjC.h:742
const Expr * getBase() const
Definition ExprObjC.h:786
bool isObjectReceiver() const
Definition ExprObjC.h:801
bool isImplicitProperty() const
Definition ExprObjC.h:734
ObjCMethodDecl * getImplicitPropertySetter() const
Definition ExprObjC.h:747
ObjCInterfaceDecl * getClassReceiver() const
Definition ExprObjC.h:797
bool isClassReceiver() const
Definition ExprObjC.h:803
bool isSuperReceiver() const
Definition ExprObjC.h:802
ObjCProtocolDecl * getProtocol() const
Definition ExprObjC.h:553
Selector getSelector() const
Definition ExprObjC.h:500
StringLiteral * getString()
Definition ExprObjC.h:96
Expr * getKeyExpr() const
Definition ExprObjC.h:912
Expr * getBaseExpr() const
Definition ExprObjC.h:909
Expr * getIndexExpr(unsigned Idx)
Definition Expr.h:2592
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2580
TypeSourceInfo * getTypeSourceInfo() const
Definition Expr.h:2573
unsigned getNumComponents() const
Definition Expr.h:2588
const IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1694
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2485
@ Array
An index into an array.
Definition Expr.h:2432
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition Expr.h:2439
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2481
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1234
OpenACCDirectiveKind getDirectiveKind() const
Definition StmtOpenACC.h:57
ArrayRef< const OpenACCClause * > clauses() const
Definition StmtOpenACC.h:67
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition ExprCXX.h:3284
NestedNameSpecifier getQualifier() const
Fetches the nested-name qualifier, if one was given.
Definition ExprCXX.h:3248
const DeclarationNameInfo & getNameInfo() const
Gets the full name info.
Definition ExprCXX.h:3239
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3281
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3337
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition ExprCXX.h:4392
Expr * getIndexExpr() const
Definition ExprCXX.h:4628
Expr * getPackIdExpression() const
Definition ExprCXX.h:4624
const Expr * getSubExpr() const
Definition Expr.h:2205
Expr * getExpr(unsigned Init)
Definition Expr.h:6115
unsigned getNumExprs() const
Return the number of expressions in this paren list.
Definition Expr.h:6113
StringRef getIdentKindName() const
Definition Expr.h:2068
PredefinedIdentKind getIdentKind() const
Definition Expr.h:2046
virtual ~PrinterHelper()
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition Expr.h:6844
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:7513
ArrayRef< concepts::Requirement * > getRequirements() const
ArrayRef< ParmVarDecl * > getLocalParameters() const
Expr * getRetValue()
Definition Stmt.h:3197
CompoundStmt * getBlock() const
Definition Stmt.h:3803
Expr * getFilterExpr() const
Definition Stmt.h:3799
CompoundStmt * getBlock() const
Definition Stmt.h:3840
CompoundStmt * getTryBlock() const
Definition Stmt.h:3884
bool getIsCXXTry() const
Definition Stmt.h:3882
SEHFinallyStmt * getFinallyHandler() const
Definition Stmt.cpp:1343
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition Stmt.cpp:1339
CompoundStmt * getOriginalStmt()
Definition StmtSYCL.h:54
TypeSourceInfo * getTypeSourceInfo()
Definition Expr.h:2149
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
bool isUnarySelector() const
unsigned getNumArgs() const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Definition Expr.h:4682
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4688
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition ExprCXX.h:4509
StringRef getBuiltinStr() const
Return a string representing the name of the specific builtin function.
Definition Expr.cpp:2269
bool isValid() const
Return true if this is a valid SourceLocation object.
CompoundStmt * getSubStmt()
Definition Expr.h:4618
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Stmt(StmtClass SC, EmptyShell)
Construct an empty statement.
Definition Stmt.h:1485
void dumpPretty(const ASTContext &Context) const
dumpPretty/printPretty - These two methods do a "pretty print" of the AST back to its original source...
void outputString(raw_ostream &OS) const
Definition Expr.cpp:1215
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Definition ExprCXX.cpp:1787
Expr * getCond()
Definition Stmt.h:2582
Stmt * getBody()
Definition Stmt.h:2594
Stmt * getInit()
Definition Stmt.h:2599
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition Stmt.h:2633
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Pack
The template argument is actually a parameter pack.
ArgKind getKind() const
Return the kind of stored template argument.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
void print(raw_ostream &Out, const ASTContext &Context, bool OmitTemplateKW=false) const
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8429
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition ExprCXX.h:2965
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition ExprCXX.h:2962
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition ExprCXX.h:2943
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2270
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9344
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
Definition Type.cpp:2113
bool isRecordType() const
Definition TypeBase.h:8811
QualType getArgumentType() const
Definition Expr.h:2674
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2663
static bool isPostfix(Opcode Op)
isPostfix - Return true if this is a postfix operation, like x++.
Definition Expr.h:2320
Expr * getSubExpr() const
Definition Expr.h:2291
Opcode getOpcode() const
Definition Expr.h:2286
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition Expr.cpp:1412
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4218
Expr * getBase()
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:4199
bool isImplicitAccess() const
True if this is an implicit access, i.e., one in which the member being accessed was not written in t...
Definition ExprCXX.cpp:1652
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the full name info for the member that this expression refers to.
Definition ExprCXX.h:4231
LiteralOperatorKind getLiteralOperatorKind() const
Returns the kind of literal operator invocation which this expression represents.
Definition ExprCXX.cpp:1006
const IdentifierInfo * getUDSuffix() const
Returns the ud-suffix specified for this literal.
Definition ExprCXX.cpp:1035
Expr * getCookedLiteral()
If this is not a raw user-defined literal, get the underlying cooked literal (representing the litera...
Definition ExprCXX.cpp:1027
@ LOK_String
operator "" X (const CharT *, size_t)
Definition ExprCXX.h:686
@ LOK_Raw
Raw form: operator "" X (const char *)
Definition ExprCXX.h:674
@ LOK_Floating
operator "" X (long double)
Definition ExprCXX.h:683
@ LOK_Integer
operator "" X (unsigned long long)
Definition ExprCXX.h:680
@ LOK_Template
Raw form: operator "" X<cs...> ()
Definition ExprCXX.h:677
@ LOK_Character
operator "" X (CharT)
Definition ExprCXX.h:689
const Expr * getSubExpr() const
Definition Expr.h:4979
QualType getType() const
Definition Decl.h:723
@ CInit
C-style initialization with assignment.
Definition Decl.h:937
@ CallInit
Call-style initialization (C++98)
Definition Decl.h:940
Expr * getCond()
Definition Stmt.h:2759
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
Definition Stmt.h:2795
Stmt * getBody()
Definition Stmt.h:2771
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ LCK_ByCopy
Capturing by copy (a.k.a., by value)
Definition Lambda.h:36
@ LCK_ByRef
Capturing by reference.
Definition Lambda.h:37
@ LCK_VLAType
Capturing variable-length array type.
Definition Lambda.h:38
@ LCK_StarThis
Capturing the *this object by copy.
Definition Lambda.h:35
@ LCK_This
Capturing the *this object by reference.
Definition Lambda.h:34
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition JsonSupport.h:21
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
Definition JsonSupport.h:28
@ LCD_ByRef
Definition Lambda.h:25
@ LCD_None
Definition Lambda.h:23
@ LCD_ByCopy
Definition Lambda.h:24
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
U cast(CodeGen::Address addr)
Definition Address.h:327
@ ObjCSelf
Parameter for Objective-C 'self' argument.
Definition Decl.h:1754
CXXNewInitializationStyle
Definition ExprCXX.h:2244
ArrayRef< TemplateArgumentLoc > arguments() const
const Expr * RHS
The original right-hand side.
Definition ExprCXX.h:317
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition ExprCXX.h:313
const Expr * LHS
The original left-hand side.
Definition ExprCXX.h:315
DeclarationName getName() const
getName - Returns the embedded declaration name.
void printName(raw_ostream &OS, PrintingPolicy Policy) const
printName - Print the human-readable name to a stream.
Expr * Value
The value of the dictionary element.
Definition ExprObjC.h:300
bool isPackExpansion() const
Determines whether this dictionary element is a pack expansion.
Definition ExprObjC.h:310
Expr * Key
The key for the dictionary element.
Definition ExprObjC.h:297
Describes how types, statements, expressions, and declarations should be printed.
unsigned FullyQualifiedName
When true, print the fully qualified name of function declarations.
unsigned Alignof
Whether we can use 'alignof' rather than '__alignof'.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned ConstantsAsWritten
Whether we should print the constant expressions as written in the sources.
unsigned IncludeNewlines
When true, include newlines after statements like "break", etc.
unsigned TerseOutput
Provide a 'terse' output.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
unsigned UnderscoreAlignof
Whether we can use '_Alignof' rather than '__alignof'.
unsigned SuppressImplicitBase
When true, don't print the implicit 'self' or 'this' expressions.