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::VisitOMPFuseDirective(OMPFuseDirective *Node) {
799 Indent() << "#pragma omp fuse";
800 PrintOMPExecutableDirective(Node);
801}
802
803void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
804 Indent() << "#pragma omp for";
805 PrintOMPExecutableDirective(Node);
806}
807
808void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
809 Indent() << "#pragma omp for simd";
810 PrintOMPExecutableDirective(Node);
811}
812
813void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
814 Indent() << "#pragma omp sections";
815 PrintOMPExecutableDirective(Node);
816}
817
818void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
819 Indent() << "#pragma omp section";
820 PrintOMPExecutableDirective(Node);
821}
822
823void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {
824 Indent() << "#pragma omp scope";
825 PrintOMPExecutableDirective(Node);
826}
827
828void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
829 Indent() << "#pragma omp single";
830 PrintOMPExecutableDirective(Node);
831}
832
833void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
834 Indent() << "#pragma omp master";
835 PrintOMPExecutableDirective(Node);
836}
837
838void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
839 Indent() << "#pragma omp critical";
840 if (Node->getDirectiveName().getName()) {
841 OS << " (";
842 Node->getDirectiveName().printName(OS, Policy);
843 OS << ")";
844 }
845 PrintOMPExecutableDirective(Node);
846}
847
848void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
849 Indent() << "#pragma omp parallel for";
850 PrintOMPExecutableDirective(Node);
851}
852
853void StmtPrinter::VisitOMPParallelForSimdDirective(
854 OMPParallelForSimdDirective *Node) {
855 Indent() << "#pragma omp parallel for simd";
856 PrintOMPExecutableDirective(Node);
857}
858
859void StmtPrinter::VisitOMPParallelMasterDirective(
860 OMPParallelMasterDirective *Node) {
861 Indent() << "#pragma omp parallel master";
862 PrintOMPExecutableDirective(Node);
863}
864
865void StmtPrinter::VisitOMPParallelMaskedDirective(
866 OMPParallelMaskedDirective *Node) {
867 Indent() << "#pragma omp parallel masked";
868 PrintOMPExecutableDirective(Node);
869}
870
871void StmtPrinter::VisitOMPParallelSectionsDirective(
872 OMPParallelSectionsDirective *Node) {
873 Indent() << "#pragma omp parallel sections";
874 PrintOMPExecutableDirective(Node);
875}
876
877void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
878 Indent() << "#pragma omp task";
879 PrintOMPExecutableDirective(Node);
880}
881
882void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
883 Indent() << "#pragma omp taskyield";
884 PrintOMPExecutableDirective(Node);
885}
886
887void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
888 Indent() << "#pragma omp barrier";
889 PrintOMPExecutableDirective(Node);
890}
891
892void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
893 Indent() << "#pragma omp taskwait";
894 PrintOMPExecutableDirective(Node);
895}
896
897void StmtPrinter::VisitOMPAssumeDirective(OMPAssumeDirective *Node) {
898 Indent() << "#pragma omp assume";
899 PrintOMPExecutableDirective(Node);
900}
901
902void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
903 Indent() << "#pragma omp error";
904 PrintOMPExecutableDirective(Node);
905}
906
907void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
908 Indent() << "#pragma omp taskgroup";
909 PrintOMPExecutableDirective(Node);
910}
911
912void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
913 Indent() << "#pragma omp flush";
914 PrintOMPExecutableDirective(Node);
915}
916
917void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
918 Indent() << "#pragma omp depobj";
919 PrintOMPExecutableDirective(Node);
920}
921
922void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
923 Indent() << "#pragma omp scan";
924 PrintOMPExecutableDirective(Node);
925}
926
927void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
928 Indent() << "#pragma omp ordered";
929 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
930}
931
932void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
933 Indent() << "#pragma omp atomic";
934 PrintOMPExecutableDirective(Node);
935}
936
937void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
938 Indent() << "#pragma omp target";
939 PrintOMPExecutableDirective(Node);
940}
941
942void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
943 Indent() << "#pragma omp target data";
944 PrintOMPExecutableDirective(Node);
945}
946
947void StmtPrinter::VisitOMPTargetEnterDataDirective(
948 OMPTargetEnterDataDirective *Node) {
949 Indent() << "#pragma omp target enter data";
950 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
951}
952
953void StmtPrinter::VisitOMPTargetExitDataDirective(
954 OMPTargetExitDataDirective *Node) {
955 Indent() << "#pragma omp target exit data";
956 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
957}
958
959void StmtPrinter::VisitOMPTargetParallelDirective(
960 OMPTargetParallelDirective *Node) {
961 Indent() << "#pragma omp target parallel";
962 PrintOMPExecutableDirective(Node);
963}
964
965void StmtPrinter::VisitOMPTargetParallelForDirective(
966 OMPTargetParallelForDirective *Node) {
967 Indent() << "#pragma omp target parallel for";
968 PrintOMPExecutableDirective(Node);
969}
970
971void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
972 Indent() << "#pragma omp teams";
973 PrintOMPExecutableDirective(Node);
974}
975
976void StmtPrinter::VisitOMPCancellationPointDirective(
977 OMPCancellationPointDirective *Node) {
978 unsigned OpenMPVersion =
979 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;
980 Indent() << "#pragma omp cancellation point "
981 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);
982 PrintOMPExecutableDirective(Node);
983}
984
985void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
986 unsigned OpenMPVersion =
987 Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion;
988 Indent() << "#pragma omp cancel "
989 << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion);
990 PrintOMPExecutableDirective(Node);
991}
992
993void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
994 Indent() << "#pragma omp taskloop";
995 PrintOMPExecutableDirective(Node);
996}
997
998void StmtPrinter::VisitOMPTaskLoopSimdDirective(
999 OMPTaskLoopSimdDirective *Node) {
1000 Indent() << "#pragma omp taskloop simd";
1001 PrintOMPExecutableDirective(Node);
1002}
1003
1004void StmtPrinter::VisitOMPMasterTaskLoopDirective(
1005 OMPMasterTaskLoopDirective *Node) {
1006 Indent() << "#pragma omp master taskloop";
1007 PrintOMPExecutableDirective(Node);
1008}
1009
1010void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
1011 OMPMaskedTaskLoopDirective *Node) {
1012 Indent() << "#pragma omp masked taskloop";
1013 PrintOMPExecutableDirective(Node);
1014}
1015
1016void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
1017 OMPMasterTaskLoopSimdDirective *Node) {
1018 Indent() << "#pragma omp master taskloop simd";
1019 PrintOMPExecutableDirective(Node);
1020}
1021
1022void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
1023 OMPMaskedTaskLoopSimdDirective *Node) {
1024 Indent() << "#pragma omp masked taskloop simd";
1025 PrintOMPExecutableDirective(Node);
1026}
1027
1028void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
1029 OMPParallelMasterTaskLoopDirective *Node) {
1030 Indent() << "#pragma omp parallel master taskloop";
1031 PrintOMPExecutableDirective(Node);
1032}
1033
1034void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
1035 OMPParallelMaskedTaskLoopDirective *Node) {
1036 Indent() << "#pragma omp parallel masked taskloop";
1037 PrintOMPExecutableDirective(Node);
1038}
1039
1040void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
1041 OMPParallelMasterTaskLoopSimdDirective *Node) {
1042 Indent() << "#pragma omp parallel master taskloop simd";
1043 PrintOMPExecutableDirective(Node);
1044}
1045
1046void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
1047 OMPParallelMaskedTaskLoopSimdDirective *Node) {
1048 Indent() << "#pragma omp parallel masked taskloop simd";
1049 PrintOMPExecutableDirective(Node);
1050}
1051
1052void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1053 Indent() << "#pragma omp distribute";
1054 PrintOMPExecutableDirective(Node);
1055}
1056
1057void StmtPrinter::VisitOMPTargetUpdateDirective(
1058 OMPTargetUpdateDirective *Node) {
1059 Indent() << "#pragma omp target update";
1060 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1061}
1062
1063void StmtPrinter::VisitOMPDistributeParallelForDirective(
1064 OMPDistributeParallelForDirective *Node) {
1065 Indent() << "#pragma omp distribute parallel for";
1066 PrintOMPExecutableDirective(Node);
1067}
1068
1069void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1070 OMPDistributeParallelForSimdDirective *Node) {
1071 Indent() << "#pragma omp distribute parallel for simd";
1072 PrintOMPExecutableDirective(Node);
1073}
1074
1075void StmtPrinter::VisitOMPDistributeSimdDirective(
1076 OMPDistributeSimdDirective *Node) {
1077 Indent() << "#pragma omp distribute simd";
1078 PrintOMPExecutableDirective(Node);
1079}
1080
1081void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1082 OMPTargetParallelForSimdDirective *Node) {
1083 Indent() << "#pragma omp target parallel for simd";
1084 PrintOMPExecutableDirective(Node);
1085}
1086
1087void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1088 Indent() << "#pragma omp target simd";
1089 PrintOMPExecutableDirective(Node);
1090}
1091
1092void StmtPrinter::VisitOMPTeamsDistributeDirective(
1093 OMPTeamsDistributeDirective *Node) {
1094 Indent() << "#pragma omp teams distribute";
1095 PrintOMPExecutableDirective(Node);
1096}
1097
1098void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1099 OMPTeamsDistributeSimdDirective *Node) {
1100 Indent() << "#pragma omp teams distribute simd";
1101 PrintOMPExecutableDirective(Node);
1102}
1103
1104void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1105 OMPTeamsDistributeParallelForSimdDirective *Node) {
1106 Indent() << "#pragma omp teams distribute parallel for simd";
1107 PrintOMPExecutableDirective(Node);
1108}
1109
1110void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1111 OMPTeamsDistributeParallelForDirective *Node) {
1112 Indent() << "#pragma omp teams distribute parallel for";
1113 PrintOMPExecutableDirective(Node);
1114}
1115
1116void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1117 Indent() << "#pragma omp target teams";
1118 PrintOMPExecutableDirective(Node);
1119}
1120
1121void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1122 OMPTargetTeamsDistributeDirective *Node) {
1123 Indent() << "#pragma omp target teams distribute";
1124 PrintOMPExecutableDirective(Node);
1125}
1126
1127void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1128 OMPTargetTeamsDistributeParallelForDirective *Node) {
1129 Indent() << "#pragma omp target teams distribute parallel for";
1130 PrintOMPExecutableDirective(Node);
1131}
1132
1133void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1134 OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
1135 Indent() << "#pragma omp target teams distribute parallel for simd";
1136 PrintOMPExecutableDirective(Node);
1137}
1138
1139void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1140 OMPTargetTeamsDistributeSimdDirective *Node) {
1141 Indent() << "#pragma omp target teams distribute simd";
1142 PrintOMPExecutableDirective(Node);
1143}
1144
1145void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1146 Indent() << "#pragma omp interop";
1147 PrintOMPExecutableDirective(Node);
1148}
1149
1150void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1151 Indent() << "#pragma omp dispatch";
1152 PrintOMPExecutableDirective(Node);
1153}
1154
1155void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1156 Indent() << "#pragma omp masked";
1157 PrintOMPExecutableDirective(Node);
1158}
1159
1160void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1161 Indent() << "#pragma omp loop";
1162 PrintOMPExecutableDirective(Node);
1163}
1164
1165void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1166 OMPTeamsGenericLoopDirective *Node) {
1167 Indent() << "#pragma omp teams loop";
1168 PrintOMPExecutableDirective(Node);
1169}
1170
1171void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1172 OMPTargetTeamsGenericLoopDirective *Node) {
1173 Indent() << "#pragma omp target teams loop";
1174 PrintOMPExecutableDirective(Node);
1175}
1176
1177void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1178 OMPParallelGenericLoopDirective *Node) {
1179 Indent() << "#pragma omp parallel loop";
1180 PrintOMPExecutableDirective(Node);
1181}
1182
1183void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1184 OMPTargetParallelGenericLoopDirective *Node) {
1185 Indent() << "#pragma omp target parallel loop";
1186 PrintOMPExecutableDirective(Node);
1187}
1188
1189//===----------------------------------------------------------------------===//
1190// OpenACC construct printing methods
1191//===----------------------------------------------------------------------===//
1192void StmtPrinter::PrintOpenACCClauseList(OpenACCConstructStmt *S) {
1193 if (!S->clauses().empty()) {
1194 OS << ' ';
1195 OpenACCClausePrinter Printer(OS, Policy);
1196 Printer.VisitClauseList(S->clauses());
1197 }
1198}
1199void StmtPrinter::PrintOpenACCConstruct(OpenACCConstructStmt *S) {
1200 Indent() << "#pragma acc " << S->getDirectiveKind();
1201 PrintOpenACCClauseList(S);
1202 OS << '\n';
1203}
1204void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
1205 PrintOpenACCConstruct(S);
1206 PrintStmt(S->getStructuredBlock());
1207}
1208
1209void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
1210 PrintOpenACCConstruct(S);
1211 PrintStmt(S->getLoop());
1212}
1213
1214void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {
1215 PrintOpenACCConstruct(S);
1216 PrintStmt(S->getLoop());
1217}
1218
1219void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {
1220 PrintOpenACCConstruct(S);
1221 PrintStmt(S->getStructuredBlock());
1222}
1223void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
1224 PrintOpenACCConstruct(S);
1225 PrintStmt(S->getStructuredBlock());
1226}
1227void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) {
1228 PrintOpenACCConstruct(S);
1229}
1230void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
1231 PrintOpenACCConstruct(S);
1232}
1233void StmtPrinter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
1234 PrintOpenACCConstruct(S);
1235}
1236void StmtPrinter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
1237 PrintOpenACCConstruct(S);
1238}
1239void StmtPrinter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {
1240 PrintOpenACCConstruct(S);
1241}
1242void StmtPrinter::VisitOpenACCUpdateConstruct(OpenACCUpdateConstruct *S) {
1243 PrintOpenACCConstruct(S);
1244}
1245
1246void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
1247 Indent() << "#pragma acc wait";
1248 if (!S->getLParenLoc().isInvalid()) {
1249 OS << "(";
1250 if (S->hasDevNumExpr()) {
1251 OS << "devnum: ";
1252 S->getDevNumExpr()->printPretty(OS, nullptr, Policy);
1253 OS << " : ";
1254 }
1255
1256 if (S->hasQueuesTag())
1257 OS << "queues: ";
1258
1259 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](const Expr *E) {
1260 E->printPretty(OS, nullptr, Policy);
1261 });
1262
1263 OS << ")";
1264 }
1265
1266 PrintOpenACCClauseList(S);
1267 OS << '\n';
1268}
1269
1270void StmtPrinter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) {
1271 Indent() << "#pragma acc atomic";
1272
1273 if (S->getAtomicKind() != OpenACCAtomicKind::None)
1274 OS << " " << S->getAtomicKind();
1275
1276 PrintOpenACCClauseList(S);
1277 OS << '\n';
1278 PrintStmt(S->getAssociatedStmt());
1279}
1280
1281void StmtPrinter::VisitOpenACCCacheConstruct(OpenACCCacheConstruct *S) {
1282 Indent() << "#pragma acc cache(";
1283 if (S->hasReadOnly())
1284 OS << "readonly: ";
1285
1286 llvm::interleaveComma(S->getVarList(), OS, [&](const Expr *E) {
1287 E->printPretty(OS, nullptr, Policy);
1288 });
1289
1290 OS << ")\n";
1291}
1292
1293//===----------------------------------------------------------------------===//
1294// Expr printing methods.
1295//===----------------------------------------------------------------------===//
1296
1297void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1298 OS << Node->getBuiltinStr() << "()";
1299}
1300
1301void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
1302 // FIXME: Embed parameters are not reflected in the AST, so there is no way to
1303 // print them yet.
1304 OS << "#embed ";
1305 OS << Node->getFileName();
1306 OS << NL;
1307}
1308
1309void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1310 PrintExpr(Node->getSubExpr());
1311}
1312
1313void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1314 ValueDecl *VD = Node->getDecl();
1315 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(VD)) {
1316 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1317 return;
1318 }
1319 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(VD)) {
1320 TPOD->printAsExpr(OS, Policy);
1321 return;
1322 }
1323 Node->getQualifier().print(OS, Policy);
1324 if (Node->hasTemplateKeyword())
1325 OS << "template ";
1326
1327 bool ForceAnonymous =
1328 Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm;
1329 DeclarationNameInfo NameInfo = Node->getNameInfo();
1330 if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
1331 !ForceAnonymous &&
1332 (ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier)) {
1333 if (Policy.CleanUglifiedParameters &&
1335 OS << ID->deuglifiedName();
1336 else
1337 NameInfo.printName(OS, Policy);
1338 } else {
1339 switch (VD->getKind()) {
1340 case Decl::NonTypeTemplateParm: {
1341 auto *TD = cast<NonTypeTemplateParmDecl>(VD);
1342 OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << "";
1343 break;
1344 }
1345 case Decl::ParmVar: {
1346 auto *PD = cast<ParmVarDecl>(VD);
1347 OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
1348 << PD->getFunctionScopeIndex();
1349 break;
1350 }
1351 case Decl::Decomposition:
1352 OS << "decomposition";
1353 for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
1354 OS << '-' << I->getName();
1355 break;
1356 default:
1357 OS << "unhandled-anonymous-" << VD->getDeclKindName();
1358 break;
1359 }
1360 }
1361 if (Node->hasExplicitTemplateArgs()) {
1362 const TemplateParameterList *TPL = nullptr;
1363 if (!Node->hadMultipleCandidates())
1364 if (auto *TD = dyn_cast<TemplateDecl>(VD))
1365 TPL = TD->getTemplateParameters();
1366 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1367 }
1368}
1369
1370void StmtPrinter::VisitDependentScopeDeclRefExpr(
1371 DependentScopeDeclRefExpr *Node) {
1372 Node->getQualifier().print(OS, Policy);
1373 if (Node->hasTemplateKeyword())
1374 OS << "template ";
1375 OS << Node->getNameInfo();
1376 if (Node->hasExplicitTemplateArgs())
1377 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1378}
1379
1380void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1381 Node->getQualifier().print(OS, Policy);
1382 if (Node->hasTemplateKeyword())
1383 OS << "template ";
1384 OS << Node->getNameInfo();
1385 if (Node->hasExplicitTemplateArgs())
1386 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1387}
1388
1389static bool isImplicitSelf(const Expr *E) {
1390 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1391 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1392 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1393 DRE->getBeginLoc().isInvalid())
1394 return true;
1395 }
1396 }
1397 return false;
1398}
1399
1400void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1401 if (Node->getBase()) {
1402 if (!Policy.SuppressImplicitBase ||
1403 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1404 PrintExpr(Node->getBase());
1405 OS << (Node->isArrow() ? "->" : ".");
1406 }
1407 }
1408 OS << *Node->getDecl();
1409}
1410
1411void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1412 if (Node->isSuperReceiver())
1413 OS << "super.";
1414 else if (Node->isObjectReceiver() && Node->getBase()) {
1415 PrintExpr(Node->getBase());
1416 OS << ".";
1417 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1418 OS << Node->getClassReceiver()->getName() << ".";
1419 }
1420
1421 if (Node->isImplicitProperty()) {
1422 if (const auto *Getter = Node->getImplicitPropertyGetter())
1423 Getter->getSelector().print(OS);
1424 else
1427 } else
1428 OS << Node->getExplicitProperty()->getName();
1429}
1430
1431void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1432 PrintExpr(Node->getBaseExpr());
1433 OS << "[";
1434 PrintExpr(Node->getKeyExpr());
1435 OS << "]";
1436}
1437
1438void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1439 SYCLUniqueStableNameExpr *Node) {
1440 OS << "__builtin_sycl_unique_stable_name(";
1441 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1442 OS << ")";
1443}
1444
1445void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1447}
1448
1449void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {
1450 OS << '*';
1451}
1452
1453void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1454 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1455}
1456
1457/// Prints the given expression using the original source text. Returns true on
1458/// success, false otherwise.
1459static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1460 const ASTContext *Context) {
1461 if (!Context)
1462 return false;
1463 bool Invalid = false;
1464 StringRef Source = Lexer::getSourceText(
1466 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1467 if (!Invalid) {
1468 OS << Source;
1469 return true;
1470 }
1471 return false;
1472}
1473
1474void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1475 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1476 return;
1477 bool isSigned = Node->getType()->isSignedIntegerType();
1478 OS << toString(Node->getValue(), 10, isSigned);
1479
1480 if (isa<BitIntType>(Node->getType())) {
1481 OS << (isSigned ? "wb" : "uwb");
1482 return;
1483 }
1484
1485 // Emit suffixes. Integer literals are always a builtin integer type.
1486 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1487 default: llvm_unreachable("Unexpected type for integer literal!");
1488 case BuiltinType::Char_S:
1489 case BuiltinType::Char_U: OS << "i8"; break;
1490 case BuiltinType::UChar: OS << "Ui8"; break;
1491 case BuiltinType::SChar: OS << "i8"; break;
1492 case BuiltinType::Short: OS << "i16"; break;
1493 case BuiltinType::UShort: OS << "Ui16"; break;
1494 case BuiltinType::Int: break; // no suffix.
1495 case BuiltinType::UInt: OS << 'U'; break;
1496 case BuiltinType::Long: OS << 'L'; break;
1497 case BuiltinType::ULong: OS << "UL"; break;
1498 case BuiltinType::LongLong: OS << "LL"; break;
1499 case BuiltinType::ULongLong: OS << "ULL"; break;
1500 case BuiltinType::Int128:
1501 break; // no suffix.
1502 case BuiltinType::UInt128:
1503 break; // no suffix.
1504 case BuiltinType::WChar_S:
1505 case BuiltinType::WChar_U:
1506 break; // no suffix
1507 }
1508}
1509
1510void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1511 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1512 return;
1513 OS << Node->getValueAsString(/*Radix=*/10);
1514
1515 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1516 default: llvm_unreachable("Unexpected type for fixed point literal!");
1517 case BuiltinType::ShortFract: OS << "hr"; break;
1518 case BuiltinType::ShortAccum: OS << "hk"; break;
1519 case BuiltinType::UShortFract: OS << "uhr"; break;
1520 case BuiltinType::UShortAccum: OS << "uhk"; break;
1521 case BuiltinType::Fract: OS << "r"; break;
1522 case BuiltinType::Accum: OS << "k"; break;
1523 case BuiltinType::UFract: OS << "ur"; break;
1524 case BuiltinType::UAccum: OS << "uk"; break;
1525 case BuiltinType::LongFract: OS << "lr"; break;
1526 case BuiltinType::LongAccum: OS << "lk"; break;
1527 case BuiltinType::ULongFract: OS << "ulr"; break;
1528 case BuiltinType::ULongAccum: OS << "ulk"; break;
1529 }
1530}
1531
1532static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1533 bool PrintSuffix) {
1534 SmallString<16> Str;
1535 Node->getValue().toString(Str);
1536 OS << Str;
1537 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1538 OS << '.'; // Trailing dot in order to separate from ints.
1539
1540 if (!PrintSuffix)
1541 return;
1542
1543 // Emit suffixes. Float literals are always a builtin float type.
1544 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1545 default: llvm_unreachable("Unexpected type for float literal!");
1546 case BuiltinType::Half: break; // FIXME: suffix?
1547 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1548 case BuiltinType::Double: break; // no suffix.
1549 case BuiltinType::Float16: OS << "F16"; break;
1550 case BuiltinType::Float: OS << 'F'; break;
1551 case BuiltinType::LongDouble: OS << 'L'; break;
1552 case BuiltinType::Float128: OS << 'Q'; break;
1553 }
1554}
1555
1556void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1557 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1558 return;
1559 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1560}
1561
1562void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1563 PrintExpr(Node->getSubExpr());
1564 OS << "i";
1565}
1566
1567void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1568 Str->outputString(OS);
1569}
1570
1571void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1572 OS << "(";
1573 PrintExpr(Node->getSubExpr());
1574 OS << ")";
1575}
1576
1577void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1578 if (!Node->isPostfix()) {
1580
1581 // Print a space if this is an "identifier operator" like __real, or if
1582 // it might be concatenated incorrectly like '+'.
1583 switch (Node->getOpcode()) {
1584 default: break;
1585 case UO_Real:
1586 case UO_Imag:
1587 case UO_Extension:
1588 OS << ' ';
1589 break;
1590 case UO_Plus:
1591 case UO_Minus:
1592 if (isa<UnaryOperator>(Node->getSubExpr()))
1593 OS << ' ';
1594 break;
1595 }
1596 }
1597 PrintExpr(Node->getSubExpr());
1598
1599 if (Node->isPostfix())
1601}
1602
1603void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1604 OS << "__builtin_offsetof(";
1605 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1606 OS << ", ";
1607 bool PrintedSomething = false;
1608 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1609 OffsetOfNode ON = Node->getComponent(i);
1610 if (ON.getKind() == OffsetOfNode::Array) {
1611 // Array node
1612 OS << "[";
1613 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1614 OS << "]";
1615 PrintedSomething = true;
1616 continue;
1617 }
1618
1619 // Skip implicit base indirections.
1620 if (ON.getKind() == OffsetOfNode::Base)
1621 continue;
1622
1623 // Field or identifier node.
1624 const IdentifierInfo *Id = ON.getFieldName();
1625 if (!Id)
1626 continue;
1627
1628 if (PrintedSomething)
1629 OS << ".";
1630 else
1631 PrintedSomething = true;
1632 OS << Id->getName();
1633 }
1634 OS << ")";
1635}
1636
1637void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1638 UnaryExprOrTypeTraitExpr *Node) {
1639 const char *Spelling = getTraitSpelling(Node->getKind());
1640 if (Node->getKind() == UETT_AlignOf) {
1641 if (Policy.Alignof)
1642 Spelling = "alignof";
1643 else if (Policy.UnderscoreAlignof)
1644 Spelling = "_Alignof";
1645 else
1646 Spelling = "__alignof";
1647 }
1648
1649 OS << Spelling;
1650
1651 if (Node->isArgumentType()) {
1652 OS << '(';
1653 Node->getArgumentType().print(OS, Policy);
1654 OS << ')';
1655 } else {
1656 OS << " ";
1657 PrintExpr(Node->getArgumentExpr());
1658 }
1659}
1660
1661void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1662 OS << "_Generic(";
1663 if (Node->isExprPredicate())
1664 PrintExpr(Node->getControllingExpr());
1665 else
1666 Node->getControllingType()->getType().print(OS, Policy);
1667
1668 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1669 OS << ", ";
1670 QualType T = Assoc.getType();
1671 if (T.isNull())
1672 OS << "default";
1673 else
1674 T.print(OS, Policy);
1675 OS << ": ";
1676 PrintExpr(Assoc.getAssociationExpr());
1677 }
1678 OS << ")";
1679}
1680
1681void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1682 PrintExpr(Node->getLHS());
1683 OS << "[";
1684 PrintExpr(Node->getRHS());
1685 OS << "]";
1686}
1687
1688void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1689 PrintExpr(Node->getBase());
1690 OS << "[";
1691 PrintExpr(Node->getRowIdx());
1692 OS << "]";
1693 OS << "[";
1694 PrintExpr(Node->getColumnIdx());
1695 OS << "]";
1696}
1697
1698void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1699 PrintExpr(Node->getBase());
1700 OS << "[";
1701 if (Node->getLowerBound())
1702 PrintExpr(Node->getLowerBound());
1703 if (Node->getColonLocFirst().isValid()) {
1704 OS << ":";
1705 if (Node->getLength())
1706 PrintExpr(Node->getLength());
1707 }
1708 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1709 OS << ":";
1710 if (Node->getStride())
1711 PrintExpr(Node->getStride());
1712 }
1713 OS << "]";
1714}
1715
1716void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1717 OS << "(";
1718 for (Expr *E : Node->getDimensions()) {
1719 OS << "[";
1720 PrintExpr(E);
1721 OS << "]";
1722 }
1723 OS << ")";
1724 PrintExpr(Node->getBase());
1725}
1726
1727void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1728 OS << "iterator(";
1729 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1730 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1731 VD->getType().print(OS, Policy);
1732 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1733 OS << " " << VD->getName() << " = ";
1734 PrintExpr(Range.Begin);
1735 OS << ":";
1736 PrintExpr(Range.End);
1737 if (Range.Step) {
1738 OS << ":";
1739 PrintExpr(Range.Step);
1740 }
1741 if (I < E - 1)
1742 OS << ", ";
1743 }
1744 OS << ")";
1745}
1746
1747void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1748 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1749 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1750 // Don't print any defaulted arguments
1751 break;
1752 }
1753
1754 if (i) OS << ", ";
1755 PrintExpr(Call->getArg(i));
1756 }
1757}
1758
1759void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1760 PrintExpr(Call->getCallee());
1761 OS << "(";
1762 PrintCallArgs(Call);
1763 OS << ")";
1764}
1765
1766static bool isImplicitThis(const Expr *E) {
1767 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1768 return TE->isImplicit();
1769 return false;
1770}
1771
1772void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1773 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1774 PrintExpr(Node->getBase());
1775
1776 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1777 FieldDecl *ParentDecl =
1778 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1779 : nullptr;
1780
1781 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1782 OS << (Node->isArrow() ? "->" : ".");
1783 }
1784
1785 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1786 if (FD->isAnonymousStructOrUnion())
1787 return;
1788
1789 Node->getQualifier().print(OS, Policy);
1790 if (Node->hasTemplateKeyword())
1791 OS << "template ";
1792 OS << Node->getMemberNameInfo();
1793 const TemplateParameterList *TPL = nullptr;
1794 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1795 if (!Node->hadMultipleCandidates())
1796 if (auto *FTD = FD->getPrimaryTemplate())
1797 TPL = FTD->getTemplateParameters();
1798 } else if (auto *VTSD =
1799 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1800 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1801 if (Node->hasExplicitTemplateArgs())
1802 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1803}
1804
1805void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1806 PrintExpr(Node->getBase());
1807 OS << (Node->isArrow() ? "->isa" : ".isa");
1808}
1809
1810void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1811 PrintExpr(Node->getBase());
1812 OS << ".";
1813 OS << Node->getAccessor().getName();
1814}
1815
1816void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1817 OS << '(';
1818 Node->getTypeAsWritten().print(OS, Policy);
1819 OS << ')';
1820 PrintExpr(Node->getSubExpr());
1821}
1822
1823void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1824 OS << '(';
1825 Node->getType().print(OS, Policy);
1826 OS << ')';
1827 PrintExpr(Node->getInitializer());
1828}
1829
1830void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1831 // No need to print anything, simply forward to the subexpression.
1832 PrintExpr(Node->getSubExpr());
1833}
1834
1835void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1836 PrintExpr(Node->getLHS());
1837 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1838 PrintExpr(Node->getRHS());
1839}
1840
1841void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1842 PrintExpr(Node->getLHS());
1843 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1844 PrintExpr(Node->getRHS());
1845}
1846
1847void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1848 PrintExpr(Node->getCond());
1849 OS << " ? ";
1850 PrintExpr(Node->getLHS());
1851 OS << " : ";
1852 PrintExpr(Node->getRHS());
1853}
1854
1855// GNU extensions.
1856
1857void
1858StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1859 PrintExpr(Node->getCommon());
1860 OS << " ?: ";
1861 PrintExpr(Node->getFalseExpr());
1862}
1863
1864void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1865 OS << "&&" << Node->getLabel()->getName();
1866}
1867
1868void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1869 OS << "(";
1870 PrintRawCompoundStmt(E->getSubStmt());
1871 OS << ")";
1872}
1873
1874void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1875 OS << "__builtin_choose_expr(";
1876 PrintExpr(Node->getCond());
1877 OS << ", ";
1878 PrintExpr(Node->getLHS());
1879 OS << ", ";
1880 PrintExpr(Node->getRHS());
1881 OS << ")";
1882}
1883
1884void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1885 OS << "__null";
1886}
1887
1888void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1889 OS << "__builtin_shufflevector(";
1890 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1891 if (i) OS << ", ";
1892 PrintExpr(Node->getExpr(i));
1893 }
1894 OS << ")";
1895}
1896
1897void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1898 OS << "__builtin_convertvector(";
1899 PrintExpr(Node->getSrcExpr());
1900 OS << ", ";
1901 Node->getType().print(OS, Policy);
1902 OS << ")";
1903}
1904
1905void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1906 if (Node->getSyntacticForm()) {
1907 Visit(Node->getSyntacticForm());
1908 return;
1909 }
1910
1911 OS << "{";
1912 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1913 if (i) OS << ", ";
1914 if (Node->getInit(i))
1915 PrintExpr(Node->getInit(i));
1916 else
1917 OS << "{}";
1918 }
1919 OS << "}";
1920}
1921
1922void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1923 // There's no way to express this expression in any of our supported
1924 // languages, so just emit something terse and (hopefully) clear.
1925 OS << "{";
1926 PrintExpr(Node->getSubExpr());
1927 OS << "}";
1928}
1929
1930void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1931 OS << "*";
1932}
1933
1934void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1935 OS << "(";
1936 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1937 if (i) OS << ", ";
1938 PrintExpr(Node->getExpr(i));
1939 }
1940 OS << ")";
1941}
1942
1943void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1944 bool NeedsEquals = true;
1945 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1946 if (D.isFieldDesignator()) {
1947 if (D.getDotLoc().isInvalid()) {
1948 if (const IdentifierInfo *II = D.getFieldName()) {
1949 OS << II->getName() << ":";
1950 NeedsEquals = false;
1951 }
1952 } else {
1953 OS << "." << D.getFieldName()->getName();
1954 }
1955 } else {
1956 OS << "[";
1957 if (D.isArrayDesignator()) {
1958 PrintExpr(Node->getArrayIndex(D));
1959 } else {
1960 PrintExpr(Node->getArrayRangeStart(D));
1961 OS << " ... ";
1962 PrintExpr(Node->getArrayRangeEnd(D));
1963 }
1964 OS << "]";
1965 }
1966 }
1967
1968 if (NeedsEquals)
1969 OS << " = ";
1970 else
1971 OS << " ";
1972 PrintExpr(Node->getInit());
1973}
1974
1975void StmtPrinter::VisitDesignatedInitUpdateExpr(
1976 DesignatedInitUpdateExpr *Node) {
1977 OS << "{";
1978 OS << "/*base*/";
1979 PrintExpr(Node->getBase());
1980 OS << ", ";
1981
1982 OS << "/*updater*/";
1983 PrintExpr(Node->getUpdater());
1984 OS << "}";
1985}
1986
1987void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1988 OS << "/*no init*/";
1989}
1990
1991void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1992 if (Node->getType()->getAsCXXRecordDecl()) {
1993 OS << "/*implicit*/";
1994 Node->getType().print(OS, Policy);
1995 OS << "()";
1996 } else {
1997 OS << "/*implicit*/(";
1998 Node->getType().print(OS, Policy);
1999 OS << ')';
2000 if (Node->getType()->isRecordType())
2001 OS << "{}";
2002 else
2003 OS << 0;
2004 }
2005}
2006
2007void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
2008 OS << "__builtin_va_arg(";
2009 PrintExpr(Node->getSubExpr());
2010 OS << ", ";
2011 Node->getType().print(OS, Policy);
2012 OS << ")";
2013}
2014
2015void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
2016 PrintExpr(Node->getSyntacticForm());
2017}
2018
2019void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
2020 const char *Name = nullptr;
2021 switch (Node->getOp()) {
2022#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2023 case AtomicExpr::AO ## ID: \
2024 Name = #ID "("; \
2025 break;
2026#include "clang/Basic/Builtins.inc"
2027 }
2028 OS << Name;
2029
2030 // AtomicExpr stores its subexpressions in a permuted order.
2031 PrintExpr(Node->getPtr());
2032 if (Node->hasVal1Operand()) {
2033 OS << ", ";
2034 PrintExpr(Node->getVal1());
2035 }
2036 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
2037 Node->isCmpXChg()) {
2038 OS << ", ";
2039 PrintExpr(Node->getVal2());
2040 }
2041 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
2042 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
2043 OS << ", ";
2044 PrintExpr(Node->getWeak());
2045 }
2046 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
2047 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
2048 OS << ", ";
2049 PrintExpr(Node->getOrder());
2050 }
2051 if (Node->isCmpXChg()) {
2052 OS << ", ";
2053 PrintExpr(Node->getOrderFail());
2054 }
2055 OS << ")";
2056}
2057
2058// C++
2059void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
2061 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
2062 if (Node->getNumArgs() == 1) {
2063 OS << getOperatorSpelling(Kind) << ' ';
2064 PrintExpr(Node->getArg(0));
2065 } else {
2066 PrintExpr(Node->getArg(0));
2067 OS << ' ' << getOperatorSpelling(Kind);
2068 }
2069 } else if (Kind == OO_Arrow) {
2070 PrintExpr(Node->getArg(0));
2071 } else if (Kind == OO_Call || Kind == OO_Subscript) {
2072 PrintExpr(Node->getArg(0));
2073 OS << (Kind == OO_Call ? '(' : '[');
2074 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
2075 if (ArgIdx > 1)
2076 OS << ", ";
2077 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
2078 PrintExpr(Node->getArg(ArgIdx));
2079 }
2080 OS << (Kind == OO_Call ? ')' : ']');
2081 } else if (Node->getNumArgs() == 1) {
2082 OS << getOperatorSpelling(Kind) << ' ';
2083 PrintExpr(Node->getArg(0));
2084 } else if (Node->getNumArgs() == 2) {
2085 PrintExpr(Node->getArg(0));
2086 OS << ' ' << getOperatorSpelling(Kind) << ' ';
2087 PrintExpr(Node->getArg(1));
2088 } else {
2089 llvm_unreachable("unknown overloaded operator");
2090 }
2091}
2092
2093void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2094 // If we have a conversion operator call only print the argument.
2095 CXXMethodDecl *MD = Node->getMethodDecl();
2096 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2097 PrintExpr(Node->getImplicitObjectArgument());
2098 return;
2099 }
2100 VisitCallExpr(cast<CallExpr>(Node));
2101}
2102
2103void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2104 PrintExpr(Node->getCallee());
2105 OS << "<<<";
2106 PrintCallArgs(Node->getConfig());
2107 OS << ">>>(";
2108 PrintCallArgs(Node);
2109 OS << ")";
2110}
2111
2112void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2113 CXXRewrittenBinaryOperator *Node) {
2114 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
2115 Node->getDecomposedForm();
2116 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
2117 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
2118 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
2119}
2120
2121void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2122 OS << Node->getCastName() << '<';
2123 Node->getTypeAsWritten().print(OS, Policy);
2124 OS << ">(";
2125 PrintExpr(Node->getSubExpr());
2126 OS << ")";
2127}
2128
2129void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2130 VisitCXXNamedCastExpr(Node);
2131}
2132
2133void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2134 VisitCXXNamedCastExpr(Node);
2135}
2136
2137void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2138 VisitCXXNamedCastExpr(Node);
2139}
2140
2141void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2142 VisitCXXNamedCastExpr(Node);
2143}
2144
2145void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2146 OS << "__builtin_bit_cast(";
2147 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2148 OS << ", ";
2149 PrintExpr(Node->getSubExpr());
2150 OS << ")";
2151}
2152
2153void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2154 VisitCXXNamedCastExpr(Node);
2155}
2156
2157void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2158 OS << "typeid(";
2159 if (Node->isTypeOperand()) {
2160 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2161 } else {
2162 PrintExpr(Node->getExprOperand());
2163 }
2164 OS << ")";
2165}
2166
2167void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2168 OS << "__uuidof(";
2169 if (Node->isTypeOperand()) {
2170 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2171 } else {
2172 PrintExpr(Node->getExprOperand());
2173 }
2174 OS << ")";
2175}
2176
2177void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2178 PrintExpr(Node->getBaseExpr());
2179 if (Node->isArrow())
2180 OS << "->";
2181 else
2182 OS << ".";
2183 Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);
2184 OS << Node->getPropertyDecl()->getDeclName();
2185}
2186
2187void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2188 PrintExpr(Node->getBase());
2189 OS << "[";
2190 PrintExpr(Node->getIdx());
2191 OS << "]";
2192}
2193
2194void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2195 switch (Node->getLiteralOperatorKind()) {
2197 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2198 break;
2200 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2201 const TemplateArgumentList *Args =
2202 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2203 assert(Args);
2204
2205 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2206 const TemplateParameterList *TPL = nullptr;
2207 if (!DRE->hadMultipleCandidates())
2208 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2209 TPL = TD->getTemplateParameters();
2210 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2211 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2212 OS << "()";
2213 return;
2214 }
2215
2216 const TemplateArgument &Pack = Args->get(0);
2217 for (const auto &P : Pack.pack_elements()) {
2218 char C = (char)P.getAsIntegral().getZExtValue();
2219 OS << C;
2220 }
2221 break;
2222 }
2224 // Print integer literal without suffix.
2225 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2226 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2227 break;
2228 }
2230 // Print floating literal without suffix.
2232 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2233 break;
2234 }
2237 PrintExpr(Node->getCookedLiteral());
2238 break;
2239 }
2240 OS << Node->getUDSuffix()->getName();
2241}
2242
2243void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2244 OS << (Node->getValue() ? "true" : "false");
2245}
2246
2247void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2248 OS << "nullptr";
2249}
2250
2251void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2252 OS << "this";
2253}
2254
2255void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2256 if (!Node->getSubExpr())
2257 OS << "throw";
2258 else {
2259 OS << "throw ";
2260 PrintExpr(Node->getSubExpr());
2261 }
2262}
2263
2264void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2265 // Nothing to print: we picked up the default argument.
2266}
2267
2268void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2269 // Nothing to print: we picked up the default initializer.
2270}
2271
2272void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2273 auto TargetType = Node->getType();
2274 auto *Auto = TargetType->getContainedDeducedType();
2275 bool Bare = Auto && Auto->isDeduced();
2276
2277 // Parenthesize deduced casts.
2278 if (Bare)
2279 OS << '(';
2280 TargetType.print(OS, Policy);
2281 if (Bare)
2282 OS << ')';
2283
2284 // No extra braces surrounding the inner construct.
2285 if (!Node->isListInitialization())
2286 OS << '(';
2287 PrintExpr(Node->getSubExpr());
2288 if (!Node->isListInitialization())
2289 OS << ')';
2290}
2291
2292void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2293 PrintExpr(Node->getSubExpr());
2294}
2295
2296void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2297 Node->getType().print(OS, Policy);
2298 if (Node->isStdInitListInitialization())
2299 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2300 else if (Node->isListInitialization())
2301 OS << "{";
2302 else
2303 OS << "(";
2304 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2305 ArgEnd = Node->arg_end();
2306 Arg != ArgEnd; ++Arg) {
2307 if ((*Arg)->isDefaultArgument())
2308 break;
2309 if (Arg != Node->arg_begin())
2310 OS << ", ";
2311 PrintExpr(*Arg);
2312 }
2313 if (Node->isStdInitListInitialization())
2314 /* See above. */;
2315 else if (Node->isListInitialization())
2316 OS << "}";
2317 else
2318 OS << ")";
2319}
2320
2321void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2322 OS << '[';
2323 bool NeedComma = false;
2324 switch (Node->getCaptureDefault()) {
2325 case LCD_None:
2326 break;
2327
2328 case LCD_ByCopy:
2329 OS << '=';
2330 NeedComma = true;
2331 break;
2332
2333 case LCD_ByRef:
2334 OS << '&';
2335 NeedComma = true;
2336 break;
2337 }
2339 CEnd = Node->explicit_capture_end();
2340 C != CEnd;
2341 ++C) {
2342 if (C->capturesVLAType())
2343 continue;
2344
2345 if (NeedComma)
2346 OS << ", ";
2347 NeedComma = true;
2348
2349 switch (C->getCaptureKind()) {
2350 case LCK_This:
2351 OS << "this";
2352 break;
2353
2354 case LCK_StarThis:
2355 OS << "*this";
2356 break;
2357
2358 case LCK_ByRef:
2359 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2360 OS << '&';
2361 OS << C->getCapturedVar()->getName();
2362 break;
2363
2364 case LCK_ByCopy:
2365 OS << C->getCapturedVar()->getName();
2366 break;
2367
2368 case LCK_VLAType:
2369 llvm_unreachable("VLA type in explicit captures.");
2370 }
2371
2372 if (C->isPackExpansion())
2373 OS << "...";
2374
2375 if (Node->isInitCapture(C)) {
2376 // Init captures are always VarDecl.
2377 auto *D = cast<VarDecl>(C->getCapturedVar());
2378
2379 llvm::StringRef Pre;
2380 llvm::StringRef Post;
2381 if (D->getInitStyle() == VarDecl::CallInit &&
2382 !isa<ParenListExpr>(D->getInit())) {
2383 Pre = "(";
2384 Post = ")";
2385 } else if (D->getInitStyle() == VarDecl::CInit) {
2386 Pre = " = ";
2387 }
2388
2389 OS << Pre;
2390 PrintExpr(D->getInit());
2391 OS << Post;
2392 }
2393 }
2394 OS << ']';
2395
2396 if (!Node->getExplicitTemplateParameters().empty()) {
2398 OS, Node->getLambdaClass()->getASTContext(),
2399 /*OmitTemplateKW*/true);
2400 }
2401
2402 if (Node->hasExplicitParameters()) {
2403 OS << '(';
2404 CXXMethodDecl *Method = Node->getCallOperator();
2405 NeedComma = false;
2406 for (const auto *P : Method->parameters()) {
2407 if (NeedComma) {
2408 OS << ", ";
2409 } else {
2410 NeedComma = true;
2411 }
2412 std::string ParamStr =
2413 (Policy.CleanUglifiedParameters && P->getIdentifier())
2414 ? P->getIdentifier()->deuglifiedName().str()
2415 : P->getNameAsString();
2416 P->getOriginalType().print(OS, Policy, ParamStr);
2417 }
2418 if (Method->isVariadic()) {
2419 if (NeedComma)
2420 OS << ", ";
2421 OS << "...";
2422 }
2423 OS << ')';
2424
2425 if (Node->isMutable())
2426 OS << " mutable";
2427
2428 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2429 Proto->printExceptionSpecification(OS, Policy);
2430
2431 // FIXME: Attributes
2432
2433 // Print the trailing return type if it was specified in the source.
2434 if (Node->hasExplicitResultType()) {
2435 OS << " -> ";
2436 Proto->getReturnType().print(OS, Policy);
2437 }
2438 }
2439
2440 // Print the body.
2441 OS << ' ';
2442 if (Policy.TerseOutput)
2443 OS << "{}";
2444 else
2445 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2446}
2447
2448void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2449 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2450 TSInfo->getType().print(OS, Policy);
2451 else
2452 Node->getType().print(OS, Policy);
2453 OS << "()";
2454}
2455
2456void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2457 if (E->isGlobalNew())
2458 OS << "::";
2459 OS << "new ";
2460 unsigned NumPlace = E->getNumPlacementArgs();
2461 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2462 OS << "(";
2463 PrintExpr(E->getPlacementArg(0));
2464 for (unsigned i = 1; i < NumPlace; ++i) {
2466 break;
2467 OS << ", ";
2468 PrintExpr(E->getPlacementArg(i));
2469 }
2470 OS << ") ";
2471 }
2472 if (E->isParenTypeId())
2473 OS << "(";
2474 std::string TypeS;
2475 if (E->isArray()) {
2476 llvm::raw_string_ostream s(TypeS);
2477 s << '[';
2478 if (std::optional<Expr *> Size = E->getArraySize())
2479 (*Size)->printPretty(s, Helper, Policy);
2480 s << ']';
2481 }
2482 E->getAllocatedType().print(OS, Policy, TypeS);
2483 if (E->isParenTypeId())
2484 OS << ")";
2485
2487 if (InitStyle != CXXNewInitializationStyle::None) {
2488 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2490 if (Bare)
2491 OS << "(";
2492 PrintExpr(E->getInitializer());
2493 if (Bare)
2494 OS << ")";
2495 }
2496}
2497
2498void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2499 if (E->isGlobalDelete())
2500 OS << "::";
2501 OS << "delete ";
2502 if (E->isArrayForm())
2503 OS << "[] ";
2504 PrintExpr(E->getArgument());
2505}
2506
2507void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2508 PrintExpr(E->getBase());
2509 if (E->isArrow())
2510 OS << "->";
2511 else
2512 OS << '.';
2513 E->getQualifier().print(OS, Policy);
2514 OS << "~";
2515
2516 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2517 OS << II->getName();
2518 else
2519 E->getDestroyedType().print(OS, Policy);
2520}
2521
2522void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2524 OS << "{";
2525
2526 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2527 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2528 // Don't print any defaulted arguments
2529 break;
2530 }
2531
2532 if (i) OS << ", ";
2533 PrintExpr(E->getArg(i));
2534 }
2535
2537 OS << "}";
2538}
2539
2540void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2541 // Parens are printed by the surrounding context.
2542 OS << "<forwarded>";
2543}
2544
2545void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2546 PrintExpr(E->getSubExpr());
2547}
2548
2549void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2550 // Just forward to the subexpression.
2551 PrintExpr(E->getSubExpr());
2552}
2553
2554void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2555 CXXUnresolvedConstructExpr *Node) {
2556 Node->getTypeAsWritten().print(OS, Policy);
2557 if (!Node->isListInitialization())
2558 OS << '(';
2559 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2560 ++Arg) {
2561 if (Arg != Node->arg_begin())
2562 OS << ", ";
2563 PrintExpr(*Arg);
2564 }
2565 if (!Node->isListInitialization())
2566 OS << ')';
2567}
2568
2569void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2570 CXXDependentScopeMemberExpr *Node) {
2571 if (!Node->isImplicitAccess()) {
2572 PrintExpr(Node->getBase());
2573 OS << (Node->isArrow() ? "->" : ".");
2574 }
2575 Node->getQualifier().print(OS, Policy);
2576 if (Node->hasTemplateKeyword())
2577 OS << "template ";
2578 OS << Node->getMemberNameInfo();
2579 if (Node->hasExplicitTemplateArgs())
2580 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2581}
2582
2583void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2584 if (!Node->isImplicitAccess()) {
2585 PrintExpr(Node->getBase());
2586 OS << (Node->isArrow() ? "->" : ".");
2587 }
2588 Node->getQualifier().print(OS, Policy);
2589 if (Node->hasTemplateKeyword())
2590 OS << "template ";
2591 OS << Node->getMemberNameInfo();
2592 if (Node->hasExplicitTemplateArgs())
2593 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2594}
2595
2596void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2597 OS << getTraitSpelling(E->getTrait()) << "(";
2598 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2599 if (I > 0)
2600 OS << ", ";
2601 E->getArg(I)->getType().print(OS, Policy);
2602 }
2603 OS << ")";
2604}
2605
2606void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2607 OS << getTraitSpelling(E->getTrait()) << '(';
2608 E->getQueriedType().print(OS, Policy);
2609 OS << ')';
2610}
2611
2612void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2613 OS << getTraitSpelling(E->getTrait()) << '(';
2614 PrintExpr(E->getQueriedExpression());
2615 OS << ')';
2616}
2617
2618void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2619 OS << "noexcept(";
2620 PrintExpr(E->getOperand());
2621 OS << ")";
2622}
2623
2624void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2625 PrintExpr(E->getPattern());
2626 OS << "...";
2627}
2628
2629void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2630 OS << "sizeof...(" << *E->getPack() << ")";
2631}
2632
2633void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2634 PrintExpr(E->getPackIdExpression());
2635 OS << "...[";
2636 PrintExpr(E->getIndexExpr());
2637 OS << "]";
2638}
2639
2640void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2641 SubstNonTypeTemplateParmPackExpr *Node) {
2642 OS << *Node->getParameterPack();
2643}
2644
2645void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2646 SubstNonTypeTemplateParmExpr *Node) {
2647 Visit(Node->getReplacement());
2648}
2649
2650void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2651 OS << *E->getParameterPack();
2652}
2653
2654void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2655 PrintExpr(Node->getSubExpr());
2656}
2657
2658void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2659 OS << "(";
2660 if (E->getLHS()) {
2661 PrintExpr(E->getLHS());
2662 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2663 }
2664 OS << "...";
2665 if (E->getRHS()) {
2666 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2667 PrintExpr(E->getRHS());
2668 }
2669 OS << ")";
2670}
2671
2672void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2673 llvm::interleaveComma(Node->getUserSpecifiedInitExprs(), OS,
2674 [&](Expr *E) { PrintExpr(E); });
2675}
2676
2677void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2678 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2679 NNS.getNestedNameSpecifier().print(OS, Policy);
2680 if (E->getTemplateKWLoc().isValid())
2681 OS << "template ";
2682 OS << E->getFoundDecl()->getName();
2683 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2684 Policy,
2686}
2687
2688void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2689 OS << "requires ";
2690 auto LocalParameters = E->getLocalParameters();
2691 if (!LocalParameters.empty()) {
2692 OS << "(";
2693 for (ParmVarDecl *LocalParam : LocalParameters) {
2694 PrintRawDecl(LocalParam);
2695 if (LocalParam != LocalParameters.back())
2696 OS << ", ";
2697 }
2698
2699 OS << ") ";
2700 }
2701 OS << "{ ";
2702 auto Requirements = E->getRequirements();
2703 for (concepts::Requirement *Req : Requirements) {
2704 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2705 if (TypeReq->isSubstitutionFailure())
2706 OS << "<<error-type>>";
2707 else
2708 TypeReq->getType()->getType().print(OS, Policy);
2709 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2710 if (ExprReq->isCompound())
2711 OS << "{ ";
2712 if (ExprReq->isExprSubstitutionFailure())
2713 OS << "<<error-expression>>";
2714 else
2715 PrintExpr(ExprReq->getExpr());
2716 if (ExprReq->isCompound()) {
2717 OS << " }";
2718 if (ExprReq->getNoexceptLoc().isValid())
2719 OS << " noexcept";
2720 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2721 if (!RetReq.isEmpty()) {
2722 OS << " -> ";
2723 if (RetReq.isSubstitutionFailure())
2724 OS << "<<error-type>>";
2725 else if (RetReq.isTypeConstraint())
2726 RetReq.getTypeConstraint()->print(OS, Policy);
2727 }
2728 }
2729 } else {
2730 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2731 OS << "requires ";
2732 if (NestedReq->hasInvalidConstraint())
2733 OS << "<<error-expression>>";
2734 else
2735 PrintExpr(NestedReq->getConstraintExpr());
2736 }
2737 OS << "; ";
2738 }
2739 OS << "}";
2740}
2741
2742// C++ Coroutines
2743
2744void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2745 Visit(S->getBody());
2746}
2747
2748void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2749 OS << "co_return";
2750 if (S->getOperand()) {
2751 OS << " ";
2752 Visit(S->getOperand());
2753 }
2754 OS << ";";
2755}
2756
2757void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2758 OS << "co_await ";
2759 PrintExpr(S->getOperand());
2760}
2761
2762void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2763 OS << "co_await ";
2764 PrintExpr(S->getOperand());
2765}
2766
2767void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2768 OS << "co_yield ";
2769 PrintExpr(S->getOperand());
2770}
2771
2772// Obj-C
2773
2774void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2775 OS << "@";
2776 VisitStringLiteral(Node->getString());
2777}
2778
2779void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2780 OS << "@";
2781 Visit(E->getSubExpr());
2782}
2783
2784void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2785 OS << "@[ ";
2786 ObjCArrayLiteral::child_range Ch = E->children();
2787 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2788 if (I != Ch.begin())
2789 OS << ", ";
2790 Visit(*I);
2791 }
2792 OS << " ]";
2793}
2794
2795void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2796 OS << "@{ ";
2797 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2798 if (I > 0)
2799 OS << ", ";
2800
2801 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2802 Visit(Element.Key);
2803 OS << " : ";
2804 Visit(Element.Value);
2805 if (Element.isPackExpansion())
2806 OS << "...";
2807 }
2808 OS << " }";
2809}
2810
2811void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2812 OS << "@encode(";
2813 Node->getEncodedType().print(OS, Policy);
2814 OS << ')';
2815}
2816
2817void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2818 OS << "@selector(";
2819 Node->getSelector().print(OS);
2820 OS << ')';
2821}
2822
2823void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2824 OS << "@protocol(" << *Node->getProtocol() << ')';
2825}
2826
2827void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2828 OS << "[";
2829 switch (Mess->getReceiverKind()) {
2831 PrintExpr(Mess->getInstanceReceiver());
2832 break;
2833
2835 Mess->getClassReceiver().print(OS, Policy);
2836 break;
2837
2840 OS << "Super";
2841 break;
2842 }
2843
2844 OS << ' ';
2845 Selector selector = Mess->getSelector();
2846 if (selector.isUnarySelector()) {
2847 OS << selector.getNameForSlot(0);
2848 } else {
2849 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2850 if (i < selector.getNumArgs()) {
2851 if (i > 0) OS << ' ';
2852 if (selector.getIdentifierInfoForSlot(i))
2853 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2854 else
2855 OS << ":";
2856 }
2857 else OS << ", "; // Handle variadic methods.
2858
2859 PrintExpr(Mess->getArg(i));
2860 }
2861 }
2862 OS << "]";
2863}
2864
2865void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2866 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2867}
2868
2869void
2870StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2871 PrintExpr(E->getSubExpr());
2872}
2873
2874void
2875StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2876 OS << '(' << E->getBridgeKindName();
2877 E->getType().print(OS, Policy);
2878 OS << ')';
2879 PrintExpr(E->getSubExpr());
2880}
2881
2882void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2883 BlockDecl *BD = Node->getBlockDecl();
2884 OS << "^";
2885
2886 const FunctionType *AFT = Node->getFunctionType();
2887
2888 if (isa<FunctionNoProtoType>(AFT)) {
2889 OS << "()";
2890 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2891 OS << '(';
2892 for (BlockDecl::param_iterator AI = BD->param_begin(),
2893 E = BD->param_end(); AI != E; ++AI) {
2894 if (AI != BD->param_begin()) OS << ", ";
2895 std::string ParamStr = (*AI)->getNameAsString();
2896 (*AI)->getType().print(OS, Policy, ParamStr);
2897 }
2898
2899 const auto *FT = cast<FunctionProtoType>(AFT);
2900 if (FT->isVariadic()) {
2901 if (!BD->param_empty()) OS << ", ";
2902 OS << "...";
2903 }
2904 OS << ')';
2905 }
2906 OS << "{ }";
2907}
2908
2909void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2910 PrintExpr(Node->getSourceExpr());
2911}
2912
2913void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2914 OS << "<recovery-expr>(";
2915 const char *Sep = "";
2916 for (Expr *E : Node->subExpressions()) {
2917 OS << Sep;
2918 PrintExpr(E);
2919 Sep = ", ";
2920 }
2921 OS << ')';
2922}
2923
2924void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2925 OS << "__builtin_astype(";
2926 PrintExpr(Node->getSrcExpr());
2927 OS << ", ";
2928 Node->getType().print(OS, Policy);
2929 OS << ")";
2930}
2931
2932void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
2933 PrintExpr(Node->getArgLValue());
2934}
2935
2936//===----------------------------------------------------------------------===//
2937// Stmt method implementations
2938//===----------------------------------------------------------------------===//
2939
2940void Stmt::dumpPretty(const ASTContext &Context) const {
2941 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2942}
2943
2944void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2945 const PrintingPolicy &Policy, unsigned Indentation,
2946 StringRef NL, const ASTContext *Context) const {
2947 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2948 P.Visit(const_cast<Stmt *>(this));
2949}
2950
2951void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2952 const PrintingPolicy &Policy,
2953 unsigned Indentation, StringRef NL,
2954 const ASTContext *Context) const {
2955 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2956 P.PrintControlledStmt(const_cast<Stmt *>(this));
2957}
2958
2959void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2960 const PrintingPolicy &Policy, bool AddQuotes) const {
2961 std::string Buf;
2962 llvm::raw_string_ostream TempOut(Buf);
2963
2964 printPretty(TempOut, Helper, Policy);
2965
2966 Out << JsonFormat(TempOut.str(), AddQuotes);
2967}
2968
2969//===----------------------------------------------------------------------===//
2970// PrinterHelper
2971//===----------------------------------------------------------------------===//
2972
2973// 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:220
const LangOptions & getLangOpts() const
Definition ASTContext.h:926
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:3038
QualType getQueriedType() const
Definition ExprCXX.h:3042
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:4753
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition Decl.h:4748
param_iterator param_begin()
Definition Decl.h:4752
bool param_empty() const
Definition Decl.h:4751
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:2654
bool isGlobalDelete() const
Definition ExprCXX.h:2653
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:3971
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the member name.
Definition ExprCXX.h:3979
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4005
bool hasExplicitTemplateArgs() const
Determines whether this member expression actually had a C++ template argument list explicitly specif...
Definition ExprCXX.h:4045
Expr * getBase() const
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:3962
bool hasTemplateKeyword() const
Determines whether the member name was preceded by the template keyword.
Definition ExprCXX.h:4041
bool isImplicitAccess() const
True if this is an implicit access, i.e.
Definition ExprCXX.h:3954
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:4073
Expr * getRHS() const
Definition ExprCXX.h:5060
Expr * getLHS() const
Definition ExprCXX.h:5059
BinaryOperatorKind getOperator() const
Definition ExprCXX.h:5079
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:2466
QualType getAllocatedType() const
Definition ExprCXX.h:2436
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:2471
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition ExprCXX.h:2529
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2505
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2496
bool isParenTypeId() const
Definition ExprCXX.h:2517
bool isGlobalNew() const
Definition ExprCXX.h:2523
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2535
Expr * getOperand() const
Definition ExprCXX.h:4328
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Definition ExprCXX.h:114
ArrayRef< Expr * > getUserSpecifiedInitExprs()
Definition ExprCXX.h:5189
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition ExprCXX.h:2811
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:2805
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:2848
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:3801
QualType getTypeAsWritten() const
Retrieve the type that is being constructed, as specified in the source code.
Definition ExprCXX.h:3780
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:5617
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:5326
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:5426
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3620
bool hasExplicitTemplateArgs() const
Determines whether this lookup had explicit template arguments.
Definition ExprCXX.h:3596
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3564
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3593
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3548
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:3110
ExpressionTrait getTrait() const
Definition ExprCXX.h:3106
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:4703
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:4869
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:4939
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:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
Expr * getBase()
Fetches base expression of array shaping expression.
Definition ExprOpenMP.h:90
ArrayRef< Expr * > getDimensions() const
Fetches the dimensions for array shaping expression.
Definition ExprOpenMP.h:80
IteratorRange getIteratorRange(unsigned I)
Gets the iterator range for the given iterator.
Definition Expr.cpp: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:5591
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition ExprCXX.h:3282
NestedNameSpecifier getQualifier() const
Fetches the nested-name qualifier, if one was given.
Definition ExprCXX.h:3246
const DeclarationNameInfo & getNameInfo() const
Gets the full name info.
Definition ExprCXX.h:3237
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition ExprCXX.h:3279
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3339
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition ExprCXX.h:4394
Expr * getIndexExpr() const
Definition ExprCXX.h:4630
Expr * getPackIdExpression() const
Definition ExprCXX.h:4626
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:4511
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:8269
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition ExprCXX.h:2963
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition ExprCXX.h:2960
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition ExprCXX.h:2941
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:9167
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:8651
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:4220
Expr * getBase()
Retrieve the base object of this member expressions, e.g., the x in x.m.
Definition ExprCXX.h:4201
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:4233
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:723
@ CInit
C-style initialization with assignment.
Definition Decl.h:931
@ CallInit
Call-style initialization (C++98)
Definition Decl.h:934
Expr * getCond()
Definition Stmt.h: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:1728
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.