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