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 Node->getQualifier().print(OS, Policy);
1334 if (Node->hasTemplateKeyword())
1335 OS << "template ";
1336
1337 bool ForceAnonymous =
1338 Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm;
1339 DeclarationNameInfo NameInfo = Node->getNameInfo();
1340 if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
1341 !ForceAnonymous &&
1342 (ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier)) {
1343 if (Policy.CleanUglifiedParameters &&
1345 OS << ID->deuglifiedName();
1346 else
1347 NameInfo.printName(OS, Policy);
1348 } else {
1349 switch (VD->getKind()) {
1350 case Decl::NonTypeTemplateParm: {
1351 auto *TD = cast<NonTypeTemplateParmDecl>(VD);
1352 OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << "";
1353 break;
1354 }
1355 case Decl::ParmVar: {
1356 auto *PD = cast<ParmVarDecl>(VD);
1357 OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
1358 << PD->getFunctionScopeIndex();
1359 break;
1360 }
1361 case Decl::Decomposition:
1362 OS << "decomposition";
1363 for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
1364 OS << '-' << I->getName();
1365 break;
1366 default:
1367 OS << "unhandled-anonymous-" << VD->getDeclKindName();
1368 break;
1369 }
1370 }
1371 if (Node->hasExplicitTemplateArgs()) {
1372 const TemplateParameterList *TPL = nullptr;
1373 if (!Node->hadMultipleCandidates())
1374 if (auto *TD = dyn_cast<TemplateDecl>(VD))
1375 TPL = TD->getTemplateParameters();
1376 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1377 }
1378}
1379
1380void StmtPrinter::VisitDependentScopeDeclRefExpr(
1381 DependentScopeDeclRefExpr *Node) {
1382 Node->getQualifier().print(OS, Policy);
1383 if (Node->hasTemplateKeyword())
1384 OS << "template ";
1385 OS << Node->getNameInfo();
1386 if (Node->hasExplicitTemplateArgs())
1387 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1388}
1389
1390void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1391 Node->getQualifier().print(OS, Policy);
1392 if (Node->hasTemplateKeyword())
1393 OS << "template ";
1394 OS << Node->getNameInfo();
1395 if (Node->hasExplicitTemplateArgs())
1396 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1397}
1398
1399static bool isImplicitSelf(const Expr *E) {
1400 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1401 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1402 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1403 DRE->getBeginLoc().isInvalid())
1404 return true;
1405 }
1406 }
1407 return false;
1408}
1409
1410void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1411 if (Node->getBase()) {
1412 if (!Policy.SuppressImplicitBase ||
1413 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1414 PrintExpr(Node->getBase());
1415 OS << (Node->isArrow() ? "->" : ".");
1416 }
1417 }
1418 OS << *Node->getDecl();
1419}
1420
1421void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1422 if (Node->isSuperReceiver())
1423 OS << "super.";
1424 else if (Node->isObjectReceiver() && Node->getBase()) {
1425 PrintExpr(Node->getBase());
1426 OS << ".";
1427 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1428 OS << Node->getClassReceiver()->getName() << ".";
1429 }
1430
1431 if (Node->isImplicitProperty()) {
1432 if (const auto *Getter = Node->getImplicitPropertyGetter())
1433 Getter->getSelector().print(OS);
1434 else
1437 } else
1438 OS << Node->getExplicitProperty()->getName();
1439}
1440
1441void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1442 PrintExpr(Node->getBaseExpr());
1443 OS << "[";
1444 PrintExpr(Node->getKeyExpr());
1445 OS << "]";
1446}
1447
1448void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1449 SYCLUniqueStableNameExpr *Node) {
1450 OS << "__builtin_sycl_unique_stable_name(";
1451 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1452 OS << ")";
1453}
1454
1455void StmtPrinter::VisitUnresolvedSYCLKernelCallStmt(
1456 UnresolvedSYCLKernelCallStmt *Node) {
1457 PrintStmt(Node->getOriginalStmt());
1458}
1459
1460void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1462}
1463
1464void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {
1465 OS << '*';
1466}
1467
1468void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1469 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1470}
1471
1472/// Prints the given expression using the original source text. Returns true on
1473/// success, false otherwise.
1474static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1475 const ASTContext *Context) {
1476 if (!Context)
1477 return false;
1478 bool Invalid = false;
1479 StringRef Source = Lexer::getSourceText(
1481 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1482 if (!Invalid) {
1483 OS << Source;
1484 return true;
1485 }
1486 return false;
1487}
1488
1489void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1490 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1491 return;
1492 bool isSigned = Node->getType()->isSignedIntegerType();
1493 OS << toString(Node->getValue(), 10, isSigned);
1494
1495 if (isa<BitIntType>(Node->getType())) {
1496 OS << (isSigned ? "wb" : "uwb");
1497 return;
1498 }
1499
1500 // Emit suffixes. Integer literals are always a builtin integer type.
1501 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1502 default: llvm_unreachable("Unexpected type for integer literal!");
1503 case BuiltinType::Char_S:
1504 case BuiltinType::Char_U: OS << "i8"; break;
1505 case BuiltinType::UChar: OS << "Ui8"; break;
1506 case BuiltinType::SChar: OS << "i8"; break;
1507 case BuiltinType::Short: OS << "i16"; break;
1508 case BuiltinType::UShort: OS << "Ui16"; break;
1509 case BuiltinType::Int: break; // no suffix.
1510 case BuiltinType::UInt: OS << 'U'; break;
1511 case BuiltinType::Long: OS << 'L'; break;
1512 case BuiltinType::ULong: OS << "UL"; break;
1513 case BuiltinType::LongLong: OS << "LL"; break;
1514 case BuiltinType::ULongLong: OS << "ULL"; break;
1515 case BuiltinType::Int128:
1516 break; // no suffix.
1517 case BuiltinType::UInt128:
1518 break; // no suffix.
1519 case BuiltinType::WChar_S:
1520 case BuiltinType::WChar_U:
1521 break; // no suffix
1522 }
1523}
1524
1525void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1526 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1527 return;
1528 OS << Node->getValueAsString(/*Radix=*/10);
1529
1530 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1531 default: llvm_unreachable("Unexpected type for fixed point literal!");
1532 case BuiltinType::ShortFract: OS << "hr"; break;
1533 case BuiltinType::ShortAccum: OS << "hk"; break;
1534 case BuiltinType::UShortFract: OS << "uhr"; break;
1535 case BuiltinType::UShortAccum: OS << "uhk"; break;
1536 case BuiltinType::Fract: OS << "r"; break;
1537 case BuiltinType::Accum: OS << "k"; break;
1538 case BuiltinType::UFract: OS << "ur"; break;
1539 case BuiltinType::UAccum: OS << "uk"; break;
1540 case BuiltinType::LongFract: OS << "lr"; break;
1541 case BuiltinType::LongAccum: OS << "lk"; break;
1542 case BuiltinType::ULongFract: OS << "ulr"; break;
1543 case BuiltinType::ULongAccum: OS << "ulk"; break;
1544 }
1545}
1546
1547static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1548 bool PrintSuffix) {
1549 SmallString<16> Str;
1550 Node->getValue().toString(Str);
1551 OS << Str;
1552 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1553 OS << '.'; // Trailing dot in order to separate from ints.
1554
1555 if (!PrintSuffix)
1556 return;
1557
1558 // Emit suffixes. Float literals are always a builtin float type.
1559 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1560 default: llvm_unreachable("Unexpected type for float literal!");
1561 case BuiltinType::Half: break; // FIXME: suffix?
1562 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1563 case BuiltinType::Double: break; // no suffix.
1564 case BuiltinType::Float16: OS << "F16"; break;
1565 case BuiltinType::Float: OS << 'F'; break;
1566 case BuiltinType::LongDouble: OS << 'L'; break;
1567 case BuiltinType::Float128: OS << 'Q'; break;
1568 }
1569}
1570
1571void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1572 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1573 return;
1574 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1575}
1576
1577void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1578 PrintExpr(Node->getSubExpr());
1579 OS << "i";
1580}
1581
1582void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1583 Str->outputString(OS);
1584}
1585
1586void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1587 OS << "(";
1588 PrintExpr(Node->getSubExpr());
1589 OS << ")";
1590}
1591
1592void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1593 if (!Node->isPostfix()) {
1595
1596 // Print a space if this is an "identifier operator" like __real, or if
1597 // it might be concatenated incorrectly like '+'.
1598 switch (Node->getOpcode()) {
1599 default: break;
1600 case UO_Real:
1601 case UO_Imag:
1602 case UO_Extension:
1603 OS << ' ';
1604 break;
1605 case UO_Plus:
1606 case UO_Minus:
1607 if (isa<UnaryOperator>(Node->getSubExpr()))
1608 OS << ' ';
1609 break;
1610 }
1611 }
1612 PrintExpr(Node->getSubExpr());
1613
1614 if (Node->isPostfix())
1616}
1617
1618void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1619 OS << "__builtin_offsetof(";
1620 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1621 OS << ", ";
1622 bool PrintedSomething = false;
1623 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1624 OffsetOfNode ON = Node->getComponent(i);
1625 if (ON.getKind() == OffsetOfNode::Array) {
1626 // Array node
1627 OS << "[";
1628 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1629 OS << "]";
1630 PrintedSomething = true;
1631 continue;
1632 }
1633
1634 // Skip implicit base indirections.
1635 if (ON.getKind() == OffsetOfNode::Base)
1636 continue;
1637
1638 // Field or identifier node.
1639 const IdentifierInfo *Id = ON.getFieldName();
1640 if (!Id)
1641 continue;
1642
1643 if (PrintedSomething)
1644 OS << ".";
1645 else
1646 PrintedSomething = true;
1647 OS << Id->getName();
1648 }
1649 OS << ")";
1650}
1651
1652void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1653 UnaryExprOrTypeTraitExpr *Node) {
1654 const char *Spelling = getTraitSpelling(Node->getKind());
1655 if (Node->getKind() == UETT_AlignOf) {
1656 if (Policy.Alignof)
1657 Spelling = "alignof";
1658 else if (Policy.UnderscoreAlignof)
1659 Spelling = "_Alignof";
1660 else
1661 Spelling = "__alignof";
1662 }
1663
1664 OS << Spelling;
1665
1666 if (Node->isArgumentType()) {
1667 OS << '(';
1668 Node->getArgumentType().print(OS, Policy);
1669 OS << ')';
1670 } else {
1671 OS << " ";
1672 PrintExpr(Node->getArgumentExpr());
1673 }
1674}
1675
1676void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1677 OS << "_Generic(";
1678 if (Node->isExprPredicate())
1679 PrintExpr(Node->getControllingExpr());
1680 else
1681 Node->getControllingType()->getType().print(OS, Policy);
1682
1683 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1684 OS << ", ";
1685 QualType T = Assoc.getType();
1686 if (T.isNull())
1687 OS << "default";
1688 else
1689 T.print(OS, Policy);
1690 OS << ": ";
1691 PrintExpr(Assoc.getAssociationExpr());
1692 }
1693 OS << ")";
1694}
1695
1696void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1697 PrintExpr(Node->getLHS());
1698 OS << "[";
1699 PrintExpr(Node->getRHS());
1700 OS << "]";
1701}
1702
1703void StmtPrinter::VisitMatrixSingleSubscriptExpr(
1704 MatrixSingleSubscriptExpr *Node) {
1705 PrintExpr(Node->getBase());
1706 OS << "[";
1707 PrintExpr(Node->getRowIdx());
1708 OS << "]";
1709}
1710
1711void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1712 PrintExpr(Node->getBase());
1713 OS << "[";
1714 PrintExpr(Node->getRowIdx());
1715 OS << "]";
1716 OS << "[";
1717 PrintExpr(Node->getColumnIdx());
1718 OS << "]";
1719}
1720
1721void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1722 PrintExpr(Node->getBase());
1723 OS << "[";
1724 if (Node->getLowerBound())
1725 PrintExpr(Node->getLowerBound());
1726 if (Node->getColonLocFirst().isValid()) {
1727 OS << ":";
1728 if (Node->getLength())
1729 PrintExpr(Node->getLength());
1730 }
1731 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1732 OS << ":";
1733 if (Node->getStride())
1734 PrintExpr(Node->getStride());
1735 }
1736 OS << "]";
1737}
1738
1739void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1740 OS << "(";
1741 for (Expr *E : Node->getDimensions()) {
1742 OS << "[";
1743 PrintExpr(E);
1744 OS << "]";
1745 }
1746 OS << ")";
1747 PrintExpr(Node->getBase());
1748}
1749
1750void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1751 OS << "iterator(";
1752 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1753 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1754 VD->getType().print(OS, Policy);
1755 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1756 OS << " " << VD->getName() << " = ";
1757 PrintExpr(Range.Begin);
1758 OS << ":";
1759 PrintExpr(Range.End);
1760 if (Range.Step) {
1761 OS << ":";
1762 PrintExpr(Range.Step);
1763 }
1764 if (I < E - 1)
1765 OS << ", ";
1766 }
1767 OS << ")";
1768}
1769
1770void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1771 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1772 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1773 // Don't print any defaulted arguments
1774 break;
1775 }
1776
1777 if (i) OS << ", ";
1778 PrintExpr(Call->getArg(i));
1779 }
1780}
1781
1782void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1783 PrintExpr(Call->getCallee());
1784 OS << "(";
1785 PrintCallArgs(Call);
1786 OS << ")";
1787}
1788
1789static bool isImplicitThis(const Expr *E) {
1790 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1791 return TE->isImplicit();
1792 return false;
1793}
1794
1795void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1796 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1797 PrintExpr(Node->getBase());
1798
1799 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1800 FieldDecl *ParentDecl =
1801 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1802 : nullptr;
1803
1804 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1805 OS << (Node->isArrow() ? "->" : ".");
1806 }
1807
1808 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1809 if (FD->isAnonymousStructOrUnion())
1810 return;
1811
1812 Node->getQualifier().print(OS, Policy);
1813 if (Node->hasTemplateKeyword())
1814 OS << "template ";
1815 OS << Node->getMemberNameInfo();
1816 const TemplateParameterList *TPL = nullptr;
1817 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1818 if (!Node->hadMultipleCandidates())
1819 if (auto *FTD = FD->getPrimaryTemplate())
1820 TPL = FTD->getTemplateParameters();
1821 } else if (auto *VTSD =
1822 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1823 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1824 if (Node->hasExplicitTemplateArgs())
1825 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1826}
1827
1828void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1829 PrintExpr(Node->getBase());
1830 OS << (Node->isArrow() ? "->isa" : ".isa");
1831}
1832
1833void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1834 PrintExpr(Node->getBase());
1835 OS << ".";
1836 OS << Node->getAccessor().getName();
1837}
1838
1839void StmtPrinter::VisitMatrixElementExpr(MatrixElementExpr *Node) {
1840 PrintExpr(Node->getBase());
1841 OS << ".";
1842 OS << Node->getAccessor().getName();
1843}
1844
1845void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1846 OS << '(';
1847 Node->getTypeAsWritten().print(OS, Policy);
1848 OS << ')';
1849 PrintExpr(Node->getSubExpr());
1850}
1851
1852void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1853 OS << '(';
1854 Node->getType().print(OS, Policy);
1855 OS << ')';
1856 PrintExpr(Node->getInitializer());
1857}
1858
1859void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1860 // No need to print anything, simply forward to the subexpression.
1861 PrintExpr(Node->getSubExpr());
1862}
1863
1864void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1865 PrintExpr(Node->getLHS());
1866 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1867 PrintExpr(Node->getRHS());
1868}
1869
1870void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1871 PrintExpr(Node->getLHS());
1872 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1873 PrintExpr(Node->getRHS());
1874}
1875
1876void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1877 PrintExpr(Node->getCond());
1878 OS << " ? ";
1879 PrintExpr(Node->getLHS());
1880 OS << " : ";
1881 PrintExpr(Node->getRHS());
1882}
1883
1884// GNU extensions.
1885
1886void
1887StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1888 PrintExpr(Node->getCommon());
1889 OS << " ?: ";
1890 PrintExpr(Node->getFalseExpr());
1891}
1892
1893void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1894 OS << "&&" << Node->getLabel()->getName();
1895}
1896
1897void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1898 OS << "(";
1899 PrintRawCompoundStmt(E->getSubStmt());
1900 OS << ")";
1901}
1902
1903void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1904 OS << "__builtin_choose_expr(";
1905 PrintExpr(Node->getCond());
1906 OS << ", ";
1907 PrintExpr(Node->getLHS());
1908 OS << ", ";
1909 PrintExpr(Node->getRHS());
1910 OS << ")";
1911}
1912
1913void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1914 OS << "__null";
1915}
1916
1917void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1918 OS << "__builtin_shufflevector(";
1919 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1920 if (i) OS << ", ";
1921 PrintExpr(Node->getExpr(i));
1922 }
1923 OS << ")";
1924}
1925
1926void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1927 OS << "__builtin_convertvector(";
1928 PrintExpr(Node->getSrcExpr());
1929 OS << ", ";
1930 Node->getType().print(OS, Policy);
1931 OS << ")";
1932}
1933
1934void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1935 if (Node->getSyntacticForm()) {
1936 Visit(Node->getSyntacticForm());
1937 return;
1938 }
1939
1940 OS << "{";
1941 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1942 if (i) OS << ", ";
1943 if (Node->getInit(i))
1944 PrintExpr(Node->getInit(i));
1945 else
1946 OS << "{}";
1947 }
1948 OS << "}";
1949}
1950
1951void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1952 // There's no way to express this expression in any of our supported
1953 // languages, so just emit something terse and (hopefully) clear.
1954 OS << "{";
1955 PrintExpr(Node->getSubExpr());
1956 OS << "}";
1957}
1958
1959void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1960 OS << "*";
1961}
1962
1963void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1964 OS << "(";
1965 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1966 if (i) OS << ", ";
1967 PrintExpr(Node->getExpr(i));
1968 }
1969 OS << ")";
1970}
1971
1972void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1973 bool NeedsEquals = true;
1974 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1975 if (D.isFieldDesignator()) {
1976 if (D.getDotLoc().isInvalid()) {
1977 if (const IdentifierInfo *II = D.getFieldName()) {
1978 OS << II->getName() << ":";
1979 NeedsEquals = false;
1980 }
1981 } else {
1982 OS << "." << D.getFieldName()->getName();
1983 }
1984 } else {
1985 OS << "[";
1986 if (D.isArrayDesignator()) {
1987 PrintExpr(Node->getArrayIndex(D));
1988 } else {
1989 PrintExpr(Node->getArrayRangeStart(D));
1990 OS << " ... ";
1991 PrintExpr(Node->getArrayRangeEnd(D));
1992 }
1993 OS << "]";
1994 }
1995 }
1996
1997 if (NeedsEquals)
1998 OS << " = ";
1999 else
2000 OS << " ";
2001 PrintExpr(Node->getInit());
2002}
2003
2004void StmtPrinter::VisitDesignatedInitUpdateExpr(
2005 DesignatedInitUpdateExpr *Node) {
2006 OS << "{";
2007 OS << "/*base*/";
2008 PrintExpr(Node->getBase());
2009 OS << ", ";
2010
2011 OS << "/*updater*/";
2012 PrintExpr(Node->getUpdater());
2013 OS << "}";
2014}
2015
2016void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
2017 OS << "/*no init*/";
2018}
2019
2020void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
2021 if (Node->getType()->getAsCXXRecordDecl()) {
2022 OS << "/*implicit*/";
2023 Node->getType().print(OS, Policy);
2024 OS << "()";
2025 } else {
2026 OS << "/*implicit*/(";
2027 Node->getType().print(OS, Policy);
2028 OS << ')';
2029 if (Node->getType()->isRecordType())
2030 OS << "{}";
2031 else
2032 OS << 0;
2033 }
2034}
2035
2036void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
2037 OS << "__builtin_va_arg(";
2038 PrintExpr(Node->getSubExpr());
2039 OS << ", ";
2040 Node->getType().print(OS, Policy);
2041 OS << ")";
2042}
2043
2044void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
2045 PrintExpr(Node->getSyntacticForm());
2046}
2047
2048void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
2049 const char *Name = nullptr;
2050 switch (Node->getOp()) {
2051#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2052 case AtomicExpr::AO ## ID: \
2053 Name = #ID "("; \
2054 break;
2055#include "clang/Basic/Builtins.inc"
2056 }
2057 OS << Name;
2058
2059 // AtomicExpr stores its subexpressions in a permuted order.
2060 PrintExpr(Node->getPtr());
2061 if (Node->hasVal1Operand()) {
2062 OS << ", ";
2063 PrintExpr(Node->getVal1());
2064 }
2065 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
2066 Node->isCmpXChg()) {
2067 OS << ", ";
2068 PrintExpr(Node->getVal2());
2069 }
2070 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
2071 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
2072 OS << ", ";
2073 PrintExpr(Node->getWeak());
2074 }
2075 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
2076 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
2077 OS << ", ";
2078 PrintExpr(Node->getOrder());
2079 }
2080 if (Node->isCmpXChg()) {
2081 OS << ", ";
2082 PrintExpr(Node->getOrderFail());
2083 }
2084 OS << ")";
2085}
2086
2087// C++
2088void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
2090 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
2091 if (Node->getNumArgs() == 1) {
2092 OS << getOperatorSpelling(Kind) << ' ';
2093 PrintExpr(Node->getArg(0));
2094 } else {
2095 PrintExpr(Node->getArg(0));
2096 OS << ' ' << getOperatorSpelling(Kind);
2097 }
2098 } else if (Kind == OO_Arrow) {
2099 PrintExpr(Node->getArg(0));
2100 } else if (Kind == OO_Call || Kind == OO_Subscript) {
2101 PrintExpr(Node->getArg(0));
2102 OS << (Kind == OO_Call ? '(' : '[');
2103 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
2104 if (ArgIdx > 1)
2105 OS << ", ";
2106 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
2107 PrintExpr(Node->getArg(ArgIdx));
2108 }
2109 OS << (Kind == OO_Call ? ')' : ']');
2110 } else if (Node->getNumArgs() == 1) {
2111 OS << getOperatorSpelling(Kind) << ' ';
2112 PrintExpr(Node->getArg(0));
2113 } else if (Node->getNumArgs() == 2) {
2114 PrintExpr(Node->getArg(0));
2115 OS << ' ' << getOperatorSpelling(Kind) << ' ';
2116 PrintExpr(Node->getArg(1));
2117 } else {
2118 llvm_unreachable("unknown overloaded operator");
2119 }
2120}
2121
2122void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2123 // If we have a conversion operator call only print the argument.
2124 CXXMethodDecl *MD = Node->getMethodDecl();
2125 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2126 PrintExpr(Node->getImplicitObjectArgument());
2127 return;
2128 }
2129 VisitCallExpr(cast<CallExpr>(Node));
2130}
2131
2132void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2133 PrintExpr(Node->getCallee());
2134 OS << "<<<";
2135 PrintCallArgs(Node->getConfig());
2136 OS << ">>>(";
2137 PrintCallArgs(Node);
2138 OS << ")";
2139}
2140
2141void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2142 CXXRewrittenBinaryOperator *Node) {
2143 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
2144 Node->getDecomposedForm();
2145 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
2146 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
2147 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
2148}
2149
2150void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2151 OS << Node->getCastName() << '<';
2152 Node->getTypeAsWritten().print(OS, Policy);
2153 OS << ">(";
2154 PrintExpr(Node->getSubExpr());
2155 OS << ")";
2156}
2157
2158void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2159 VisitCXXNamedCastExpr(Node);
2160}
2161
2162void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2163 VisitCXXNamedCastExpr(Node);
2164}
2165
2166void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2167 VisitCXXNamedCastExpr(Node);
2168}
2169
2170void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2171 VisitCXXNamedCastExpr(Node);
2172}
2173
2174void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2175 OS << "__builtin_bit_cast(";
2176 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2177 OS << ", ";
2178 PrintExpr(Node->getSubExpr());
2179 OS << ")";
2180}
2181
2182void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2183 VisitCXXNamedCastExpr(Node);
2184}
2185
2186void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2187 OS << "typeid(";
2188 if (Node->isTypeOperand()) {
2189 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2190 } else {
2191 PrintExpr(Node->getExprOperand());
2192 }
2193 OS << ")";
2194}
2195
2196void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2197 OS << "__uuidof(";
2198 if (Node->isTypeOperand()) {
2199 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2200 } else {
2201 PrintExpr(Node->getExprOperand());
2202 }
2203 OS << ")";
2204}
2205
2206void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2207 PrintExpr(Node->getBaseExpr());
2208 if (Node->isArrow())
2209 OS << "->";
2210 else
2211 OS << ".";
2212 Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);
2213 OS << Node->getPropertyDecl()->getDeclName();
2214}
2215
2216void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2217 PrintExpr(Node->getBase());
2218 OS << "[";
2219 PrintExpr(Node->getIdx());
2220 OS << "]";
2221}
2222
2223void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2224 switch (Node->getLiteralOperatorKind()) {
2226 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2227 break;
2229 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2230 const TemplateArgumentList *Args =
2231 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2232 assert(Args);
2233
2234 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2235 const TemplateParameterList *TPL = nullptr;
2236 if (!DRE->hadMultipleCandidates())
2237 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2238 TPL = TD->getTemplateParameters();
2239 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2240 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2241 OS << "()";
2242 return;
2243 }
2244
2245 const TemplateArgument &Pack = Args->get(0);
2246 for (const auto &P : Pack.pack_elements()) {
2247 char C = (char)P.getAsIntegral().getZExtValue();
2248 OS << C;
2249 }
2250 break;
2251 }
2253 // Print integer literal without suffix.
2254 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2255 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2256 break;
2257 }
2259 // Print floating literal without suffix.
2261 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2262 break;
2263 }
2266 PrintExpr(Node->getCookedLiteral());
2267 break;
2268 }
2269 OS << Node->getUDSuffix()->getName();
2270}
2271
2272void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2273 OS << (Node->getValue() ? "true" : "false");
2274}
2275
2276void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2277 OS << "nullptr";
2278}
2279
2280void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2281 OS << "this";
2282}
2283
2284void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2285 if (!Node->getSubExpr())
2286 OS << "throw";
2287 else {
2288 OS << "throw ";
2289 PrintExpr(Node->getSubExpr());
2290 }
2291}
2292
2293void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2294 // Nothing to print: we picked up the default argument.
2295}
2296
2297void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2298 // Nothing to print: we picked up the default initializer.
2299}
2300
2301void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2302 auto TargetType = Node->getType();
2303 auto *Auto = TargetType->getContainedDeducedType();
2304 bool Bare = Auto && Auto->isDeduced();
2305
2306 // Parenthesize deduced casts.
2307 if (Bare)
2308 OS << '(';
2309 TargetType.print(OS, Policy);
2310 if (Bare)
2311 OS << ')';
2312
2313 // No extra braces surrounding the inner construct.
2314 if (!Node->isListInitialization())
2315 OS << '(';
2316 PrintExpr(Node->getSubExpr());
2317 if (!Node->isListInitialization())
2318 OS << ')';
2319}
2320
2321void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2322 PrintExpr(Node->getSubExpr());
2323}
2324
2325void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2326 Node->getType().print(OS, Policy);
2327 if (Node->isStdInitListInitialization())
2328 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2329 else if (Node->isListInitialization())
2330 OS << "{";
2331 else
2332 OS << "(";
2333 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2334 ArgEnd = Node->arg_end();
2335 Arg != ArgEnd; ++Arg) {
2336 if ((*Arg)->isDefaultArgument())
2337 break;
2338 if (Arg != Node->arg_begin())
2339 OS << ", ";
2340 PrintExpr(*Arg);
2341 }
2342 if (Node->isStdInitListInitialization())
2343 /* See above. */;
2344 else if (Node->isListInitialization())
2345 OS << "}";
2346 else
2347 OS << ")";
2348}
2349
2350void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2351 OS << '[';
2352 bool NeedComma = false;
2353 switch (Node->getCaptureDefault()) {
2354 case LCD_None:
2355 break;
2356
2357 case LCD_ByCopy:
2358 OS << '=';
2359 NeedComma = true;
2360 break;
2361
2362 case LCD_ByRef:
2363 OS << '&';
2364 NeedComma = true;
2365 break;
2366 }
2368 CEnd = Node->explicit_capture_end();
2369 C != CEnd;
2370 ++C) {
2371 if (C->capturesVLAType())
2372 continue;
2373
2374 if (NeedComma)
2375 OS << ", ";
2376 NeedComma = true;
2377
2378 switch (C->getCaptureKind()) {
2379 case LCK_This:
2380 OS << "this";
2381 break;
2382
2383 case LCK_StarThis:
2384 OS << "*this";
2385 break;
2386
2387 case LCK_ByRef:
2388 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2389 OS << '&';
2390 OS << C->getCapturedVar()->getName();
2391 break;
2392
2393 case LCK_ByCopy:
2394 OS << C->getCapturedVar()->getName();
2395 break;
2396
2397 case LCK_VLAType:
2398 llvm_unreachable("VLA type in explicit captures.");
2399 }
2400
2401 if (C->isPackExpansion())
2402 OS << "...";
2403
2404 if (Node->isInitCapture(C)) {
2405 // Init captures are always VarDecl.
2406 auto *D = cast<VarDecl>(C->getCapturedVar());
2407
2408 llvm::StringRef Pre;
2409 llvm::StringRef Post;
2410 if (D->getInitStyle() == VarDecl::CallInit &&
2411 !isa<ParenListExpr>(D->getInit())) {
2412 Pre = "(";
2413 Post = ")";
2414 } else if (D->getInitStyle() == VarDecl::CInit) {
2415 Pre = " = ";
2416 }
2417
2418 OS << Pre;
2419 PrintExpr(D->getInit());
2420 OS << Post;
2421 }
2422 }
2423 OS << ']';
2424
2425 if (!Node->getExplicitTemplateParameters().empty()) {
2427 OS, Node->getLambdaClass()->getASTContext(),
2428 /*OmitTemplateKW*/true);
2429 }
2430
2431 if (Node->hasExplicitParameters()) {
2432 OS << '(';
2433 CXXMethodDecl *Method = Node->getCallOperator();
2434 NeedComma = false;
2435 for (const auto *P : Method->parameters()) {
2436 if (NeedComma) {
2437 OS << ", ";
2438 } else {
2439 NeedComma = true;
2440 }
2441 std::string ParamStr =
2442 (Policy.CleanUglifiedParameters && P->getIdentifier())
2443 ? P->getIdentifier()->deuglifiedName().str()
2444 : P->getNameAsString();
2445 P->getOriginalType().print(OS, Policy, ParamStr);
2446 }
2447 if (Method->isVariadic()) {
2448 if (NeedComma)
2449 OS << ", ";
2450 OS << "...";
2451 }
2452 OS << ')';
2453
2454 if (Node->isMutable())
2455 OS << " mutable";
2456
2457 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2458 Proto->printExceptionSpecification(OS, Policy);
2459
2460 // FIXME: Attributes
2461
2462 // Print the trailing return type if it was specified in the source.
2463 if (Node->hasExplicitResultType()) {
2464 OS << " -> ";
2465 Proto->getReturnType().print(OS, Policy);
2466 }
2467 }
2468
2469 // Print the body.
2470 OS << ' ';
2471 if (Policy.TerseOutput || Policy.SuppressLambdaBody)
2472 OS << "{}";
2473 else
2474 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2475}
2476
2477void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2478 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2479 TSInfo->getType().print(OS, Policy);
2480 else
2481 Node->getType().print(OS, Policy);
2482 OS << "()";
2483}
2484
2485void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2486 if (E->isGlobalNew())
2487 OS << "::";
2488 OS << "new ";
2489 unsigned NumPlace = E->getNumPlacementArgs();
2490 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2491 OS << "(";
2492 PrintExpr(E->getPlacementArg(0));
2493 for (unsigned i = 1; i < NumPlace; ++i) {
2495 break;
2496 OS << ", ";
2497 PrintExpr(E->getPlacementArg(i));
2498 }
2499 OS << ") ";
2500 }
2501 if (E->isParenTypeId())
2502 OS << "(";
2503 std::string TypeS;
2504 if (E->isArray()) {
2505 llvm::raw_string_ostream s(TypeS);
2506 s << '[';
2507 if (std::optional<Expr *> Size = E->getArraySize())
2508 (*Size)->printPretty(s, Helper, Policy);
2509 s << ']';
2510 }
2511 E->getAllocatedType().print(OS, Policy, TypeS);
2512 if (E->isParenTypeId())
2513 OS << ")";
2514
2516 if (InitStyle != CXXNewInitializationStyle::None) {
2517 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2519 if (Bare)
2520 OS << "(";
2521 PrintExpr(E->getInitializer());
2522 if (Bare)
2523 OS << ")";
2524 }
2525}
2526
2527void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2528 if (E->isGlobalDelete())
2529 OS << "::";
2530 OS << "delete ";
2531 if (E->isArrayForm())
2532 OS << "[] ";
2533 PrintExpr(E->getArgument());
2534}
2535
2536void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2537 PrintExpr(E->getBase());
2538 if (E->isArrow())
2539 OS << "->";
2540 else
2541 OS << '.';
2542 E->getQualifier().print(OS, Policy);
2543 OS << "~";
2544
2545 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2546 OS << II->getName();
2547 else
2548 E->getDestroyedType().print(OS, Policy);
2549}
2550
2551void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2553 OS << "{";
2554
2555 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2556 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2557 // Don't print any defaulted arguments
2558 break;
2559 }
2560
2561 if (i) OS << ", ";
2562 PrintExpr(E->getArg(i));
2563 }
2564
2566 OS << "}";
2567}
2568
2569void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2570 // Parens are printed by the surrounding context.
2571 OS << "<forwarded>";
2572}
2573
2574void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2575 PrintExpr(E->getSubExpr());
2576}
2577
2578void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2579 // Just forward to the subexpression.
2580 PrintExpr(E->getSubExpr());
2581}
2582
2583void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2584 CXXUnresolvedConstructExpr *Node) {
2585 Node->getTypeAsWritten().print(OS, Policy);
2586 if (!Node->isListInitialization())
2587 OS << '(';
2588 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2589 ++Arg) {
2590 if (Arg != Node->arg_begin())
2591 OS << ", ";
2592 PrintExpr(*Arg);
2593 }
2594 if (!Node->isListInitialization())
2595 OS << ')';
2596}
2597
2598void StmtPrinter::VisitCXXReflectExpr(CXXReflectExpr *S) {
2599 // TODO(Reflection): Implement this.
2600 assert(false && "not implemented yet");
2601}
2602
2603void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2604 CXXDependentScopeMemberExpr *Node) {
2605 if (!Node->isImplicitAccess()) {
2606 PrintExpr(Node->getBase());
2607 OS << (Node->isArrow() ? "->" : ".");
2608 }
2609 Node->getQualifier().print(OS, Policy);
2610 if (Node->hasTemplateKeyword())
2611 OS << "template ";
2612 OS << Node->getMemberNameInfo();
2613 if (Node->hasExplicitTemplateArgs())
2614 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2615}
2616
2617void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2618 if (!Node->isImplicitAccess()) {
2619 PrintExpr(Node->getBase());
2620 OS << (Node->isArrow() ? "->" : ".");
2621 }
2622 Node->getQualifier().print(OS, Policy);
2623 if (Node->hasTemplateKeyword())
2624 OS << "template ";
2625 OS << Node->getMemberNameInfo();
2626 if (Node->hasExplicitTemplateArgs())
2627 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2628}
2629
2630void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2631 OS << getTraitSpelling(E->getTrait()) << "(";
2632 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2633 if (I > 0)
2634 OS << ", ";
2635 E->getArg(I)->getType().print(OS, Policy);
2636 }
2637 OS << ")";
2638}
2639
2640void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2641 OS << getTraitSpelling(E->getTrait()) << '(';
2642 E->getQueriedType().print(OS, Policy);
2643 OS << ')';
2644}
2645
2646void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2647 OS << getTraitSpelling(E->getTrait()) << '(';
2648 PrintExpr(E->getQueriedExpression());
2649 OS << ')';
2650}
2651
2652void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2653 OS << "noexcept(";
2654 PrintExpr(E->getOperand());
2655 OS << ")";
2656}
2657
2658void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2659 PrintExpr(E->getPattern());
2660 OS << "...";
2661}
2662
2663void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2664 OS << "sizeof...(" << *E->getPack() << ")";
2665}
2666
2667void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2668 PrintExpr(E->getPackIdExpression());
2669 OS << "...[";
2670 PrintExpr(E->getIndexExpr());
2671 OS << "]";
2672}
2673
2674void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2675 SubstNonTypeTemplateParmPackExpr *Node) {
2676 OS << *Node->getParameterPack();
2677}
2678
2679void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2680 SubstNonTypeTemplateParmExpr *Node) {
2681 Visit(Node->getReplacement());
2682}
2683
2684void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2685 OS << *E->getParameterPack();
2686}
2687
2688void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2689 PrintExpr(Node->getSubExpr());
2690}
2691
2692void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2693 OS << "(";
2694 if (E->getLHS()) {
2695 PrintExpr(E->getLHS());
2696 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2697 }
2698 OS << "...";
2699 if (E->getRHS()) {
2700 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2701 PrintExpr(E->getRHS());
2702 }
2703 OS << ")";
2704}
2705
2706void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2707 llvm::interleaveComma(Node->getUserSpecifiedInitExprs(), OS,
2708 [&](Expr *E) { PrintExpr(E); });
2709}
2710
2711void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2712 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2713 NNS.getNestedNameSpecifier().print(OS, Policy);
2714 if (E->getTemplateKWLoc().isValid())
2715 OS << "template ";
2716 OS << E->getFoundDecl()->getName();
2717 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2718 Policy,
2720}
2721
2722void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2723 OS << "requires ";
2724 auto LocalParameters = E->getLocalParameters();
2725 if (!LocalParameters.empty()) {
2726 OS << "(";
2727 for (ParmVarDecl *LocalParam : LocalParameters) {
2728 PrintRawDecl(LocalParam);
2729 if (LocalParam != LocalParameters.back())
2730 OS << ", ";
2731 }
2732
2733 OS << ") ";
2734 }
2735 OS << "{ ";
2736 auto Requirements = E->getRequirements();
2737 for (concepts::Requirement *Req : Requirements) {
2738 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2739 if (TypeReq->isSubstitutionFailure())
2740 OS << "<<error-type>>";
2741 else
2742 TypeReq->getType()->getType().print(OS, Policy);
2743 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2744 if (ExprReq->isCompound())
2745 OS << "{ ";
2746 if (ExprReq->isExprSubstitutionFailure())
2747 OS << "<<error-expression>>";
2748 else
2749 PrintExpr(ExprReq->getExpr());
2750 if (ExprReq->isCompound()) {
2751 OS << " }";
2752 if (ExprReq->getNoexceptLoc().isValid())
2753 OS << " noexcept";
2754 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2755 if (!RetReq.isEmpty()) {
2756 OS << " -> ";
2757 if (RetReq.isSubstitutionFailure())
2758 OS << "<<error-type>>";
2759 else if (RetReq.isTypeConstraint())
2760 RetReq.getTypeConstraint()->print(OS, Policy);
2761 }
2762 }
2763 } else {
2764 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2765 OS << "requires ";
2766 if (NestedReq->hasInvalidConstraint())
2767 OS << "<<error-expression>>";
2768 else
2769 PrintExpr(NestedReq->getConstraintExpr());
2770 }
2771 OS << "; ";
2772 }
2773 OS << "}";
2774}
2775
2776// C++ Coroutines
2777
2778void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2779 Visit(S->getBody());
2780}
2781
2782void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2783 OS << "co_return";
2784 if (S->getOperand()) {
2785 OS << " ";
2786 Visit(S->getOperand());
2787 }
2788 OS << ";";
2789}
2790
2791void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2792 OS << "co_await ";
2793 PrintExpr(S->getOperand());
2794}
2795
2796void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2797 OS << "co_await ";
2798 PrintExpr(S->getOperand());
2799}
2800
2801void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2802 OS << "co_yield ";
2803 PrintExpr(S->getOperand());
2804}
2805
2806// Obj-C
2807
2808void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2809 OS << "@";
2810 VisitStringLiteral(Node->getString());
2811}
2812
2813void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2814 OS << "@";
2815 Visit(E->getSubExpr());
2816}
2817
2818void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2819 OS << "@[ ";
2820 ObjCArrayLiteral::child_range Ch = E->children();
2821 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2822 if (I != Ch.begin())
2823 OS << ", ";
2824 Visit(*I);
2825 }
2826 OS << " ]";
2827}
2828
2829void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2830 OS << "@{ ";
2831 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2832 if (I > 0)
2833 OS << ", ";
2834
2835 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2836 Visit(Element.Key);
2837 OS << " : ";
2838 Visit(Element.Value);
2839 if (Element.isPackExpansion())
2840 OS << "...";
2841 }
2842 OS << " }";
2843}
2844
2845void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2846 OS << "@encode(";
2847 Node->getEncodedType().print(OS, Policy);
2848 OS << ')';
2849}
2850
2851void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2852 OS << "@selector(";
2853 Node->getSelector().print(OS);
2854 OS << ')';
2855}
2856
2857void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2858 OS << "@protocol(" << *Node->getProtocol() << ')';
2859}
2860
2861void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2862 OS << "[";
2863 switch (Mess->getReceiverKind()) {
2865 PrintExpr(Mess->getInstanceReceiver());
2866 break;
2867
2869 Mess->getClassReceiver().print(OS, Policy);
2870 break;
2871
2874 OS << "Super";
2875 break;
2876 }
2877
2878 OS << ' ';
2879 Selector selector = Mess->getSelector();
2880 if (selector.isUnarySelector()) {
2881 OS << selector.getNameForSlot(0);
2882 } else {
2883 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2884 if (i < selector.getNumArgs()) {
2885 if (i > 0) OS << ' ';
2886 if (selector.getIdentifierInfoForSlot(i))
2887 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2888 else
2889 OS << ":";
2890 }
2891 else OS << ", "; // Handle variadic methods.
2892
2893 PrintExpr(Mess->getArg(i));
2894 }
2895 }
2896 OS << "]";
2897}
2898
2899void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2900 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2901}
2902
2903void
2904StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2905 PrintExpr(E->getSubExpr());
2906}
2907
2908void
2909StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2910 OS << '(' << E->getBridgeKindName();
2911 E->getType().print(OS, Policy);
2912 OS << ')';
2913 PrintExpr(E->getSubExpr());
2914}
2915
2916void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2917 BlockDecl *BD = Node->getBlockDecl();
2918 OS << "^";
2919
2920 const FunctionType *AFT = Node->getFunctionType();
2921
2922 if (isa<FunctionNoProtoType>(AFT)) {
2923 OS << "()";
2924 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2925 OS << '(';
2926 for (BlockDecl::param_iterator AI = BD->param_begin(),
2927 E = BD->param_end(); AI != E; ++AI) {
2928 if (AI != BD->param_begin()) OS << ", ";
2929 std::string ParamStr = (*AI)->getNameAsString();
2930 (*AI)->getType().print(OS, Policy, ParamStr);
2931 }
2932
2933 const auto *FT = cast<FunctionProtoType>(AFT);
2934 if (FT->isVariadic()) {
2935 if (!BD->param_empty()) OS << ", ";
2936 OS << "...";
2937 }
2938 OS << ')';
2939 }
2940 OS << "{ }";
2941}
2942
2943void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2944 PrintExpr(Node->getSourceExpr());
2945}
2946
2947void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2948 OS << "<recovery-expr>(";
2949 const char *Sep = "";
2950 for (Expr *E : Node->subExpressions()) {
2951 OS << Sep;
2952 PrintExpr(E);
2953 Sep = ", ";
2954 }
2955 OS << ')';
2956}
2957
2958void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2959 OS << "__builtin_astype(";
2960 PrintExpr(Node->getSrcExpr());
2961 OS << ", ";
2962 Node->getType().print(OS, Policy);
2963 OS << ")";
2964}
2965
2966void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
2967 PrintExpr(Node->getArgLValue());
2968}
2969
2970//===----------------------------------------------------------------------===//
2971// Stmt method implementations
2972//===----------------------------------------------------------------------===//
2973
2974void Stmt::dumpPretty(const ASTContext &Context) const {
2975 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2976}
2977
2978void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2979 const PrintingPolicy &Policy, unsigned Indentation,
2980 StringRef NL, const ASTContext *Context) const {
2981 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2982 P.Visit(const_cast<Stmt *>(this));
2983}
2984
2985void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2986 const PrintingPolicy &Policy,
2987 unsigned Indentation, StringRef NL,
2988 const ASTContext *Context) const {
2989 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2990 P.PrintControlledStmt(const_cast<Stmt *>(this));
2991}
2992
2993void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2994 const PrintingPolicy &Policy, bool AddQuotes) const {
2995 std::string Buf;
2996 llvm::raw_string_ostream TempOut(Buf);
2997
2998 printPretty(TempOut, Helper, Policy);
2999
3000 Out << JsonFormat(TempOut.str(), AddQuotes);
3001}
3002
3003//===----------------------------------------------------------------------===//
3004// PrinterHelper
3005//===----------------------------------------------------------------------===//
3006
3007// Implement virtual destructor.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenACC nodes for declarative directives.
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines enumerations for expression traits intrinsics.
unsigned IndentLevel
The indent level of this token. Copied from the surrounding line.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines several types used to describe C++ lambda expressions that are shared between the parser and ...
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
Defines an enumeration for C++ overloaded operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
const Stmt * getAssociatedStmt() const
OpenACCAtomicKind getAtomicKind() const
bool hasReadOnly() const
ArrayRef< Expr * > getVarList() const
Stmt * getStructuredBlock()
bool hasQueuesTag() const
ArrayRef< Expr * > getQueueIdExprs()
bool hasDevNumExpr() const
SourceLocation getLParenLoc() const
Expr * getDevNumExpr() const
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
const LangOptions & getLangOpts() const
Definition ASTContext.h:952
LabelDecl * getLabel() const
Definition Expr.h:4576
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition Expr.h:5991
Expr * getBase()
Get base of the array section.
Definition Expr.h:7296
Expr * getLength()
Get length of array section.
Definition Expr.h:7306
bool isOMPArraySection() const
Definition Expr.h:7292
Expr * getStride()
Get stride of array section.
Definition Expr.h:7310
SourceLocation getColonLocSecond() const
Definition Expr.h:7328
Expr * getLowerBound()
Get lower bound of array section.
Definition Expr.h:7300
SourceLocation getColonLocFirst() const
Definition Expr.h:7327
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2753
ArrayTypeTrait getTrait() const
Definition ExprCXX.h:3040
QualType getQueriedType() const
Definition ExprCXX.h:3044
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:6751
bool isVolatile() const
Definition Stmt.h:3319
unsigned getNumClobbers() const
Definition Stmt.h:3374
unsigned getNumOutputs() const
Definition Stmt.h:3342
unsigned getNumInputs() const
Definition Stmt.h:3364
Expr * getVal2() const
Definition Expr.h:6978
Expr * getOrder() const
Definition Expr.h:6961
bool isCmpXChg() const
Definition Expr.h:7011
AtomicOp getOp() const
Definition Expr.h:6990
Expr * getVal1() const
Definition Expr.h:6968
Expr * getPtr() const
Definition Expr.h:6958
Expr * getWeak() const
Definition Expr.h:6984
Expr * getOrderFail() const
Definition Expr.h:6974
bool hasVal1Operand() const
Definition Expr.h:7024
Stmt * getSubStmt()
Definition Stmt.h:2245
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2241
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
Definition Expr.h:4510
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
Definition Expr.h:4491
Expr * getLHS() const
Definition Expr.h:4091
StringRef getOpcodeStr() const
Definition Expr.h:4107
Expr * getRHS() const
Definition Expr.h:4093
Opcode getOpcode() const
Definition Expr.h:4086
param_iterator param_end()
Definition Decl.h:4788
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition Decl.h:4783
param_iterator param_begin()
Definition Decl.h:4787
bool param_empty() const
Definition Decl.h:4786
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Definition Expr.cpp:2532
const BlockDecl * getBlockDecl() const
Definition Expr.h:6683
This class is used for builtin types like 'int'.
Definition TypeBase.h:3214
Kind getKind() const
Definition TypeBase.h:3262
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:743
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition ExprCXX.cpp:724
const char * getCastName() const
getCastName - Get the name of the C++ cast being used, e.g., "static_cast", "dynamic_cast",...
Definition ExprCXX.cpp:770
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()
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:385
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:3150
Expr * getCallee()
Definition Expr.h:3093
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3137
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition Decl.cpp:5700
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition Stmt.cpp:1493
Stmt * getSubStmt()
Definition Stmt.h:2039
Expr * getLHS()
Definition Stmt.h:2009
Expr * getRHS()
Definition Stmt.h:2021
Expr * getSubExpr()
Definition Expr.h:3729
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1020
unsigned getValue() const
Definition Expr.h:1632
CharacterLiteralKind getKind() const
Definition Expr.h:1625
Expr * getLHS() const
Definition Expr.h:4893
Expr * getRHS() const
Definition Expr.h:4895
Expr * getCond() const
Definition Expr.h:4891
const Expr * getInitializer() const
Definition Expr.h:3636
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1746
FPOptionsOverride getStoredFPFeatures() const
Get FPOptionsOverride from trailing storage.
Definition Stmt.h:1796
body_range body()
Definition Stmt.h:1809
bool hasStoredFPFeatures() const
Definition Stmt.h:1793
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
NamedDecl * getFoundDecl() const
SourceLocation getTemplateKWLoc() const
ConceptDecl * getNamedConcept() const
Expr * getLHS() const
Definition Expr.h:4428
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4417
Expr * getRHS() const
Definition Expr.h:4429
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4812
Expr * getOperand() const
Retrieve the operand of the 'co_return' statement.
Definition StmtCXX.h:497
CompoundStmt * getBody() const
Retrieve the body of the coroutine as written.
Definition StmtCXX.h:380
Expr * getOperand() const
Definition ExprCXX.h:5324
bool hasExplicitTemplateArgs() const
Determines whether this declaration reference was followed by an explicit template argument list.
Definition Expr.h:1428
NestedNameSpecifier getQualifier() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name.
Definition Expr.h:1374
DeclarationNameInfo getNameInfo() const
Definition Expr.h:1345
ValueDecl * getDecl()
Definition Expr.h:1341
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition Expr.h:1454
bool hadMultipleCandidates() const
Returns true if this expression refers to a function that was resolved from an overloaded set having ...
Definition Expr.h:1460
bool hasTemplateKeyword() const
Determines whether the name in this declaration reference was preceded by the template keyword.
Definition Expr.h:1424
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition Stmt.h:1650
decl_range decls()
Definition Stmt.h:1685
const Decl * getSingleDecl() const
Definition Stmt.h:1652
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:2087
Stmt * getBody()
Definition Stmt.h:3261
Expr * getOperand() const
Definition ExprCXX.h:5424
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:4895
Expr * getArrayRangeStart(const Designator &D) const
Definition Expr.cpp:4890
MutableArrayRef< Designator > designators()
Definition Expr.h:5787
Expr * getArrayIndex(const Designator &D) const
Definition Expr.cpp:4885
Expr * getInit() const
Retrieve the initializer value.
Definition Expr.h:5822
InitListExpr * getUpdater() const
Definition Expr.h:5939
Stmt * getBody()
Definition Stmt.h:2863
Expr * getCond()
Definition Stmt.h:2856
IdentifierInfo & getAccessor() const
Definition Expr.h:6584
const Expr * getBase() const
Definition Expr.h:6580
StringRef getFileName() const
Definition Expr.h:5147
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition Expr.h:3953
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:3958
This represents one expression.
Definition Expr.h:112
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3070
QualType getType() const
Definition Expr.h:144
Expr * getQueriedExpression() const
Definition ExprCXX.h: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:4717
std::string getValueAsString(unsigned Radix) const
Definition Expr.cpp:1010
llvm::APFloat getValue() const
Definition Expr.h:1669
Stmt * getInit()
Definition Stmt.h:2909
Stmt * getBody()
Definition Stmt.h:2938
Expr * getInc()
Definition Stmt.h:2937
Expr * getCond()
Definition Stmt.h:2936
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Definition Stmt.h:2924
const Expr * getSubExpr() const
Definition Expr.h:1065
ValueDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition ExprCXX.h:4867
unsigned getNumLabels() const
Definition Stmt.h:3602
bool isAsmGoto() const
Definition Stmt.h:3598
const Expr * getOutputConstraintExpr(unsigned i) const
Definition Stmt.h:3554
StringRef getLabelName(unsigned i) const
Definition Stmt.cpp:605
StringRef getInputName(unsigned i) const
Definition Stmt.h:3571
StringRef getOutputName(unsigned i) const
Definition Stmt.h:3545
const Expr * getInputConstraintExpr(unsigned i) const
Definition Stmt.h:3580
const Expr * getAsmStringExpr() const
Definition Stmt.h:3479
Expr * getOutputExpr(unsigned i)
Definition Stmt.cpp:582
Expr * getClobberExpr(unsigned i)
Definition Stmt.h:3659
Expr * getInputExpr(unsigned i)
Definition Stmt.cpp:593
AssociationTy< false > Association
Definition Expr.h:6414
TypeSourceInfo * getControllingType()
Return the controlling type of this generic selection expression.
Definition Expr.h:6458
bool isExprPredicate() const
Whether this generic selection uses an expression as its controlling argument.
Definition Expr.h:6439
association_range associations()
Definition Expr.h:6514
Expr * getControllingExpr()
Return the controlling expression of this generic selection expression.
Definition Expr.h:6446
LabelDecl * getLabel() const
Definition Stmt.h:2988
const Expr * getArgLValue() const
Return the l-value expression that was written as the argument in source.
Definition Expr.h:7437
StringRef getName() const
Return the actual identifier string.
const Expr * getSubExpr() const
Definition Expr.h:1746
unsigned getNumInits() const
Definition Expr.h:5332
InitListExpr * getSyntacticForm() const
Definition Expr.h:5475
const Expr * getInit(unsigned Init) const
Definition Expr.h:5356
Stmt * getSubStmt()
Definition Stmt.h:2174
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:1430
bool isInitCapture(const LambdaCapture *Capture) const
Determine whether one of this lambda's captures is an init-capture.
Definition ExprCXX.cpp:1360
CXXMethodDecl * getCallOperator() const
Retrieve the function call operator associated with this lambda expression.
Definition ExprCXX.cpp:1406
const CompoundStmt * getCompoundStmtBody() const
Retrieve the CompoundStmt representing the body of the lambda.
Definition ExprCXX.cpp:1353
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:1416
ArrayRef< NamedDecl * > getExplicitTemplateParameters() const
Get the template parameters were explicitly specified (as opposed to being invented by use of an auto...
Definition ExprCXX.cpp:1421
capture_iterator explicit_capture_end() const
Retrieve an iterator pointing past the end of the sequence of explicit lambda captures.
Definition ExprCXX.cpp:1381
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:1377
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:1402
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:1052
LabelDecl * getLabelDecl()
Definition Stmt.h:3101
bool hasLabelTarget() const
Definition Stmt.h:3096
StringRef getAsmString() const
Definition Stmt.h:3705
bool hasBraces() const
Definition Stmt.h:3699
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:3539
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition Expr.h:3478
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3450
bool hasExplicitTemplateArgs() const
Determines whether the member name was followed by an explicit template argument list.
Definition Expr.h:3511
Expr * getBase() const
Definition Expr.h:3444
bool hadMultipleCandidates() const
Returns true if this member expression refers to a method that was resolved from an overloaded set ha...
Definition Expr.h:3571
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition Expr.h:3507
DeclarationNameInfo getMemberNameInfo() const
Retrieve the member declaration name info.
Definition Expr.h:3544
bool isArrow() const
Definition Expr.h:3551
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
Expr * getBase()
Fetches base expression of array shaping expression.
Definition ExprOpenMP.h:90
ArrayRef< Expr * > getDimensions() const
Fetches the dimensions for array shaping expression.
Definition ExprOpenMP.h:80
IteratorRange getIteratorRange(unsigned I)
Gets the iterator range for the given iterator.
Definition Expr.cpp:5553
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:5549
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:2589
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2577
TypeSourceInfo * getTypeSourceInfo() const
Definition Expr.h:2570
unsigned getNumComponents() const
Definition Expr.h:2585
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2482
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1688
@ Array
An index into an array.
Definition Expr.h:2429
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition Expr.h:2436
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2478
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1231
OpenACCDirectiveKind getDirectiveKind() const
Definition StmtOpenACC.h:57
ArrayRef< const OpenACCClause * > clauses() const
Definition StmtOpenACC.h:67
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition ExprCXX.h: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:2202
Expr * getExpr(unsigned Init)
Definition Expr.h:6115
unsigned getNumExprs() const
Return the number of expressions in this paren list.
Definition Expr.h:6113
StringRef getIdentKindName() const
Definition Expr.h:2065
PredefinedIdentKind getIdentKind() const
Definition Expr.h:2043
virtual ~PrinterHelper()
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition Expr.h:6840
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
ArrayRef< Expr * > subExpressions()
Definition Expr.h:7509
ArrayRef< concepts::Requirement * > getRequirements() const
ArrayRef< ParmVarDecl * > getLocalParameters() const
Expr * getRetValue()
Definition Stmt.h:3193
CompoundStmt * getBlock() const
Definition Stmt.h:3799
Expr * getFilterExpr() const
Definition Stmt.h:3795
CompoundStmt * getBlock() const
Definition Stmt.h:3836
CompoundStmt * getTryBlock() const
Definition Stmt.h:3880
bool getIsCXXTry() const
Definition Stmt.h:3878
SEHFinallyStmt * getFinallyHandler() const
Definition Stmt.cpp:1343
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition Stmt.cpp:1339
CompoundStmt * getOriginalStmt()
Definition StmtSYCL.h:54
TypeSourceInfo * getTypeSourceInfo()
Definition Expr.h:2146
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
bool isUnarySelector() const
unsigned getNumArgs() const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Definition Expr.h:4679
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4685
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition ExprCXX.h:4509
StringRef getBuiltinStr() const
Return a string representing the name of the specific builtin function.
Definition Expr.cpp:2262
bool isValid() const
Return true if this is a valid SourceLocation object.
CompoundStmt * getSubStmt()
Definition Expr.h:4615
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Stmt(StmtClass SC, EmptyShell)
Construct an empty statement.
Definition Stmt.h:1481
void dumpPretty(const ASTContext &Context) const
dumpPretty/printPretty - These two methods do a "pretty print" of the AST back to its original source...
void outputString(raw_ostream &OS) const
Definition Expr.cpp:1209
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Definition ExprCXX.cpp:1794
Expr * getCond()
Definition Stmt.h:2578
Stmt * getBody()
Definition Stmt.h:2590
Stmt * getInit()
Definition Stmt.h:2595
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition Stmt.h:2629
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:8413
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:2231
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:9328
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
Definition Type.cpp:2074
bool isRecordType() const
Definition TypeBase.h:8795
QualType getArgumentType() const
Definition Expr.h:2671
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2660
static bool isPostfix(Opcode Op)
isPostfix - Return true if this is a postfix operation, like x++.
Definition Expr.h:2317
Expr * getSubExpr() const
Definition Expr.h:2288
Opcode getOpcode() const
Definition Expr.h:2283
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition Expr.cpp:1406
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h: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:1647
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:1001
const IdentifierInfo * getUDSuffix() const
Returns the ud-suffix specified for this literal.
Definition ExprCXX.cpp:1030
Expr * getCookedLiteral()
If this is not a raw user-defined literal, get the underlying cooked literal (representing the litera...
Definition ExprCXX.cpp:1022
@ 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:4976
QualType getType() const
Definition Decl.h:723
@ CInit
C-style initialization with assignment.
Definition Decl.h:931
@ CallInit
Call-style initialization (C++98)
Definition Decl.h:934
Expr * getCond()
Definition Stmt.h:2755
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
Definition Stmt.h:2791
Stmt * getBody()
Definition Stmt.h:2767
@ 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:1743
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 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.