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