Thanks to visit codestin.com
Credit goes to clang.llvm.org

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