clang 21.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"
22#include "clang/AST/Expr.h"
23#include "clang/AST/ExprCXX.h"
24#include "clang/AST/ExprObjC.h"
29#include "clang/AST/Stmt.h"
30#include "clang/AST/StmtCXX.h"
31#include "clang/AST/StmtObjC.h"
33#include "clang/AST/StmtSYCL.h"
36#include "clang/AST/Type.h"
40#include "clang/Basic/LLVM.h"
41#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/SmallVector.h"
50#include "llvm/ADT/StringExtras.h"
51#include "llvm/ADT/StringRef.h"
52#include "llvm/Support/Casting.h"
53#include "llvm/Support/Compiler.h"
54#include "llvm/Support/ErrorHandling.h"
55#include "llvm/Support/raw_ostream.h"
56#include <cassert>
57#include <optional>
58#include <string>
59
60using namespace clang;
61
62//===----------------------------------------------------------------------===//
63// StmtPrinter Visitor
64//===----------------------------------------------------------------------===//
65
66namespace {
67
68 class StmtPrinter : public StmtVisitor<StmtPrinter> {
69 raw_ostream &OS;
70 unsigned IndentLevel;
71 PrinterHelper* Helper;
72 PrintingPolicy Policy;
73 std::string NL;
74 const ASTContext *Context;
75
76 public:
77 StmtPrinter(raw_ostream &os, PrinterHelper *helper,
78 const PrintingPolicy &Policy, unsigned Indentation = 0,
79 StringRef NL = "\n", const ASTContext *Context = nullptr)
80 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
81 NL(NL), Context(Context) {}
82
83 void PrintStmt(Stmt *S) { PrintStmt(S, Policy.Indentation); }
84
85 void PrintStmt(Stmt *S, int SubIndent) {
86 IndentLevel += SubIndent;
87 if (isa_and_nonnull<Expr>(S)) {
88 // If this is an expr used in a stmt context, indent and newline it.
89 Indent();
90 Visit(S);
91 OS << ";" << NL;
92 } else if (S) {
93 Visit(S);
94 } else {
95 Indent() << "<<<NULL STATEMENT>>>" << NL;
96 }
97 IndentLevel -= SubIndent;
98 }
99
100 void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {
101 // FIXME: Cope better with odd prefix widths.
102 IndentLevel += (PrefixWidth + 1) / 2;
103 if (auto *DS = dyn_cast<DeclStmt>(S))
104 PrintRawDeclStmt(DS);
105 else
106 PrintExpr(cast<Expr>(S));
107 OS << "; ";
108 IndentLevel -= (PrefixWidth + 1) / 2;
109 }
110
111 void PrintControlledStmt(Stmt *S) {
112 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
113 OS << " ";
114 PrintRawCompoundStmt(CS);
115 OS << NL;
116 } else {
117 OS << NL;
118 PrintStmt(S);
119 }
120 }
121
122 void PrintRawCompoundStmt(CompoundStmt *S);
123 void PrintRawDecl(Decl *D);
124 void PrintRawDeclStmt(const DeclStmt *S);
125 void PrintRawIfStmt(IfStmt *If);
126 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
127 void PrintCallArgs(CallExpr *E);
128 void PrintRawSEHExceptHandler(SEHExceptStmt *S);
129 void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
130 void PrintOMPExecutableDirective(OMPExecutableDirective *S,
131 bool ForceNoStmt = false);
132 void PrintFPPragmas(CompoundStmt *S);
133 void PrintOpenACCClauseList(OpenACCConstructStmt *S);
134 void PrintOpenACCConstruct(OpenACCConstructStmt *S);
135
136 void PrintExpr(Expr *E) {
137 if (E)
138 Visit(E);
139 else
140 OS << "<null expr>";
141 }
142
143 raw_ostream &Indent(int Delta = 0) {
144 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
145 OS << " ";
146 return OS;
147 }
148
149 void Visit(Stmt* S) {
150 if (Helper && Helper->handledStmt(S,OS))
151 return;
153 }
154
155 void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
156 Indent() << "<<unknown stmt type>>" << NL;
157 }
158
159 void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
160 OS << "<<unknown expr type>>";
161 }
162
163 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
164
165#define ABSTRACT_STMT(CLASS)
166#define STMT(CLASS, PARENT) \
167 void Visit##CLASS(CLASS *Node);
168#include "clang/AST/StmtNodes.inc"
169 };
170
171} // namespace
172
173//===----------------------------------------------------------------------===//
174// Stmt printing methods.
175//===----------------------------------------------------------------------===//
176
177/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
178/// with no newline after the }.
179void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
180 assert(Node && "Compound statement cannot be null");
181 OS << "{" << NL;
182 PrintFPPragmas(Node);
183 for (auto *I : Node->body())
184 PrintStmt(I);
185
186 Indent() << "}";
187}
188
189void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {
190 if (!S->hasStoredFPFeatures())
191 return;
192 FPOptionsOverride FPO = S->getStoredFPFeatures();
193 bool FEnvAccess = false;
194 if (FPO.hasAllowFEnvAccessOverride()) {
195 FEnvAccess = FPO.getAllowFEnvAccessOverride();
196 Indent() << "#pragma STDC FENV_ACCESS " << (FEnvAccess ? "ON" : "OFF")
197 << NL;
198 }
199 if (FPO.hasSpecifiedExceptionModeOverride()) {
201 FPO.getSpecifiedExceptionModeOverride();
202 if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
203 Indent() << "#pragma clang fp exceptions(";
204 switch (FPO.getSpecifiedExceptionModeOverride()) {
205 default:
206 break;
207 case LangOptions::FPE_Ignore:
208 OS << "ignore";
209 break;
210 case LangOptions::FPE_MayTrap:
211 OS << "maytrap";
212 break;
213 case LangOptions::FPE_Strict:
214 OS << "strict";
215 break;
216 }
217 OS << ")\n";
218 }
219 }
220 if (FPO.hasConstRoundingModeOverride()) {
221 LangOptions::RoundingMode RM = FPO.getConstRoundingModeOverride();
222 Indent() << "#pragma STDC FENV_ROUND ";
223 switch (RM) {
224 case llvm::RoundingMode::TowardZero:
225 OS << "FE_TOWARDZERO";
226 break;
227 case llvm::RoundingMode::NearestTiesToEven:
228 OS << "FE_TONEAREST";
229 break;
230 case llvm::RoundingMode::TowardPositive:
231 OS << "FE_UPWARD";
232 break;
233 case llvm::RoundingMode::TowardNegative:
234 OS << "FE_DOWNWARD";
235 break;
236 case llvm::RoundingMode::NearestTiesToAway:
237 OS << "FE_TONEARESTFROMZERO";
238 break;
239 case llvm::RoundingMode::Dynamic:
240 OS << "FE_DYNAMIC";
241 break;
242 default:
243 llvm_unreachable("Invalid rounding mode");
244 }
245 OS << NL;
246 }
247}
248
249void StmtPrinter::PrintRawDecl(Decl *D) {
250 D->print(OS, Policy, IndentLevel);
251}
252
253void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
254 SmallVector<Decl *, 2> Decls(S->decls());
255 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
256}
257
258void StmtPrinter::VisitNullStmt(NullStmt *Node) {
259 Indent() << ";" << NL;
260}
261
262void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
263 Indent();
264 PrintRawDeclStmt(Node);
265 OS << ";" << NL;
266}
267
268void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
269 Indent();
270 PrintRawCompoundStmt(Node);
271 OS << "" << NL;
272}
273
274void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
275 Indent(-1) << "case ";
276 PrintExpr(Node->getLHS());
277 if (Node->getRHS()) {
278 OS << " ... ";
279 PrintExpr(Node->getRHS());
280 }
281 OS << ":" << NL;
282
283 PrintStmt(Node->getSubStmt(), 0);
284}
285
286void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
287 Indent(-1) << "default:" << NL;
288 PrintStmt(Node->getSubStmt(), 0);
289}
290
291void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
292 Indent(-1) << Node->getName() << ":" << NL;
293 PrintStmt(Node->getSubStmt(), 0);
294}
295
296void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
297 llvm::ArrayRef<const Attr *> Attrs = Node->getAttrs();
298 for (const auto *Attr : Attrs) {
299 Attr->printPretty(OS, Policy);
300 if (Attr != Attrs.back())
301 OS << ' ';
302 }
303
304 PrintStmt(Node->getSubStmt(), 0);
305}
306
307void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
308 if (If->isConsteval()) {
309 OS << "if ";
310 if (If->isNegatedConsteval())
311 OS << "!";
312 OS << "consteval";
313 OS << NL;
314 PrintStmt(If->getThen());
315 if (Stmt *Else = If->getElse()) {
316 Indent();
317 OS << "else";
318 PrintStmt(Else);
319 OS << NL;
320 }
321 return;
322 }
323
324 OS << "if (";
325 if (If->getInit())
326 PrintInitStmt(If->getInit(), 4);
327 if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
328 PrintRawDeclStmt(DS);
329 else
330 PrintExpr(If->getCond());
331 OS << ')';
332
333 if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
334 OS << ' ';
335 PrintRawCompoundStmt(CS);
336 OS << (If->getElse() ? " " : NL);
337 } else {
338 OS << NL;
339 PrintStmt(If->getThen());
340 if (If->getElse()) Indent();
341 }
342
343 if (Stmt *Else = If->getElse()) {
344 OS << "else";
345
346 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
347 OS << ' ';
348 PrintRawCompoundStmt(CS);
349 OS << NL;
350 } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
351 OS << ' ';
352 PrintRawIfStmt(ElseIf);
353 } else {
354 OS << NL;
355 PrintStmt(If->getElse());
356 }
357 }
358}
359
360void StmtPrinter::VisitIfStmt(IfStmt *If) {
361 Indent();
362 PrintRawIfStmt(If);
363}
364
365void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
366 Indent() << "switch (";
367 if (Node->getInit())
368 PrintInitStmt(Node->getInit(), 8);
369 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
370 PrintRawDeclStmt(DS);
371 else
372 PrintExpr(Node->getCond());
373 OS << ")";
374 PrintControlledStmt(Node->getBody());
375}
376
377void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
378 Indent() << "while (";
379 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
380 PrintRawDeclStmt(DS);
381 else
382 PrintExpr(Node->getCond());
383 OS << ")" << NL;
384 PrintStmt(Node->getBody());
385}
386
387void StmtPrinter::VisitDoStmt(DoStmt *Node) {
388 Indent() << "do ";
389 if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
390 PrintRawCompoundStmt(CS);
391 OS << " ";
392 } else {
393 OS << NL;
394 PrintStmt(Node->getBody());
395 Indent();
396 }
397
398 OS << "while (";
399 PrintExpr(Node->getCond());
400 OS << ");" << NL;
401}
402
403void StmtPrinter::VisitForStmt(ForStmt *Node) {
404 Indent() << "for (";
405 if (Node->getInit())
406 PrintInitStmt(Node->getInit(), 5);
407 else
408 OS << (Node->getCond() ? "; " : ";");
409 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
410 PrintRawDeclStmt(DS);
411 else if (Node->getCond())
412 PrintExpr(Node->getCond());
413 OS << ";";
414 if (Node->getInc()) {
415 OS << " ";
416 PrintExpr(Node->getInc());
417 }
418 OS << ")";
419 PrintControlledStmt(Node->getBody());
420}
421
422void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
423 Indent() << "for (";
424 if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
425 PrintRawDeclStmt(DS);
426 else
427 PrintExpr(cast<Expr>(Node->getElement()));
428 OS << " in ";
429 PrintExpr(Node->getCollection());
430 OS << ")";
431 PrintControlledStmt(Node->getBody());
432}
433
434void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
435 Indent() << "for (";
436 if (Node->getInit())
437 PrintInitStmt(Node->getInit(), 5);
438 PrintingPolicy SubPolicy(Policy);
439 SubPolicy.SuppressInitializers = true;
440 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
441 OS << " : ";
442 PrintExpr(Node->getRangeInit());
443 OS << ")";
444 PrintControlledStmt(Node->getBody());
445}
446
447void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
448 Indent();
449 if (Node->isIfExists())
450 OS << "__if_exists (";
451 else
452 OS << "__if_not_exists (";
453
454 if (NestedNameSpecifier *Qualifier
455 = Node->getQualifierLoc().getNestedNameSpecifier())
456 Qualifier->print(OS, Policy);
457
458 OS << Node->getNameInfo() << ") ";
459
460 PrintRawCompoundStmt(Node->getSubStmt());
461}
462
463void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
464 Indent() << "goto " << Node->getLabel()->getName() << ";";
465 if (Policy.IncludeNewlines) OS << NL;
466}
467
468void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
469 Indent() << "goto *";
470 PrintExpr(Node->getTarget());
471 OS << ";";
472 if (Policy.IncludeNewlines) OS << NL;
473}
474
475void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
476 Indent() << "continue;";
477 if (Policy.IncludeNewlines) OS << NL;
478}
479
480void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
481 Indent() << "break;";
482 if (Policy.IncludeNewlines) OS << NL;
483}
484
485void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
486 Indent() << "return";
487 if (Node->getRetValue()) {
488 OS << " ";
489 PrintExpr(Node->getRetValue());
490 }
491 OS << ";";
492 if (Policy.IncludeNewlines) OS << NL;
493}
494
495void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
496 Indent() << "asm ";
497
498 if (Node->isVolatile())
499 OS << "volatile ";
500
501 if (Node->isAsmGoto())
502 OS << "goto ";
503
504 OS << "(";
505 VisitStringLiteral(Node->getAsmString());
506
507 // Outputs
508 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
509 Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)
510 OS << " : ";
511
512 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
513 if (i != 0)
514 OS << ", ";
515
516 if (!Node->getOutputName(i).empty()) {
517 OS << '[';
518 OS << Node->getOutputName(i);
519 OS << "] ";
520 }
521
522 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
523 OS << " (";
524 Visit(Node->getOutputExpr(i));
525 OS << ")";
526 }
527
528 // Inputs
529 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||
530 Node->getNumLabels() != 0)
531 OS << " : ";
532
533 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
534 if (i != 0)
535 OS << ", ";
536
537 if (!Node->getInputName(i).empty()) {
538 OS << '[';
539 OS << Node->getInputName(i);
540 OS << "] ";
541 }
542
543 VisitStringLiteral(Node->getInputConstraintLiteral(i));
544 OS << " (";
545 Visit(Node->getInputExpr(i));
546 OS << ")";
547 }
548
549 // Clobbers
550 if (Node->getNumClobbers() != 0 || Node->getNumLabels())
551 OS << " : ";
552
553 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
554 if (i != 0)
555 OS << ", ";
556
557 VisitStringLiteral(Node->getClobberStringLiteral(i));
558 }
559
560 // Labels
561 if (Node->getNumLabels() != 0)
562 OS << " : ";
563
564 for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {
565 if (i != 0)
566 OS << ", ";
567 OS << Node->getLabelName(i);
568 }
569
570 OS << ");";
571 if (Policy.IncludeNewlines) OS << NL;
572}
573
574void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
575 // FIXME: Implement MS style inline asm statement printer.
576 Indent() << "__asm ";
577 if (Node->hasBraces())
578 OS << "{" << NL;
579 OS << Node->getAsmString() << NL;
580 if (Node->hasBraces())
581 Indent() << "}" << NL;
582}
583
584void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
585 PrintStmt(Node->getCapturedDecl()->getBody());
586}
587
588void StmtPrinter::VisitSYCLKernelCallStmt(SYCLKernelCallStmt *Node) {
589 PrintStmt(Node->getOutlinedFunctionDecl()->getBody());
590}
591
592void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
593 Indent() << "@try";
594 if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
595 PrintRawCompoundStmt(TS);
596 OS << NL;
597 }
598
599 for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) {
600 Indent() << "@catch(";
601 if (Decl *DS = catchStmt->getCatchParamDecl())
602 PrintRawDecl(DS);
603 OS << ")";
604 if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
605 PrintRawCompoundStmt(CS);
606 OS << NL;
607 }
608 }
609
610 if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
611 Indent() << "@finally";
612 if (auto *CS = dyn_cast<CompoundStmt>(FS->getFinallyBody())) {
613 PrintRawCompoundStmt(CS);
614 OS << NL;
615 }
616 }
617}
618
619void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
620}
621
622void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
623 Indent() << "@catch (...) { /* todo */ } " << NL;
624}
625
626void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
627 Indent() << "@throw";
628 if (Node->getThrowExpr()) {
629 OS << " ";
630 PrintExpr(Node->getThrowExpr());
631 }
632 OS << ";" << NL;
633}
634
635void StmtPrinter::VisitObjCAvailabilityCheckExpr(
637 OS << "@available(...)";
638}
639
640void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
641 Indent() << "@synchronized (";
642 PrintExpr(Node->getSynchExpr());
643 OS << ")";
644 PrintRawCompoundStmt(Node->getSynchBody());
645 OS << NL;
646}
647
648void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
649 Indent() << "@autoreleasepool";
650 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getSubStmt()));
651 OS << NL;
652}
653
654void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
655 OS << "catch (";
656 if (Decl *ExDecl = Node->getExceptionDecl())
657 PrintRawDecl(ExDecl);
658 else
659 OS << "...";
660 OS << ") ";
661 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
662}
663
664void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
665 Indent();
666 PrintRawCXXCatchStmt(Node);
667 OS << NL;
668}
669
670void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
671 Indent() << "try ";
672 PrintRawCompoundStmt(Node->getTryBlock());
673 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
674 OS << " ";
675 PrintRawCXXCatchStmt(Node->getHandler(i));
676 }
677 OS << NL;
678}
679
680void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
681 Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
682 PrintRawCompoundStmt(Node->getTryBlock());
683 SEHExceptStmt *E = Node->getExceptHandler();
684 SEHFinallyStmt *F = Node->getFinallyHandler();
685 if(E)
686 PrintRawSEHExceptHandler(E);
687 else {
688 assert(F && "Must have a finally block...");
689 PrintRawSEHFinallyStmt(F);
690 }
691 OS << NL;
692}
693
694void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
695 OS << "__finally ";
696 PrintRawCompoundStmt(Node->getBlock());
697 OS << NL;
698}
699
700void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
701 OS << "__except (";
702 VisitExpr(Node->getFilterExpr());
703 OS << ")" << NL;
704 PrintRawCompoundStmt(Node->getBlock());
705 OS << NL;
706}
707
708void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
709 Indent();
710 PrintRawSEHExceptHandler(Node);
711 OS << NL;
712}
713
714void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
715 Indent();
716 PrintRawSEHFinallyStmt(Node);
717 OS << NL;
718}
719
720void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
721 Indent() << "__leave;";
722 if (Policy.IncludeNewlines) OS << NL;
723}
724
725//===----------------------------------------------------------------------===//
726// OpenMP directives printing methods
727//===----------------------------------------------------------------------===//
728
729void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) {
730 PrintStmt(Node->getLoopStmt());
731}
732
733void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
734 bool ForceNoStmt) {
735 OMPClausePrinter Printer(OS, Policy);
736 ArrayRef<OMPClause *> Clauses = S->clauses();
737 for (auto *Clause : Clauses)
738 if (Clause && !Clause->isImplicit()) {
739 OS << ' ';
740 Printer.Visit(Clause);
741 }
742 OS << NL;
743 if (!ForceNoStmt && S->hasAssociatedStmt())
744 PrintStmt(S->getRawStmt());
745}
746
747void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) {
748 Indent() << "#pragma omp metadirective";
749 PrintOMPExecutableDirective(Node);
750}
751
752void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
753 Indent() << "#pragma omp parallel";
754 PrintOMPExecutableDirective(Node);
755}
756
757void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
758 Indent() << "#pragma omp simd";
759 PrintOMPExecutableDirective(Node);
760}
761
762void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {
763 Indent() << "#pragma omp tile";
764 PrintOMPExecutableDirective(Node);
765}
766
767void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {
768 Indent() << "#pragma omp unroll";
769 PrintOMPExecutableDirective(Node);
770}
771
772void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) {
773 Indent() << "#pragma omp reverse";
774 PrintOMPExecutableDirective(Node);
775}
776
777void StmtPrinter::VisitOMPInterchangeDirective(OMPInterchangeDirective *Node) {
778 Indent() << "#pragma omp interchange";
779 PrintOMPExecutableDirective(Node);
780}
781
782void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
783 Indent() << "#pragma omp for";
784 PrintOMPExecutableDirective(Node);
785}
786
787void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
788 Indent() << "#pragma omp for simd";
789 PrintOMPExecutableDirective(Node);
790}
791
792void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
793 Indent() << "#pragma omp sections";
794 PrintOMPExecutableDirective(Node);
795}
796
797void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
798 Indent() << "#pragma omp section";
799 PrintOMPExecutableDirective(Node);
800}
801
802void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {
803 Indent() << "#pragma omp scope";
804 PrintOMPExecutableDirective(Node);
805}
806
807void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
808 Indent() << "#pragma omp single";
809 PrintOMPExecutableDirective(Node);
810}
811
812void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
813 Indent() << "#pragma omp master";
814 PrintOMPExecutableDirective(Node);
815}
816
817void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
818 Indent() << "#pragma omp critical";
819 if (Node->getDirectiveName().getName()) {
820 OS << " (";
821 Node->getDirectiveName().printName(OS, Policy);
822 OS << ")";
823 }
824 PrintOMPExecutableDirective(Node);
825}
826
827void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
828 Indent() << "#pragma omp parallel for";
829 PrintOMPExecutableDirective(Node);
830}
831
832void StmtPrinter::VisitOMPParallelForSimdDirective(
834 Indent() << "#pragma omp parallel for simd";
835 PrintOMPExecutableDirective(Node);
836}
837
838void StmtPrinter::VisitOMPParallelMasterDirective(
840 Indent() << "#pragma omp parallel master";
841 PrintOMPExecutableDirective(Node);
842}
843
844void StmtPrinter::VisitOMPParallelMaskedDirective(
846 Indent() << "#pragma omp parallel masked";
847 PrintOMPExecutableDirective(Node);
848}
849
850void StmtPrinter::VisitOMPParallelSectionsDirective(
852 Indent() << "#pragma omp parallel sections";
853 PrintOMPExecutableDirective(Node);
854}
855
856void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
857 Indent() << "#pragma omp task";
858 PrintOMPExecutableDirective(Node);
859}
860
861void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
862 Indent() << "#pragma omp taskyield";
863 PrintOMPExecutableDirective(Node);
864}
865
866void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
867 Indent() << "#pragma omp barrier";
868 PrintOMPExecutableDirective(Node);
869}
870
871void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
872 Indent() << "#pragma omp taskwait";
873 PrintOMPExecutableDirective(Node);
874}
875
876void StmtPrinter::VisitOMPAssumeDirective(OMPAssumeDirective *Node) {
877 Indent() << "#pragma omp assume";
878 PrintOMPExecutableDirective(Node);
879}
880
881void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
882 Indent() << "#pragma omp error";
883 PrintOMPExecutableDirective(Node);
884}
885
886void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
887 Indent() << "#pragma omp taskgroup";
888 PrintOMPExecutableDirective(Node);
889}
890
891void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
892 Indent() << "#pragma omp flush";
893 PrintOMPExecutableDirective(Node);
894}
895
896void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
897 Indent() << "#pragma omp depobj";
898 PrintOMPExecutableDirective(Node);
899}
900
901void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
902 Indent() << "#pragma omp scan";
903 PrintOMPExecutableDirective(Node);
904}
905
906void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
907 Indent() << "#pragma omp ordered";
908 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
909}
910
911void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
912 Indent() << "#pragma omp atomic";
913 PrintOMPExecutableDirective(Node);
914}
915
916void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
917 Indent() << "#pragma omp target";
918 PrintOMPExecutableDirective(Node);
919}
920
921void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
922 Indent() << "#pragma omp target data";
923 PrintOMPExecutableDirective(Node);
924}
925
926void StmtPrinter::VisitOMPTargetEnterDataDirective(
928 Indent() << "#pragma omp target enter data";
929 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
930}
931
932void StmtPrinter::VisitOMPTargetExitDataDirective(
934 Indent() << "#pragma omp target exit data";
935 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
936}
937
938void StmtPrinter::VisitOMPTargetParallelDirective(
940 Indent() << "#pragma omp target parallel";
941 PrintOMPExecutableDirective(Node);
942}
943
944void StmtPrinter::VisitOMPTargetParallelForDirective(
946 Indent() << "#pragma omp target parallel for";
947 PrintOMPExecutableDirective(Node);
948}
949
950void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
951 Indent() << "#pragma omp teams";
952 PrintOMPExecutableDirective(Node);
953}
954
955void StmtPrinter::VisitOMPCancellationPointDirective(
957 Indent() << "#pragma omp cancellation point "
958 << getOpenMPDirectiveName(Node->getCancelRegion());
959 PrintOMPExecutableDirective(Node);
960}
961
962void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
963 Indent() << "#pragma omp cancel "
964 << getOpenMPDirectiveName(Node->getCancelRegion());
965 PrintOMPExecutableDirective(Node);
966}
967
968void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
969 Indent() << "#pragma omp taskloop";
970 PrintOMPExecutableDirective(Node);
971}
972
973void StmtPrinter::VisitOMPTaskLoopSimdDirective(
975 Indent() << "#pragma omp taskloop simd";
976 PrintOMPExecutableDirective(Node);
977}
978
979void StmtPrinter::VisitOMPMasterTaskLoopDirective(
981 Indent() << "#pragma omp master taskloop";
982 PrintOMPExecutableDirective(Node);
983}
984
985void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
987 Indent() << "#pragma omp masked taskloop";
988 PrintOMPExecutableDirective(Node);
989}
990
991void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
993 Indent() << "#pragma omp master taskloop simd";
994 PrintOMPExecutableDirective(Node);
995}
996
997void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
999 Indent() << "#pragma omp masked taskloop simd";
1000 PrintOMPExecutableDirective(Node);
1001}
1002
1003void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
1005 Indent() << "#pragma omp parallel master taskloop";
1006 PrintOMPExecutableDirective(Node);
1007}
1008
1009void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
1011 Indent() << "#pragma omp parallel masked taskloop";
1012 PrintOMPExecutableDirective(Node);
1013}
1014
1015void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
1017 Indent() << "#pragma omp parallel master taskloop simd";
1018 PrintOMPExecutableDirective(Node);
1019}
1020
1021void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
1023 Indent() << "#pragma omp parallel masked taskloop simd";
1024 PrintOMPExecutableDirective(Node);
1025}
1026
1027void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1028 Indent() << "#pragma omp distribute";
1029 PrintOMPExecutableDirective(Node);
1030}
1031
1032void StmtPrinter::VisitOMPTargetUpdateDirective(
1034 Indent() << "#pragma omp target update";
1035 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1036}
1037
1038void StmtPrinter::VisitOMPDistributeParallelForDirective(
1040 Indent() << "#pragma omp distribute parallel for";
1041 PrintOMPExecutableDirective(Node);
1042}
1043
1044void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1046 Indent() << "#pragma omp distribute parallel for simd";
1047 PrintOMPExecutableDirective(Node);
1048}
1049
1050void StmtPrinter::VisitOMPDistributeSimdDirective(
1052 Indent() << "#pragma omp distribute simd";
1053 PrintOMPExecutableDirective(Node);
1054}
1055
1056void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1058 Indent() << "#pragma omp target parallel for simd";
1059 PrintOMPExecutableDirective(Node);
1060}
1061
1062void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1063 Indent() << "#pragma omp target simd";
1064 PrintOMPExecutableDirective(Node);
1065}
1066
1067void StmtPrinter::VisitOMPTeamsDistributeDirective(
1069 Indent() << "#pragma omp teams distribute";
1070 PrintOMPExecutableDirective(Node);
1071}
1072
1073void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1075 Indent() << "#pragma omp teams distribute simd";
1076 PrintOMPExecutableDirective(Node);
1077}
1078
1079void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1081 Indent() << "#pragma omp teams distribute parallel for simd";
1082 PrintOMPExecutableDirective(Node);
1083}
1084
1085void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1087 Indent() << "#pragma omp teams distribute parallel for";
1088 PrintOMPExecutableDirective(Node);
1089}
1090
1091void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1092 Indent() << "#pragma omp target teams";
1093 PrintOMPExecutableDirective(Node);
1094}
1095
1096void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1098 Indent() << "#pragma omp target teams distribute";
1099 PrintOMPExecutableDirective(Node);
1100}
1101
1102void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1104 Indent() << "#pragma omp target teams distribute parallel for";
1105 PrintOMPExecutableDirective(Node);
1106}
1107
1108void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1110 Indent() << "#pragma omp target teams distribute parallel for simd";
1111 PrintOMPExecutableDirective(Node);
1112}
1113
1114void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1116 Indent() << "#pragma omp target teams distribute simd";
1117 PrintOMPExecutableDirective(Node);
1118}
1119
1120void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1121 Indent() << "#pragma omp interop";
1122 PrintOMPExecutableDirective(Node);
1123}
1124
1125void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1126 Indent() << "#pragma omp dispatch";
1127 PrintOMPExecutableDirective(Node);
1128}
1129
1130void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1131 Indent() << "#pragma omp masked";
1132 PrintOMPExecutableDirective(Node);
1133}
1134
1135void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1136 Indent() << "#pragma omp loop";
1137 PrintOMPExecutableDirective(Node);
1138}
1139
1140void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1142 Indent() << "#pragma omp teams loop";
1143 PrintOMPExecutableDirective(Node);
1144}
1145
1146void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1148 Indent() << "#pragma omp target teams loop";
1149 PrintOMPExecutableDirective(Node);
1150}
1151
1152void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1154 Indent() << "#pragma omp parallel loop";
1155 PrintOMPExecutableDirective(Node);
1156}
1157
1158void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1160 Indent() << "#pragma omp target parallel loop";
1161 PrintOMPExecutableDirective(Node);
1162}
1163
1164//===----------------------------------------------------------------------===//
1165// OpenACC construct printing methods
1166//===----------------------------------------------------------------------===//
1167void StmtPrinter::PrintOpenACCClauseList(OpenACCConstructStmt *S) {
1168 if (!S->clauses().empty()) {
1169 OS << ' ';
1170 OpenACCClausePrinter Printer(OS, Policy);
1171 Printer.VisitClauseList(S->clauses());
1172 }
1173}
1174void StmtPrinter::PrintOpenACCConstruct(OpenACCConstructStmt *S) {
1175 Indent() << "#pragma acc " << S->getDirectiveKind();
1176 PrintOpenACCClauseList(S);
1177 OS << '\n';
1178}
1179void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
1180 PrintOpenACCConstruct(S);
1181 PrintStmt(S->getStructuredBlock());
1182}
1183
1184void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
1185 PrintOpenACCConstruct(S);
1186 PrintStmt(S->getLoop());
1187}
1188
1189void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {
1190 PrintOpenACCConstruct(S);
1191 PrintStmt(S->getLoop());
1192}
1193
1194void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {
1195 PrintOpenACCConstruct(S);
1196 PrintStmt(S->getStructuredBlock());
1197}
1198void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
1199 PrintOpenACCConstruct(S);
1200 PrintStmt(S->getStructuredBlock());
1201}
1202void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) {
1203 PrintOpenACCConstruct(S);
1204}
1205void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
1206 PrintOpenACCConstruct(S);
1207}
1208void StmtPrinter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
1209 PrintOpenACCConstruct(S);
1210}
1211void StmtPrinter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
1212 PrintOpenACCConstruct(S);
1213}
1214void StmtPrinter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {
1215 PrintOpenACCConstruct(S);
1216}
1217void StmtPrinter::VisitOpenACCUpdateConstruct(OpenACCUpdateConstruct *S) {
1218 PrintOpenACCConstruct(S);
1219}
1220
1221void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
1222 Indent() << "#pragma acc wait";
1223 if (!S->getLParenLoc().isInvalid()) {
1224 OS << "(";
1225 if (S->hasDevNumExpr()) {
1226 OS << "devnum: ";
1227 S->getDevNumExpr()->printPretty(OS, nullptr, Policy);
1228 OS << " : ";
1229 }
1230
1231 if (S->hasQueuesTag())
1232 OS << "queues: ";
1233
1234 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](const Expr *E) {
1235 E->printPretty(OS, nullptr, Policy);
1236 });
1237
1238 OS << ")";
1239 }
1240
1241 PrintOpenACCClauseList(S);
1242 OS << '\n';
1243}
1244
1245//===----------------------------------------------------------------------===//
1246// Expr printing methods.
1247//===----------------------------------------------------------------------===//
1248
1249void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1250 OS << Node->getBuiltinStr() << "()";
1251}
1252
1253void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
1254 llvm::report_fatal_error("Not implemented");
1255}
1256
1257void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1258 PrintExpr(Node->getSubExpr());
1259}
1260
1261void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1262 ValueDecl *VD = Node->getDecl();
1263 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(VD)) {
1264 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1265 return;
1266 }
1267 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(VD)) {
1268 TPOD->printAsExpr(OS, Policy);
1269 return;
1270 }
1271 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1272 Qualifier->print(OS, Policy);
1273 if (Node->hasTemplateKeyword())
1274 OS << "template ";
1275 DeclarationNameInfo NameInfo = Node->getNameInfo();
1276 if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
1277 ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier) {
1278 if (Policy.CleanUglifiedParameters &&
1279 isa<ParmVarDecl, NonTypeTemplateParmDecl>(VD) && ID)
1280 OS << ID->deuglifiedName();
1281 else
1282 NameInfo.printName(OS, Policy);
1283 } else {
1284 switch (VD->getKind()) {
1285 case Decl::NonTypeTemplateParm: {
1286 auto *TD = cast<NonTypeTemplateParmDecl>(VD);
1287 OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << "";
1288 break;
1289 }
1290 case Decl::ParmVar: {
1291 auto *PD = cast<ParmVarDecl>(VD);
1292 OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
1293 << PD->getFunctionScopeIndex();
1294 break;
1295 }
1296 case Decl::Decomposition:
1297 OS << "decomposition";
1298 for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
1299 OS << '-' << I->getName();
1300 break;
1301 default:
1302 OS << "unhandled-anonymous-" << VD->getDeclKindName();
1303 break;
1304 }
1305 }
1306 if (Node->hasExplicitTemplateArgs()) {
1307 const TemplateParameterList *TPL = nullptr;
1308 if (!Node->hadMultipleCandidates())
1309 if (auto *TD = dyn_cast<TemplateDecl>(VD))
1310 TPL = TD->getTemplateParameters();
1311 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1312 }
1313}
1314
1315void StmtPrinter::VisitDependentScopeDeclRefExpr(
1317 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1318 Qualifier->print(OS, Policy);
1319 if (Node->hasTemplateKeyword())
1320 OS << "template ";
1321 OS << Node->getNameInfo();
1322 if (Node->hasExplicitTemplateArgs())
1323 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1324}
1325
1326void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1327 if (Node->getQualifier())
1328 Node->getQualifier()->print(OS, Policy);
1329 if (Node->hasTemplateKeyword())
1330 OS << "template ";
1331 OS << Node->getNameInfo();
1332 if (Node->hasExplicitTemplateArgs())
1333 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1334}
1335
1336static bool isImplicitSelf(const Expr *E) {
1337 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1338 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1339 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1340 DRE->getBeginLoc().isInvalid())
1341 return true;
1342 }
1343 }
1344 return false;
1345}
1346
1347void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1348 if (Node->getBase()) {
1349 if (!Policy.SuppressImplicitBase ||
1350 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1351 PrintExpr(Node->getBase());
1352 OS << (Node->isArrow() ? "->" : ".");
1353 }
1354 }
1355 OS << *Node->getDecl();
1356}
1357
1358void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1359 if (Node->isSuperReceiver())
1360 OS << "super.";
1361 else if (Node->isObjectReceiver() && Node->getBase()) {
1362 PrintExpr(Node->getBase());
1363 OS << ".";
1364 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1365 OS << Node->getClassReceiver()->getName() << ".";
1366 }
1367
1368 if (Node->isImplicitProperty()) {
1369 if (const auto *Getter = Node->getImplicitPropertyGetter())
1370 Getter->getSelector().print(OS);
1371 else
1373 Node->getImplicitPropertySetter()->getSelector());
1374 } else
1375 OS << Node->getExplicitProperty()->getName();
1376}
1377
1378void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1379 PrintExpr(Node->getBaseExpr());
1380 OS << "[";
1381 PrintExpr(Node->getKeyExpr());
1382 OS << "]";
1383}
1384
1385void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1387 OS << "__builtin_sycl_unique_stable_name(";
1388 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1389 OS << ")";
1390}
1391
1392void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1393 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1394}
1395
1396void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {
1397 OS << '*';
1398}
1399
1400void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1401 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1402}
1403
1404/// Prints the given expression using the original source text. Returns true on
1405/// success, false otherwise.
1406static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1407 const ASTContext *Context) {
1408 if (!Context)
1409 return false;
1410 bool Invalid = false;
1411 StringRef Source = Lexer::getSourceText(
1413 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1414 if (!Invalid) {
1415 OS << Source;
1416 return true;
1417 }
1418 return false;
1419}
1420
1421void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1422 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1423 return;
1424 bool isSigned = Node->getType()->isSignedIntegerType();
1425 OS << toString(Node->getValue(), 10, isSigned);
1426
1427 if (isa<BitIntType>(Node->getType())) {
1428 OS << (isSigned ? "wb" : "uwb");
1429 return;
1430 }
1431
1432 // Emit suffixes. Integer literals are always a builtin integer type.
1433 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1434 default: llvm_unreachable("Unexpected type for integer literal!");
1435 case BuiltinType::Char_S:
1436 case BuiltinType::Char_U: OS << "i8"; break;
1437 case BuiltinType::UChar: OS << "Ui8"; break;
1438 case BuiltinType::SChar: OS << "i8"; break;
1439 case BuiltinType::Short: OS << "i16"; break;
1440 case BuiltinType::UShort: OS << "Ui16"; break;
1441 case BuiltinType::Int: break; // no suffix.
1442 case BuiltinType::UInt: OS << 'U'; break;
1443 case BuiltinType::Long: OS << 'L'; break;
1444 case BuiltinType::ULong: OS << "UL"; break;
1445 case BuiltinType::LongLong: OS << "LL"; break;
1446 case BuiltinType::ULongLong: OS << "ULL"; break;
1447 case BuiltinType::Int128:
1448 break; // no suffix.
1449 case BuiltinType::UInt128:
1450 break; // no suffix.
1451 case BuiltinType::WChar_S:
1452 case BuiltinType::WChar_U:
1453 break; // no suffix
1454 }
1455}
1456
1457void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1458 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1459 return;
1460 OS << Node->getValueAsString(/*Radix=*/10);
1461
1462 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1463 default: llvm_unreachable("Unexpected type for fixed point literal!");
1464 case BuiltinType::ShortFract: OS << "hr"; break;
1465 case BuiltinType::ShortAccum: OS << "hk"; break;
1466 case BuiltinType::UShortFract: OS << "uhr"; break;
1467 case BuiltinType::UShortAccum: OS << "uhk"; break;
1468 case BuiltinType::Fract: OS << "r"; break;
1469 case BuiltinType::Accum: OS << "k"; break;
1470 case BuiltinType::UFract: OS << "ur"; break;
1471 case BuiltinType::UAccum: OS << "uk"; break;
1472 case BuiltinType::LongFract: OS << "lr"; break;
1473 case BuiltinType::LongAccum: OS << "lk"; break;
1474 case BuiltinType::ULongFract: OS << "ulr"; break;
1475 case BuiltinType::ULongAccum: OS << "ulk"; break;
1476 }
1477}
1478
1479static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1480 bool PrintSuffix) {
1481 SmallString<16> Str;
1482 Node->getValue().toString(Str);
1483 OS << Str;
1484 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1485 OS << '.'; // Trailing dot in order to separate from ints.
1486
1487 if (!PrintSuffix)
1488 return;
1489
1490 // Emit suffixes. Float literals are always a builtin float type.
1491 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1492 default: llvm_unreachable("Unexpected type for float literal!");
1493 case BuiltinType::Half: break; // FIXME: suffix?
1494 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1495 case BuiltinType::Double: break; // no suffix.
1496 case BuiltinType::Float16: OS << "F16"; break;
1497 case BuiltinType::Float: OS << 'F'; break;
1498 case BuiltinType::LongDouble: OS << 'L'; break;
1499 case BuiltinType::Float128: OS << 'Q'; break;
1500 }
1501}
1502
1503void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1504 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1505 return;
1506 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1507}
1508
1509void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1510 PrintExpr(Node->getSubExpr());
1511 OS << "i";
1512}
1513
1514void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1515 Str->outputString(OS);
1516}
1517
1518void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1519 OS << "(";
1520 PrintExpr(Node->getSubExpr());
1521 OS << ")";
1522}
1523
1524void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1525 if (!Node->isPostfix()) {
1526 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1527
1528 // Print a space if this is an "identifier operator" like __real, or if
1529 // it might be concatenated incorrectly like '+'.
1530 switch (Node->getOpcode()) {
1531 default: break;
1532 case UO_Real:
1533 case UO_Imag:
1534 case UO_Extension:
1535 OS << ' ';
1536 break;
1537 case UO_Plus:
1538 case UO_Minus:
1539 if (isa<UnaryOperator>(Node->getSubExpr()))
1540 OS << ' ';
1541 break;
1542 }
1543 }
1544 PrintExpr(Node->getSubExpr());
1545
1546 if (Node->isPostfix())
1547 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1548}
1549
1550void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1551 OS << "__builtin_offsetof(";
1552 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1553 OS << ", ";
1554 bool PrintedSomething = false;
1555 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1556 OffsetOfNode ON = Node->getComponent(i);
1557 if (ON.getKind() == OffsetOfNode::Array) {
1558 // Array node
1559 OS << "[";
1560 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1561 OS << "]";
1562 PrintedSomething = true;
1563 continue;
1564 }
1565
1566 // Skip implicit base indirections.
1567 if (ON.getKind() == OffsetOfNode::Base)
1568 continue;
1569
1570 // Field or identifier node.
1571 const IdentifierInfo *Id = ON.getFieldName();
1572 if (!Id)
1573 continue;
1574
1575 if (PrintedSomething)
1576 OS << ".";
1577 else
1578 PrintedSomething = true;
1579 OS << Id->getName();
1580 }
1581 OS << ")";
1582}
1583
1584void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1586 const char *Spelling = getTraitSpelling(Node->getKind());
1587 if (Node->getKind() == UETT_AlignOf) {
1588 if (Policy.Alignof)
1589 Spelling = "alignof";
1590 else if (Policy.UnderscoreAlignof)
1591 Spelling = "_Alignof";
1592 else
1593 Spelling = "__alignof";
1594 }
1595
1596 OS << Spelling;
1597
1598 if (Node->isArgumentType()) {
1599 OS << '(';
1600 Node->getArgumentType().print(OS, Policy);
1601 OS << ')';
1602 } else {
1603 OS << " ";
1604 PrintExpr(Node->getArgumentExpr());
1605 }
1606}
1607
1608void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1609 OS << "_Generic(";
1610 if (Node->isExprPredicate())
1611 PrintExpr(Node->getControllingExpr());
1612 else
1613 Node->getControllingType()->getType().print(OS, Policy);
1614
1615 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1616 OS << ", ";
1617 QualType T = Assoc.getType();
1618 if (T.isNull())
1619 OS << "default";
1620 else
1621 T.print(OS, Policy);
1622 OS << ": ";
1623 PrintExpr(Assoc.getAssociationExpr());
1624 }
1625 OS << ")";
1626}
1627
1628void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1629 PrintExpr(Node->getLHS());
1630 OS << "[";
1631 PrintExpr(Node->getRHS());
1632 OS << "]";
1633}
1634
1635void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1636 PrintExpr(Node->getBase());
1637 OS << "[";
1638 PrintExpr(Node->getRowIdx());
1639 OS << "]";
1640 OS << "[";
1641 PrintExpr(Node->getColumnIdx());
1642 OS << "]";
1643}
1644
1645void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1646 PrintExpr(Node->getBase());
1647 OS << "[";
1648 if (Node->getLowerBound())
1649 PrintExpr(Node->getLowerBound());
1650 if (Node->getColonLocFirst().isValid()) {
1651 OS << ":";
1652 if (Node->getLength())
1653 PrintExpr(Node->getLength());
1654 }
1655 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1656 OS << ":";
1657 if (Node->getStride())
1658 PrintExpr(Node->getStride());
1659 }
1660 OS << "]";
1661}
1662
1663void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1664 OS << "(";
1665 for (Expr *E : Node->getDimensions()) {
1666 OS << "[";
1667 PrintExpr(E);
1668 OS << "]";
1669 }
1670 OS << ")";
1671 PrintExpr(Node->getBase());
1672}
1673
1674void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1675 OS << "iterator(";
1676 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1677 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1678 VD->getType().print(OS, Policy);
1679 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1680 OS << " " << VD->getName() << " = ";
1681 PrintExpr(Range.Begin);
1682 OS << ":";
1683 PrintExpr(Range.End);
1684 if (Range.Step) {
1685 OS << ":";
1686 PrintExpr(Range.Step);
1687 }
1688 if (I < E - 1)
1689 OS << ", ";
1690 }
1691 OS << ")";
1692}
1693
1694void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1695 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1696 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1697 // Don't print any defaulted arguments
1698 break;
1699 }
1700
1701 if (i) OS << ", ";
1702 PrintExpr(Call->getArg(i));
1703 }
1704}
1705
1706void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1707 PrintExpr(Call->getCallee());
1708 OS << "(";
1709 PrintCallArgs(Call);
1710 OS << ")";
1711}
1712
1713static bool isImplicitThis(const Expr *E) {
1714 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1715 return TE->isImplicit();
1716 return false;
1717}
1718
1719void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1720 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1721 PrintExpr(Node->getBase());
1722
1723 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1724 FieldDecl *ParentDecl =
1725 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1726 : nullptr;
1727
1728 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1729 OS << (Node->isArrow() ? "->" : ".");
1730 }
1731
1732 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1733 if (FD->isAnonymousStructOrUnion())
1734 return;
1735
1736 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1737 Qualifier->print(OS, Policy);
1738 if (Node->hasTemplateKeyword())
1739 OS << "template ";
1740 OS << Node->getMemberNameInfo();
1741 const TemplateParameterList *TPL = nullptr;
1742 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1743 if (!Node->hadMultipleCandidates())
1744 if (auto *FTD = FD->getPrimaryTemplate())
1745 TPL = FTD->getTemplateParameters();
1746 } else if (auto *VTSD =
1747 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1748 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1749 if (Node->hasExplicitTemplateArgs())
1750 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1751}
1752
1753void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1754 PrintExpr(Node->getBase());
1755 OS << (Node->isArrow() ? "->isa" : ".isa");
1756}
1757
1758void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1759 PrintExpr(Node->getBase());
1760 OS << ".";
1761 OS << Node->getAccessor().getName();
1762}
1763
1764void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1765 OS << '(';
1766 Node->getTypeAsWritten().print(OS, Policy);
1767 OS << ')';
1768 PrintExpr(Node->getSubExpr());
1769}
1770
1771void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1772 OS << '(';
1773 Node->getType().print(OS, Policy);
1774 OS << ')';
1775 PrintExpr(Node->getInitializer());
1776}
1777
1778void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1779 // No need to print anything, simply forward to the subexpression.
1780 PrintExpr(Node->getSubExpr());
1781}
1782
1783void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1784 PrintExpr(Node->getLHS());
1785 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1786 PrintExpr(Node->getRHS());
1787}
1788
1789void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1790 PrintExpr(Node->getLHS());
1791 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1792 PrintExpr(Node->getRHS());
1793}
1794
1795void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1796 PrintExpr(Node->getCond());
1797 OS << " ? ";
1798 PrintExpr(Node->getLHS());
1799 OS << " : ";
1800 PrintExpr(Node->getRHS());
1801}
1802
1803// GNU extensions.
1804
1805void
1806StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1807 PrintExpr(Node->getCommon());
1808 OS << " ?: ";
1809 PrintExpr(Node->getFalseExpr());
1810}
1811
1812void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1813 OS << "&&" << Node->getLabel()->getName();
1814}
1815
1816void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1817 OS << "(";
1818 PrintRawCompoundStmt(E->getSubStmt());
1819 OS << ")";
1820}
1821
1822void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1823 OS << "__builtin_choose_expr(";
1824 PrintExpr(Node->getCond());
1825 OS << ", ";
1826 PrintExpr(Node->getLHS());
1827 OS << ", ";
1828 PrintExpr(Node->getRHS());
1829 OS << ")";
1830}
1831
1832void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1833 OS << "__null";
1834}
1835
1836void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1837 OS << "__builtin_shufflevector(";
1838 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1839 if (i) OS << ", ";
1840 PrintExpr(Node->getExpr(i));
1841 }
1842 OS << ")";
1843}
1844
1845void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1846 OS << "__builtin_convertvector(";
1847 PrintExpr(Node->getSrcExpr());
1848 OS << ", ";
1849 Node->getType().print(OS, Policy);
1850 OS << ")";
1851}
1852
1853void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1854 if (Node->getSyntacticForm()) {
1855 Visit(Node->getSyntacticForm());
1856 return;
1857 }
1858
1859 OS << "{";
1860 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1861 if (i) OS << ", ";
1862 if (Node->getInit(i))
1863 PrintExpr(Node->getInit(i));
1864 else
1865 OS << "{}";
1866 }
1867 OS << "}";
1868}
1869
1870void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1871 // There's no way to express this expression in any of our supported
1872 // languages, so just emit something terse and (hopefully) clear.
1873 OS << "{";
1874 PrintExpr(Node->getSubExpr());
1875 OS << "}";
1876}
1877
1878void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1879 OS << "*";
1880}
1881
1882void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1883 OS << "(";
1884 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1885 if (i) OS << ", ";
1886 PrintExpr(Node->getExpr(i));
1887 }
1888 OS << ")";
1889}
1890
1891void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1892 bool NeedsEquals = true;
1893 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1894 if (D.isFieldDesignator()) {
1895 if (D.getDotLoc().isInvalid()) {
1896 if (const IdentifierInfo *II = D.getFieldName()) {
1897 OS << II->getName() << ":";
1898 NeedsEquals = false;
1899 }
1900 } else {
1901 OS << "." << D.getFieldName()->getName();
1902 }
1903 } else {
1904 OS << "[";
1905 if (D.isArrayDesignator()) {
1906 PrintExpr(Node->getArrayIndex(D));
1907 } else {
1908 PrintExpr(Node->getArrayRangeStart(D));
1909 OS << " ... ";
1910 PrintExpr(Node->getArrayRangeEnd(D));
1911 }
1912 OS << "]";
1913 }
1914 }
1915
1916 if (NeedsEquals)
1917 OS << " = ";
1918 else
1919 OS << " ";
1920 PrintExpr(Node->getInit());
1921}
1922
1923void StmtPrinter::VisitDesignatedInitUpdateExpr(
1925 OS << "{";
1926 OS << "/*base*/";
1927 PrintExpr(Node->getBase());
1928 OS << ", ";
1929
1930 OS << "/*updater*/";
1931 PrintExpr(Node->getUpdater());
1932 OS << "}";
1933}
1934
1935void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1936 OS << "/*no init*/";
1937}
1938
1939void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1940 if (Node->getType()->getAsCXXRecordDecl()) {
1941 OS << "/*implicit*/";
1942 Node->getType().print(OS, Policy);
1943 OS << "()";
1944 } else {
1945 OS << "/*implicit*/(";
1946 Node->getType().print(OS, Policy);
1947 OS << ')';
1948 if (Node->getType()->isRecordType())
1949 OS << "{}";
1950 else
1951 OS << 0;
1952 }
1953}
1954
1955void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1956 OS << "__builtin_va_arg(";
1957 PrintExpr(Node->getSubExpr());
1958 OS << ", ";
1959 Node->getType().print(OS, Policy);
1960 OS << ")";
1961}
1962
1963void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1964 PrintExpr(Node->getSyntacticForm());
1965}
1966
1967void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1968 const char *Name = nullptr;
1969 switch (Node->getOp()) {
1970#define BUILTIN(ID, TYPE, ATTRS)
1971#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1972 case AtomicExpr::AO ## ID: \
1973 Name = #ID "("; \
1974 break;
1975#include "clang/Basic/Builtins.inc"
1976 }
1977 OS << Name;
1978
1979 // AtomicExpr stores its subexpressions in a permuted order.
1980 PrintExpr(Node->getPtr());
1981 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1982 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1983 Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
1984 Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
1985 Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
1986 OS << ", ";
1987 PrintExpr(Node->getVal1());
1988 }
1989 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1990 Node->isCmpXChg()) {
1991 OS << ", ";
1992 PrintExpr(Node->getVal2());
1993 }
1994 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1995 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1996 OS << ", ";
1997 PrintExpr(Node->getWeak());
1998 }
1999 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
2000 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
2001 OS << ", ";
2002 PrintExpr(Node->getOrder());
2003 }
2004 if (Node->isCmpXChg()) {
2005 OS << ", ";
2006 PrintExpr(Node->getOrderFail());
2007 }
2008 OS << ")";
2009}
2010
2011// C++
2012void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
2013 OverloadedOperatorKind Kind = Node->getOperator();
2014 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
2015 if (Node->getNumArgs() == 1) {
2016 OS << getOperatorSpelling(Kind) << ' ';
2017 PrintExpr(Node->getArg(0));
2018 } else {
2019 PrintExpr(Node->getArg(0));
2020 OS << ' ' << getOperatorSpelling(Kind);
2021 }
2022 } else if (Kind == OO_Arrow) {
2023 PrintExpr(Node->getArg(0));
2024 } else if (Kind == OO_Call || Kind == OO_Subscript) {
2025 PrintExpr(Node->getArg(0));
2026 OS << (Kind == OO_Call ? '(' : '[');
2027 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
2028 if (ArgIdx > 1)
2029 OS << ", ";
2030 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
2031 PrintExpr(Node->getArg(ArgIdx));
2032 }
2033 OS << (Kind == OO_Call ? ')' : ']');
2034 } else if (Node->getNumArgs() == 1) {
2035 OS << getOperatorSpelling(Kind) << ' ';
2036 PrintExpr(Node->getArg(0));
2037 } else if (Node->getNumArgs() == 2) {
2038 PrintExpr(Node->getArg(0));
2039 OS << ' ' << getOperatorSpelling(Kind) << ' ';
2040 PrintExpr(Node->getArg(1));
2041 } else {
2042 llvm_unreachable("unknown overloaded operator");
2043 }
2044}
2045
2046void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2047 // If we have a conversion operator call only print the argument.
2048 CXXMethodDecl *MD = Node->getMethodDecl();
2049 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2050 PrintExpr(Node->getImplicitObjectArgument());
2051 return;
2052 }
2053 VisitCallExpr(cast<CallExpr>(Node));
2054}
2055
2056void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2057 PrintExpr(Node->getCallee());
2058 OS << "<<<";
2059 PrintCallArgs(Node->getConfig());
2060 OS << ">>>(";
2061 PrintCallArgs(Node);
2062 OS << ")";
2063}
2064
2065void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2068 Node->getDecomposedForm();
2069 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
2070 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
2071 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
2072}
2073
2074void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2075 OS << Node->getCastName() << '<';
2076 Node->getTypeAsWritten().print(OS, Policy);
2077 OS << ">(";
2078 PrintExpr(Node->getSubExpr());
2079 OS << ")";
2080}
2081
2082void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2083 VisitCXXNamedCastExpr(Node);
2084}
2085
2086void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2087 VisitCXXNamedCastExpr(Node);
2088}
2089
2090void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2091 VisitCXXNamedCastExpr(Node);
2092}
2093
2094void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2095 VisitCXXNamedCastExpr(Node);
2096}
2097
2098void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2099 OS << "__builtin_bit_cast(";
2100 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2101 OS << ", ";
2102 PrintExpr(Node->getSubExpr());
2103 OS << ")";
2104}
2105
2106void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2107 VisitCXXNamedCastExpr(Node);
2108}
2109
2110void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2111 OS << "typeid(";
2112 if (Node->isTypeOperand()) {
2113 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2114 } else {
2115 PrintExpr(Node->getExprOperand());
2116 }
2117 OS << ")";
2118}
2119
2120void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2121 OS << "__uuidof(";
2122 if (Node->isTypeOperand()) {
2123 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2124 } else {
2125 PrintExpr(Node->getExprOperand());
2126 }
2127 OS << ")";
2128}
2129
2130void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2131 PrintExpr(Node->getBaseExpr());
2132 if (Node->isArrow())
2133 OS << "->";
2134 else
2135 OS << ".";
2136 if (NestedNameSpecifier *Qualifier =
2137 Node->getQualifierLoc().getNestedNameSpecifier())
2138 Qualifier->print(OS, Policy);
2139 OS << Node->getPropertyDecl()->getDeclName();
2140}
2141
2142void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2143 PrintExpr(Node->getBase());
2144 OS << "[";
2145 PrintExpr(Node->getIdx());
2146 OS << "]";
2147}
2148
2149void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2150 switch (Node->getLiteralOperatorKind()) {
2152 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2153 break;
2155 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2156 const TemplateArgumentList *Args =
2157 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2158 assert(Args);
2159
2160 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2161 const TemplateParameterList *TPL = nullptr;
2162 if (!DRE->hadMultipleCandidates())
2163 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2164 TPL = TD->getTemplateParameters();
2165 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2166 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2167 OS << "()";
2168 return;
2169 }
2170
2171 const TemplateArgument &Pack = Args->get(0);
2172 for (const auto &P : Pack.pack_elements()) {
2173 char C = (char)P.getAsIntegral().getZExtValue();
2174 OS << C;
2175 }
2176 break;
2177 }
2179 // Print integer literal without suffix.
2180 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2181 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2182 break;
2183 }
2185 // Print floating literal without suffix.
2186 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
2187 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2188 break;
2189 }
2192 PrintExpr(Node->getCookedLiteral());
2193 break;
2194 }
2195 OS << Node->getUDSuffix()->getName();
2196}
2197
2198void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2199 OS << (Node->getValue() ? "true" : "false");
2200}
2201
2202void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2203 OS << "nullptr";
2204}
2205
2206void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2207 OS << "this";
2208}
2209
2210void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2211 if (!Node->getSubExpr())
2212 OS << "throw";
2213 else {
2214 OS << "throw ";
2215 PrintExpr(Node->getSubExpr());
2216 }
2217}
2218
2219void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2220 // Nothing to print: we picked up the default argument.
2221}
2222
2223void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2224 // Nothing to print: we picked up the default initializer.
2225}
2226
2227void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2228 auto TargetType = Node->getType();
2229 auto *Auto = TargetType->getContainedDeducedType();
2230 bool Bare = Auto && Auto->isDeduced();
2231
2232 // Parenthesize deduced casts.
2233 if (Bare)
2234 OS << '(';
2235 TargetType.print(OS, Policy);
2236 if (Bare)
2237 OS << ')';
2238
2239 // No extra braces surrounding the inner construct.
2240 if (!Node->isListInitialization())
2241 OS << '(';
2242 PrintExpr(Node->getSubExpr());
2243 if (!Node->isListInitialization())
2244 OS << ')';
2245}
2246
2247void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2248 PrintExpr(Node->getSubExpr());
2249}
2250
2251void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2252 Node->getType().print(OS, Policy);
2253 if (Node->isStdInitListInitialization())
2254 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2255 else if (Node->isListInitialization())
2256 OS << "{";
2257 else
2258 OS << "(";
2259 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2260 ArgEnd = Node->arg_end();
2261 Arg != ArgEnd; ++Arg) {
2262 if ((*Arg)->isDefaultArgument())
2263 break;
2264 if (Arg != Node->arg_begin())
2265 OS << ", ";
2266 PrintExpr(*Arg);
2267 }
2268 if (Node->isStdInitListInitialization())
2269 /* See above. */;
2270 else if (Node->isListInitialization())
2271 OS << "}";
2272 else
2273 OS << ")";
2274}
2275
2276void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2277 OS << '[';
2278 bool NeedComma = false;
2279 switch (Node->getCaptureDefault()) {
2280 case LCD_None:
2281 break;
2282
2283 case LCD_ByCopy:
2284 OS << '=';
2285 NeedComma = true;
2286 break;
2287
2288 case LCD_ByRef:
2289 OS << '&';
2290 NeedComma = true;
2291 break;
2292 }
2293 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
2294 CEnd = Node->explicit_capture_end();
2295 C != CEnd;
2296 ++C) {
2297 if (C->capturesVLAType())
2298 continue;
2299
2300 if (NeedComma)
2301 OS << ", ";
2302 NeedComma = true;
2303
2304 switch (C->getCaptureKind()) {
2305 case LCK_This:
2306 OS << "this";
2307 break;
2308
2309 case LCK_StarThis:
2310 OS << "*this";
2311 break;
2312
2313 case LCK_ByRef:
2314 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2315 OS << '&';
2316 OS << C->getCapturedVar()->getName();
2317 break;
2318
2319 case LCK_ByCopy:
2320 OS << C->getCapturedVar()->getName();
2321 break;
2322
2323 case LCK_VLAType:
2324 llvm_unreachable("VLA type in explicit captures.");
2325 }
2326
2327 if (C->isPackExpansion())
2328 OS << "...";
2329
2330 if (Node->isInitCapture(C)) {
2331 // Init captures are always VarDecl.
2332 auto *D = cast<VarDecl>(C->getCapturedVar());
2333
2334 llvm::StringRef Pre;
2335 llvm::StringRef Post;
2336 if (D->getInitStyle() == VarDecl::CallInit &&
2337 !isa<ParenListExpr>(D->getInit())) {
2338 Pre = "(";
2339 Post = ")";
2340 } else if (D->getInitStyle() == VarDecl::CInit) {
2341 Pre = " = ";
2342 }
2343
2344 OS << Pre;
2345 PrintExpr(D->getInit());
2346 OS << Post;
2347 }
2348 }
2349 OS << ']';
2350
2351 if (!Node->getExplicitTemplateParameters().empty()) {
2352 Node->getTemplateParameterList()->print(
2353 OS, Node->getLambdaClass()->getASTContext(),
2354 /*OmitTemplateKW*/true);
2355 }
2356
2357 if (Node->hasExplicitParameters()) {
2358 OS << '(';
2359 CXXMethodDecl *Method = Node->getCallOperator();
2360 NeedComma = false;
2361 for (const auto *P : Method->parameters()) {
2362 if (NeedComma) {
2363 OS << ", ";
2364 } else {
2365 NeedComma = true;
2366 }
2367 std::string ParamStr =
2368 (Policy.CleanUglifiedParameters && P->getIdentifier())
2369 ? P->getIdentifier()->deuglifiedName().str()
2370 : P->getNameAsString();
2371 P->getOriginalType().print(OS, Policy, ParamStr);
2372 }
2373 if (Method->isVariadic()) {
2374 if (NeedComma)
2375 OS << ", ";
2376 OS << "...";
2377 }
2378 OS << ')';
2379
2380 if (Node->isMutable())
2381 OS << " mutable";
2382
2383 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2384 Proto->printExceptionSpecification(OS, Policy);
2385
2386 // FIXME: Attributes
2387
2388 // Print the trailing return type if it was specified in the source.
2389 if (Node->hasExplicitResultType()) {
2390 OS << " -> ";
2391 Proto->getReturnType().print(OS, Policy);
2392 }
2393 }
2394
2395 // Print the body.
2396 OS << ' ';
2397 if (Policy.TerseOutput)
2398 OS << "{}";
2399 else
2400 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2401}
2402
2403void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2404 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2405 TSInfo->getType().print(OS, Policy);
2406 else
2407 Node->getType().print(OS, Policy);
2408 OS << "()";
2409}
2410
2411void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2412 if (E->isGlobalNew())
2413 OS << "::";
2414 OS << "new ";
2415 unsigned NumPlace = E->getNumPlacementArgs();
2416 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2417 OS << "(";
2418 PrintExpr(E->getPlacementArg(0));
2419 for (unsigned i = 1; i < NumPlace; ++i) {
2420 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2421 break;
2422 OS << ", ";
2423 PrintExpr(E->getPlacementArg(i));
2424 }
2425 OS << ") ";
2426 }
2427 if (E->isParenTypeId())
2428 OS << "(";
2429 std::string TypeS;
2430 if (E->isArray()) {
2431 llvm::raw_string_ostream s(TypeS);
2432 s << '[';
2433 if (std::optional<Expr *> Size = E->getArraySize())
2434 (*Size)->printPretty(s, Helper, Policy);
2435 s << ']';
2436 }
2437 E->getAllocatedType().print(OS, Policy, TypeS);
2438 if (E->isParenTypeId())
2439 OS << ")";
2440
2441 CXXNewInitializationStyle InitStyle = E->getInitializationStyle();
2442 if (InitStyle != CXXNewInitializationStyle::None) {
2443 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2444 !isa<ParenListExpr>(E->getInitializer());
2445 if (Bare)
2446 OS << "(";
2447 PrintExpr(E->getInitializer());
2448 if (Bare)
2449 OS << ")";
2450 }
2451}
2452
2453void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2454 if (E->isGlobalDelete())
2455 OS << "::";
2456 OS << "delete ";
2457 if (E->isArrayForm())
2458 OS << "[] ";
2459 PrintExpr(E->getArgument());
2460}
2461
2462void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2463 PrintExpr(E->getBase());
2464 if (E->isArrow())
2465 OS << "->";
2466 else
2467 OS << '.';
2468 if (E->getQualifier())
2469 E->getQualifier()->print(OS, Policy);
2470 OS << "~";
2471
2472 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2473 OS << II->getName();
2474 else
2475 E->getDestroyedType().print(OS, Policy);
2476}
2477
2478void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2479 if (E->isListInitialization() && !E->isStdInitListInitialization())
2480 OS << "{";
2481
2482 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2483 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2484 // Don't print any defaulted arguments
2485 break;
2486 }
2487
2488 if (i) OS << ", ";
2489 PrintExpr(E->getArg(i));
2490 }
2491
2492 if (E->isListInitialization() && !E->isStdInitListInitialization())
2493 OS << "}";
2494}
2495
2496void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2497 // Parens are printed by the surrounding context.
2498 OS << "<forwarded>";
2499}
2500
2501void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2502 PrintExpr(E->getSubExpr());
2503}
2504
2505void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2506 // Just forward to the subexpression.
2507 PrintExpr(E->getSubExpr());
2508}
2509
2510void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2512 Node->getTypeAsWritten().print(OS, Policy);
2513 if (!Node->isListInitialization())
2514 OS << '(';
2515 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2516 ++Arg) {
2517 if (Arg != Node->arg_begin())
2518 OS << ", ";
2519 PrintExpr(*Arg);
2520 }
2521 if (!Node->isListInitialization())
2522 OS << ')';
2523}
2524
2525void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2527 if (!Node->isImplicitAccess()) {
2528 PrintExpr(Node->getBase());
2529 OS << (Node->isArrow() ? "->" : ".");
2530 }
2531 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2532 Qualifier->print(OS, Policy);
2533 if (Node->hasTemplateKeyword())
2534 OS << "template ";
2535 OS << Node->getMemberNameInfo();
2536 if (Node->hasExplicitTemplateArgs())
2537 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2538}
2539
2540void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2541 if (!Node->isImplicitAccess()) {
2542 PrintExpr(Node->getBase());
2543 OS << (Node->isArrow() ? "->" : ".");
2544 }
2545 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2546 Qualifier->print(OS, Policy);
2547 if (Node->hasTemplateKeyword())
2548 OS << "template ";
2549 OS << Node->getMemberNameInfo();
2550 if (Node->hasExplicitTemplateArgs())
2551 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2552}
2553
2554void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2555 OS << getTraitSpelling(E->getTrait()) << "(";
2556 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2557 if (I > 0)
2558 OS << ", ";
2559 E->getArg(I)->getType().print(OS, Policy);
2560 }
2561 OS << ")";
2562}
2563
2564void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2565 OS << getTraitSpelling(E->getTrait()) << '(';
2566 E->getQueriedType().print(OS, Policy);
2567 OS << ')';
2568}
2569
2570void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2571 OS << getTraitSpelling(E->getTrait()) << '(';
2572 PrintExpr(E->getQueriedExpression());
2573 OS << ')';
2574}
2575
2576void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2577 OS << "noexcept(";
2578 PrintExpr(E->getOperand());
2579 OS << ")";
2580}
2581
2582void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2583 PrintExpr(E->getPattern());
2584 OS << "...";
2585}
2586
2587void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2588 OS << "sizeof...(" << *E->getPack() << ")";
2589}
2590
2591void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2592 PrintExpr(E->getPackIdExpression());
2593 OS << "...[";
2594 PrintExpr(E->getIndexExpr());
2595 OS << "]";
2596}
2597
2598void StmtPrinter::VisitResolvedUnexpandedPackExpr(
2600 OS << "<<resolved pack(";
2601 llvm::interleave(
2602 E->getExprs().begin(), E->getExprs().end(),
2603 [this](auto *X) { PrintExpr(X); }, [this] { OS << ", "; });
2604 OS << ")>>";
2605}
2606
2607void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2609 OS << *Node->getParameterPack();
2610}
2611
2612void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2614 Visit(Node->getReplacement());
2615}
2616
2617void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2618 OS << *E->getParameterPack();
2619}
2620
2621void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2622 PrintExpr(Node->getSubExpr());
2623}
2624
2625void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2626 OS << "(";
2627 if (E->getLHS()) {
2628 PrintExpr(E->getLHS());
2629 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2630 }
2631 OS << "...";
2632 if (E->getRHS()) {
2633 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2634 PrintExpr(E->getRHS());
2635 }
2636 OS << ")";
2637}
2638
2639void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2640 OS << "(";
2641 llvm::interleaveComma(Node->getInitExprs(), OS,
2642 [&](Expr *E) { PrintExpr(E); });
2643 OS << ")";
2644}
2645
2646void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2647 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2648 if (NNS)
2649 NNS.getNestedNameSpecifier()->print(OS, Policy);
2650 if (E->getTemplateKWLoc().isValid())
2651 OS << "template ";
2652 OS << E->getFoundDecl()->getName();
2653 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2654 Policy,
2655 E->getNamedConcept()->getTemplateParameters());
2656}
2657
2658void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2659 OS << "requires ";
2660 auto LocalParameters = E->getLocalParameters();
2661 if (!LocalParameters.empty()) {
2662 OS << "(";
2663 for (ParmVarDecl *LocalParam : LocalParameters) {
2664 PrintRawDecl(LocalParam);
2665 if (LocalParam != LocalParameters.back())
2666 OS << ", ";
2667 }
2668
2669 OS << ") ";
2670 }
2671 OS << "{ ";
2672 auto Requirements = E->getRequirements();
2673 for (concepts::Requirement *Req : Requirements) {
2674 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2675 if (TypeReq->isSubstitutionFailure())
2676 OS << "<<error-type>>";
2677 else
2678 TypeReq->getType()->getType().print(OS, Policy);
2679 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2680 if (ExprReq->isCompound())
2681 OS << "{ ";
2682 if (ExprReq->isExprSubstitutionFailure())
2683 OS << "<<error-expression>>";
2684 else
2685 PrintExpr(ExprReq->getExpr());
2686 if (ExprReq->isCompound()) {
2687 OS << " }";
2688 if (ExprReq->getNoexceptLoc().isValid())
2689 OS << " noexcept";
2690 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2691 if (!RetReq.isEmpty()) {
2692 OS << " -> ";
2693 if (RetReq.isSubstitutionFailure())
2694 OS << "<<error-type>>";
2695 else if (RetReq.isTypeConstraint())
2696 RetReq.getTypeConstraint()->print(OS, Policy);
2697 }
2698 }
2699 } else {
2700 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2701 OS << "requires ";
2702 if (NestedReq->hasInvalidConstraint())
2703 OS << "<<error-expression>>";
2704 else
2705 PrintExpr(NestedReq->getConstraintExpr());
2706 }
2707 OS << "; ";
2708 }
2709 OS << "}";
2710}
2711
2712// C++ Coroutines
2713
2714void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2715 Visit(S->getBody());
2716}
2717
2718void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2719 OS << "co_return";
2720 if (S->getOperand()) {
2721 OS << " ";
2722 Visit(S->getOperand());
2723 }
2724 OS << ";";
2725}
2726
2727void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2728 OS << "co_await ";
2729 PrintExpr(S->getOperand());
2730}
2731
2732void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2733 OS << "co_await ";
2734 PrintExpr(S->getOperand());
2735}
2736
2737void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2738 OS << "co_yield ";
2739 PrintExpr(S->getOperand());
2740}
2741
2742// Obj-C
2743
2744void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2745 OS << "@";
2746 VisitStringLiteral(Node->getString());
2747}
2748
2749void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2750 OS << "@";
2751 Visit(E->getSubExpr());
2752}
2753
2754void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2755 OS << "@[ ";
2757 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2758 if (I != Ch.begin())
2759 OS << ", ";
2760 Visit(*I);
2761 }
2762 OS << " ]";
2763}
2764
2765void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2766 OS << "@{ ";
2767 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2768 if (I > 0)
2769 OS << ", ";
2770
2771 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2772 Visit(Element.Key);
2773 OS << " : ";
2774 Visit(Element.Value);
2775 if (Element.isPackExpansion())
2776 OS << "...";
2777 }
2778 OS << " }";
2779}
2780
2781void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2782 OS << "@encode(";
2783 Node->getEncodedType().print(OS, Policy);
2784 OS << ')';
2785}
2786
2787void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2788 OS << "@selector(";
2789 Node->getSelector().print(OS);
2790 OS << ')';
2791}
2792
2793void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2794 OS << "@protocol(" << *Node->getProtocol() << ')';
2795}
2796
2797void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2798 OS << "[";
2799 switch (Mess->getReceiverKind()) {
2801 PrintExpr(Mess->getInstanceReceiver());
2802 break;
2803
2805 Mess->getClassReceiver().print(OS, Policy);
2806 break;
2807
2810 OS << "Super";
2811 break;
2812 }
2813
2814 OS << ' ';
2815 Selector selector = Mess->getSelector();
2816 if (selector.isUnarySelector()) {
2817 OS << selector.getNameForSlot(0);
2818 } else {
2819 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2820 if (i < selector.getNumArgs()) {
2821 if (i > 0) OS << ' ';
2822 if (selector.getIdentifierInfoForSlot(i))
2823 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2824 else
2825 OS << ":";
2826 }
2827 else OS << ", "; // Handle variadic methods.
2828
2829 PrintExpr(Mess->getArg(i));
2830 }
2831 }
2832 OS << "]";
2833}
2834
2835void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2836 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2837}
2838
2839void
2840StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2841 PrintExpr(E->getSubExpr());
2842}
2843
2844void
2845StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2846 OS << '(' << E->getBridgeKindName();
2847 E->getType().print(OS, Policy);
2848 OS << ')';
2849 PrintExpr(E->getSubExpr());
2850}
2851
2852void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2853 BlockDecl *BD = Node->getBlockDecl();
2854 OS << "^";
2855
2856 const FunctionType *AFT = Node->getFunctionType();
2857
2858 if (isa<FunctionNoProtoType>(AFT)) {
2859 OS << "()";
2860 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2861 OS << '(';
2862 for (BlockDecl::param_iterator AI = BD->param_begin(),
2863 E = BD->param_end(); AI != E; ++AI) {
2864 if (AI != BD->param_begin()) OS << ", ";
2865 std::string ParamStr = (*AI)->getNameAsString();
2866 (*AI)->getType().print(OS, Policy, ParamStr);
2867 }
2868
2869 const auto *FT = cast<FunctionProtoType>(AFT);
2870 if (FT->isVariadic()) {
2871 if (!BD->param_empty()) OS << ", ";
2872 OS << "...";
2873 }
2874 OS << ')';
2875 }
2876 OS << "{ }";
2877}
2878
2879void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2880 PrintExpr(Node->getSourceExpr());
2881}
2882
2883void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2884 // TODO: Print something reasonable for a TypoExpr, if necessary.
2885 llvm_unreachable("Cannot print TypoExpr nodes");
2886}
2887
2888void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2889 OS << "<recovery-expr>(";
2890 const char *Sep = "";
2891 for (Expr *E : Node->subExpressions()) {
2892 OS << Sep;
2893 PrintExpr(E);
2894 Sep = ", ";
2895 }
2896 OS << ')';
2897}
2898
2899void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2900 OS << "__builtin_astype(";
2901 PrintExpr(Node->getSrcExpr());
2902 OS << ", ";
2903 Node->getType().print(OS, Policy);
2904 OS << ")";
2905}
2906
2907void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
2908 PrintExpr(Node->getArgLValue());
2909}
2910
2911//===----------------------------------------------------------------------===//
2912// Stmt method implementations
2913//===----------------------------------------------------------------------===//
2914
2915void Stmt::dumpPretty(const ASTContext &Context) const {
2916 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2917}
2918
2919void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2920 const PrintingPolicy &Policy, unsigned Indentation,
2921 StringRef NL, const ASTContext *Context) const {
2922 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2923 P.Visit(const_cast<Stmt *>(this));
2924}
2925
2926void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2927 const PrintingPolicy &Policy,
2928 unsigned Indentation, StringRef NL,
2929 const ASTContext *Context) const {
2930 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2931 P.PrintControlledStmt(const_cast<Stmt *>(this));
2932}
2933
2934void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2935 const PrintingPolicy &Policy, bool AddQuotes) const {
2936 std::string Buf;
2937 llvm::raw_string_ostream TempOut(Buf);
2938
2939 printPretty(TempOut, Helper, Policy);
2940
2941 Out << JsonFormat(TempOut.str(), AddQuotes);
2942}
2943
2944//===----------------------------------------------------------------------===//
2945// PrinterHelper
2946//===----------------------------------------------------------------------===//
2947
2948// Implement virtual destructor.
Defines the clang::ASTContext interface.
DynTypedNode Node
StringRef P
const Decl * D
Expr * E
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1181
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines enumerations for expression traits intrinsics.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
#define X(type, name)
Definition: Value.h:144
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.
uint32_t Id
Definition: SemaARM.cpp:1122
SourceRange Range
Definition: SemaObjC.cpp:758
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
SourceManager & getSourceManager()
Definition: ASTContext.h:741
const LangOptions & getLangOpts() const
Definition: ASTContext.h:834
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4421
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5805
Represents a loop initializing the elements of an array.
Definition: Expr.h:5752
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition: Expr.h:6986
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2718
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2853
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition: Expr.h:6475
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6678
Attr - This represents one attribute.
Definition: Attr.h:43
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const
Represents an attribute applied to a statement.
Definition: Stmt.h:2107
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4324
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3909
StringRef getOpcodeStr() const
Definition: Expr.h:3975
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4503
param_iterator param_end()
Definition: Decl.h:4602
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition: Decl.h:4597
param_iterator param_begin()
Definition: Decl.h:4601
bool param_empty() const
Definition: Decl.h:4600
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6414
BreakStmt - This represents a break.
Definition: Stmt.h:3007
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5296
This class is used for builtin types like 'int'.
Definition: Type.h:3035
Kind getKind() const
Definition: Type.h:3083
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition: Expr.h:3840
Represents a call to a CUDA kernel function.
Definition: ExprCXX.h:231
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition: ExprCXX.h:601
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1491
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
A C++ const_cast expression (C++ [expr.const.cast]).
Definition: ExprCXX.h:563
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1546
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1268
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1375
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2498
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition: ExprCXX.h:3683
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition: ExprCXX.h:478
Represents a folding of a pack over an operator.
Definition: ExprCXX.h:4844
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Definition: ExprCXX.h:1817
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1737
Represents a call to a member function that may be written either with member call syntax (e....
Definition: ExprCXX.h:176
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2117
Abstract class common to all of the C++ "named"/"keyword" casts.
Definition: ExprCXX.h:372
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2241
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4126
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:81
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4958
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition: ExprCXX.h:2617
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
A rewritten comparison expression that was originally written using operator syntax.
Definition: ExprCXX.h:283
An expression "T()" which creates an rvalue of a non-class type T.
Definition: ExprCXX.h:2182
A C++ static_cast expression (C++ [expr.static.cast]).
Definition: ExprCXX.h:433
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition: ExprCXX.h:797
Represents a C++ functional cast expression that builds a temporary object.
Definition: ExprCXX.h:1885
Represents the this expression in C++.
Definition: ExprCXX.h:1152
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1206
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:69
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:845
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition: ExprCXX.h:3557
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition: ExprCXX.h:1066
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2874
This captures a statement into a function.
Definition: Stmt.h:3784
CaseStmt - Represent a case statement.
Definition: Stmt.h:1828
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition: Expr.cpp:1024
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4641
Represents a 'co_await' expression.
Definition: ExprCXX.h:5189
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4171
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3477
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1628
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4262
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1077
ContinueStmt - This represents a continue.
Definition: Stmt.h:2977
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4582
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition: StmtCXX.h:473
Represents the body of a coroutine.
Definition: StmtCXX.h:320
Represents a 'co_yield' expression.
Definition: ExprCXX.h:5270
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1265
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1519
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
const char * getDeclKindName() const
Definition: DeclBase.cpp:150
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:445
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.
Represents a 'co_await' expression while the type of the promise is dependent.
Definition: ExprCXX.h:5221
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3323
Represents a single C99 designator.
Definition: Expr.h:5376
Represents a C99 designated initializer expression.
Definition: Expr.h:5333
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2752
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
Represents a reference to #emded data.
Definition: Expr.h:4916
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3474
This represents one expression.
Definition: Expr.h:110
QualType getType() const
Definition: Expr.h:142
An expression trait intrinsic.
Definition: ExprCXX.h:2924
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition: Expr.h:6354
Represents difference between two FPOptions values.
Definition: LangOptions.h:979
Represents a member of a struct/union/class.
Definition: Decl.h:3040
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition: Decl.cpp:4586
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2808
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2656
bool isVariadic() const
Whether this function is variadic.
Definition: Decl.cpp:3093
Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...
Definition: ExprCXX.h:4652
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5108
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4322
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:3286
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4716
Represents a C11 generic selection.
Definition: Expr.h:5966
AssociationTy< false > Association
Definition: Expr.h:6197
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2889
This class represents temporary values used to represent inout and out arguments in HLSL.
Definition: Expr.h:7152
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IfStmt - This represents an if/then/else.
Definition: Stmt.h:2165
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1717
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3724
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5841
IndirectGotoStmt - This represents an indirect goto.
Definition: Stmt.h:2928
Describes an C or C++ initializer list.
Definition: Expr.h:5088
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2058
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1954
llvm::RoundingMode RoundingMode
Definition: LangOptions.h:76
FPExceptionModeKind
Possible floating point exception behavior.
Definition: LangOptions.h:288
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:1023
This represents a Microsoft inline-assembly statement extension.
Definition: Stmt.h:3509
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Definition: StmtCXX.h:253
A member reference to an MSPropertyDecl.
Definition: ExprCXX.h:933
MS property subscript expression.
Definition: ExprCXX.h:1004
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4732
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition: Expr.h:2796
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3236
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:280
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
Represents a place-holder for an object not to be initialized by anything.
Definition: Expr.h:5661
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition: Stmt.h:1591
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition: ExprOpenMP.h:24
This represents '#pragma omp atomic' directive.
Definition: StmtOpenMP.h:2947
This represents '#pragma omp barrier' directive.
Definition: StmtOpenMP.h:2625
This represents '#pragma omp cancel' directive.
Definition: StmtOpenMP.h:3655
This represents '#pragma omp cancellation point' directive.
Definition: StmtOpenMP.h:3597
Representation of an OpenMP canonical loop.
Definition: StmtOpenMP.h:142
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:2076
This represents implicit clause 'depend' for the '#pragma omp task' directive.
This represents '#pragma omp depobj' directive.
Definition: StmtOpenMP.h:2841
This represents '#pragma omp dispatch' directive.
Definition: StmtOpenMP.h:5948
This represents '#pragma omp distribute' directive.
Definition: StmtOpenMP.h:4425
This represents '#pragma omp distribute parallel for' composite directive.
Definition: StmtOpenMP.h:4547
This represents '#pragma omp distribute parallel for simd' composite directive.
Definition: StmtOpenMP.h:4643
This represents '#pragma omp distribute simd' composite directive.
Definition: StmtOpenMP.h:4708
This represents '#pragma omp error' directive.
Definition: StmtOpenMP.h:6432
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
This represents '#pragma omp flush' directive.
Definition: StmtOpenMP.h:2789
This represents '#pragma omp for' directive.
Definition: StmtOpenMP.h:1634
This represents '#pragma omp for simd' directive.
Definition: StmtOpenMP.h:1724
This represents '#pragma omp loop' directive.
Definition: StmtOpenMP.h:6103
Represents the '#pragma omp interchange' loop transformation directive.
Definition: StmtOpenMP.h:5769
This represents '#pragma omp interop' directive.
Definition: StmtOpenMP.h:5895
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition: ExprOpenMP.h:151
This represents '#pragma omp masked' directive.
Definition: StmtOpenMP.h:6013
This represents '#pragma omp masked taskloop' directive.
Definition: StmtOpenMP.h:3930
This represents '#pragma omp masked taskloop simd' directive.
Definition: StmtOpenMP.h:4071
This represents '#pragma omp master' directive.
Definition: StmtOpenMP.h:2028
This represents '#pragma omp master taskloop' directive.
Definition: StmtOpenMP.h:3854
This represents '#pragma omp master taskloop simd' directive.
Definition: StmtOpenMP.h:4006
This represents '#pragma omp metadirective' directive.
Definition: StmtOpenMP.h:6064
This represents '#pragma omp ordered' directive.
Definition: StmtOpenMP.h:2893
This represents '#pragma omp parallel' directive.
Definition: StmtOpenMP.h:612
This represents '#pragma omp parallel for' directive.
Definition: StmtOpenMP.h:2147
This represents '#pragma omp parallel for simd' directive.
Definition: StmtOpenMP.h:2244
This represents '#pragma omp parallel loop' directive.
Definition: StmtOpenMP.h:6305
This represents '#pragma omp parallel masked' directive.
Definition: StmtOpenMP.h:2372
This represents '#pragma omp parallel masked taskloop' directive.
Definition: StmtOpenMP.h:4215
This represents '#pragma omp parallel masked taskloop simd' directive.
Definition: StmtOpenMP.h:4360
This represents '#pragma omp parallel master' directive.
Definition: StmtOpenMP.h:2309
This represents '#pragma omp parallel master taskloop' directive.
Definition: StmtOpenMP.h:4137
This represents '#pragma omp parallel master taskloop simd' directive.
Definition: StmtOpenMP.h:4293
This represents '#pragma omp parallel sections' directive.
Definition: StmtOpenMP.h:2436
Represents the '#pragma omp reverse' loop transformation directive.
Definition: StmtOpenMP.h:5704
This represents '#pragma omp scan' directive.
Definition: StmtOpenMP.h:5842
This represents '#pragma omp scope' directive.
Definition: StmtOpenMP.h:1925
This represents '#pragma omp section' directive.
Definition: StmtOpenMP.h:1864
This represents '#pragma omp sections' directive.
Definition: StmtOpenMP.h:1787
This represents '#pragma omp simd' directive.
Definition: StmtOpenMP.h:1571
This represents '#pragma omp single' directive.
Definition: StmtOpenMP.h:1977
This represents '#pragma omp target data' directive.
Definition: StmtOpenMP.h:3206
This represents '#pragma omp target' directive.
Definition: StmtOpenMP.h:3152
This represents '#pragma omp target enter data' directive.
Definition: StmtOpenMP.h:3260
This represents '#pragma omp target exit data' directive.
Definition: StmtOpenMP.h:3315
This represents '#pragma omp target parallel' directive.
Definition: StmtOpenMP.h:3369
This represents '#pragma omp target parallel for' directive.
Definition: StmtOpenMP.h:3449
This represents '#pragma omp target parallel for simd' directive.
Definition: StmtOpenMP.h:4774
This represents '#pragma omp target parallel loop' directive.
Definition: StmtOpenMP.h:6370
This represents '#pragma omp target simd' directive.
Definition: StmtOpenMP.h:4841
This represents '#pragma omp target teams' directive.
Definition: StmtOpenMP.h:5199
This represents '#pragma omp target teams distribute' combined directive.
Definition: StmtOpenMP.h:5255
This represents '#pragma omp target teams distribute parallel for' combined directive.
Definition: StmtOpenMP.h:5322
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
Definition: StmtOpenMP.h:5420
This represents '#pragma omp target teams distribute simd' combined directive.
Definition: StmtOpenMP.h:5490
This represents '#pragma omp target teams loop' directive.
Definition: StmtOpenMP.h:6230
This represents '#pragma omp target update' directive.
Definition: StmtOpenMP.h:4491
This represents '#pragma omp task' directive.
Definition: StmtOpenMP.h:2517
This represents '#pragma omp taskloop' directive.
Definition: StmtOpenMP.h:3715
This represents '#pragma omp taskloop simd' directive.
Definition: StmtOpenMP.h:3788
This represents '#pragma omp taskgroup' directive.
Definition: StmtOpenMP.h:2722
This represents '#pragma omp taskwait' directive.
Definition: StmtOpenMP.h:2671
This represents '#pragma omp taskyield' directive.
Definition: StmtOpenMP.h:2579
This represents '#pragma omp teams' directive.
Definition: StmtOpenMP.h:3544
This represents '#pragma omp teams distribute' directive.
Definition: StmtOpenMP.h:4906
This represents '#pragma omp teams distribute parallel for' composite directive.
Definition: StmtOpenMP.h:5106
This represents '#pragma omp teams distribute parallel for simd' composite directive.
Definition: StmtOpenMP.h:5040
This represents '#pragma omp teams distribute simd' combined directive.
Definition: StmtOpenMP.h:4972
This represents '#pragma omp teams loop' directive.
Definition: StmtOpenMP.h:6165
This represents the '#pragma omp tile' loop transformation directive.
Definition: StmtOpenMP.h:5548
This represents the '#pragma omp unroll' loop transformation directive.
Definition: StmtOpenMP.h:5630
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:191
Represents Objective-C's @catch statement.
Definition: StmtObjC.h:77
Represents Objective-C's @finally statement.
Definition: StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition: StmtObjC.h:303
Represents Objective-C's @throw statement.
Definition: StmtObjC.h:358
Represents Objective-C's @try ... @catch ... @finally statement.
Definition: StmtObjC.h:167
Represents Objective-C's @autoreleasepool Statement.
Definition: StmtObjC.h:394
A runtime availability query.
Definition: ExprObjC.h:1692
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:87
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:127
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition: ExprObjC.h:1632
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:309
ObjCEncodeExpr, used for @encode in Objective-C.
Definition: ExprObjC.h:410
Represents Objective-C's collection statement.
Definition: StmtObjC.h:23
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition: ExprObjC.h:1571
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition: ExprObjC.h:1487
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:549
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:941
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: ExprObjC.h:1391
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1256
Selector getSelector() const
Definition: ExprObjC.cpp:291
@ SuperInstance
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:955
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:949
@ SuperClass
The receiver is a superclass.
Definition: ExprObjC.h:952
@ Class
The receiver is a class.
Definition: ExprObjC.h:946
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Definition: ExprObjC.h:1275
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition: ExprObjC.h:1230
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition: ExprObjC.h:1378
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:617
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition: ExprObjC.h:505
ObjCSelectorExpr used for @selector in Objective-C.
Definition: ExprObjC.h:455
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:51
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition: ExprObjC.h:840
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2519
Helper class for OffsetOfExpr.
Definition: Expr.h:2413
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition: Expr.h:2471
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition: Expr.cpp:1706
@ Array
An index into an array.
Definition: Expr.h:2418
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2425
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:2467
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1173
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
Definition: Expr.h:2078
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Definition: StmtOpenACC.h:131
This is the base class for an OpenACC statement-level construct, other construct types are expected t...
Definition: StmtOpenACC.h:25
This class represents a 'loop' construct.
Definition: StmtOpenACC.h:194
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4180
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2170
Represents a parameter to a function.
Definition: Decl.h:1725
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1991
StringRef getIdentKindName() const
Definition: Expr.h:2048
virtual bool handledStmt(Stmt *E, raw_ostream &OS)=0
virtual ~PrinterHelper()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6546
A (possibly-)qualified type.
Definition: Type.h:929
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition: Expr.h:7258
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:502
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3046
Represents a __leave statement.
Definition: Stmt.h:3745
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
Definition: StmtSYCL.h:37
static std::string getPropertyNameFromSetterSelector(Selector Sel)
Return the property name for the given setter selector.
Smart pointer class that efficiently represents Objective-C method names.
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.
bool isUnarySelector() const
unsigned getNumArgs() const
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition: Expr.h:4514
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4258
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4810
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4466
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Definition: StmtVisitor.h:45
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:186
Stmt - This represents one statement.
Definition: Stmt.h:84
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
child_range children()
Definition: Stmt.cpp:295
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1469
void dumpPretty(const ASTContext &Context) const
dumpPretty/printPretty - These two methods do a "pretty print" of the AST back to its original source...
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1778
void outputString(raw_ostream &OS) const
Definition: Expr.cpp:1215
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4488
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition: ExprCXX.h:4573
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2415
A template argument list.
Definition: DeclTemplate.h:250
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:286
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:271
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:280
Represents a template argument.
Definition: TemplateBase.h:61
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:432
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
A container of type source information.
Definition: Type.h:7908
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2768
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8810
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
Definition: Expr.h:6837
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2622
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2232
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition: Expr.cpp:1407
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3203
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3943
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
Definition: ExprCXX.h:637
@ LOK_String
operator "" X (const CharT *, size_t)
Definition: ExprCXX.h:679
@ LOK_Raw
Raw form: operator "" X (const char *)
Definition: ExprCXX.h:667
@ LOK_Floating
operator "" X (long double)
Definition: ExprCXX.h:676
@ LOK_Integer
operator "" X (unsigned long long)
Definition: ExprCXX.h:673
@ LOK_Template
Raw form: operator "" X<cs...> ()
Definition: ExprCXX.h:670
@ LOK_Character
operator "" X (CharT)
Definition: ExprCXX.h:682
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4750
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
QualType getType() const
Definition: Decl.h:682
@ CInit
C-style initialization with assignment.
Definition: Decl.h:891
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:894
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2611
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
@ 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,...
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
Definition: JsonSupport.h:28
@ LCD_ByRef
Definition: Lambda.h:25
@ LCD_None
Definition: Lambda.h:23
@ LCD_ByCopy
Definition: Lambda.h:24
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
CXXNewInitializationStyle
Definition: ExprCXX.h:2226
const Expr * RHS
The original right-hand side.
Definition: ExprCXX.h:310
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition: ExprCXX.h:306
const Expr * LHS
The original left-hand side.
Definition: ExprCXX.h:308
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
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.
Iterator range representation begin:end[:step].
Definition: ExprOpenMP.h:154
An element in an Objective-C dictionary literal.
Definition: ExprObjC.h:262
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned Alignof
Whether we can use 'alignof' rather than '__alignof'.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned ConstantsAsWritten
Whether we should print the constant expressions as written in the sources.
unsigned IncludeNewlines
When true, include newlines after statements like "break", etc.
unsigned Indentation
The number of spaces to use to indent each line.
Definition: PrettyPrinter.h:95
unsigned TerseOutput
Provide a 'terse' output.
unsigned UnderscoreAlignof
Whether we can use '_Alignof' rather than '__alignof'.
unsigned SuppressImplicitBase
When true, don't print the implicit 'self' or 'this' expressions.
Iterator for iterating over Stmt * arrays that contain only T *.
Definition: Stmt.h:1338