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::VisitOMPAssumeDirective(OMPAssumeDirective *Node) {
871 Indent() << "#pragma omp assume";
872 PrintOMPExecutableDirective(Node);
873}
874
875void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
876 Indent() << "#pragma omp error";
877 PrintOMPExecutableDirective(Node);
878}
879
880void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
881 Indent() << "#pragma omp taskgroup";
882 PrintOMPExecutableDirective(Node);
883}
884
885void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
886 Indent() << "#pragma omp flush";
887 PrintOMPExecutableDirective(Node);
888}
889
890void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
891 Indent() << "#pragma omp depobj";
892 PrintOMPExecutableDirective(Node);
893}
894
895void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
896 Indent() << "#pragma omp scan";
897 PrintOMPExecutableDirective(Node);
898}
899
900void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
901 Indent() << "#pragma omp ordered";
902 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
903}
904
905void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
906 Indent() << "#pragma omp atomic";
907 PrintOMPExecutableDirective(Node);
908}
909
910void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
911 Indent() << "#pragma omp target";
912 PrintOMPExecutableDirective(Node);
913}
914
915void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
916 Indent() << "#pragma omp target data";
917 PrintOMPExecutableDirective(Node);
918}
919
920void StmtPrinter::VisitOMPTargetEnterDataDirective(
922 Indent() << "#pragma omp target enter data";
923 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
924}
925
926void StmtPrinter::VisitOMPTargetExitDataDirective(
928 Indent() << "#pragma omp target exit data";
929 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
930}
931
932void StmtPrinter::VisitOMPTargetParallelDirective(
934 Indent() << "#pragma omp target parallel";
935 PrintOMPExecutableDirective(Node);
936}
937
938void StmtPrinter::VisitOMPTargetParallelForDirective(
940 Indent() << "#pragma omp target parallel for";
941 PrintOMPExecutableDirective(Node);
942}
943
944void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
945 Indent() << "#pragma omp teams";
946 PrintOMPExecutableDirective(Node);
947}
948
949void StmtPrinter::VisitOMPCancellationPointDirective(
951 Indent() << "#pragma omp cancellation point "
952 << getOpenMPDirectiveName(Node->getCancelRegion());
953 PrintOMPExecutableDirective(Node);
954}
955
956void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
957 Indent() << "#pragma omp cancel "
958 << getOpenMPDirectiveName(Node->getCancelRegion());
959 PrintOMPExecutableDirective(Node);
960}
961
962void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
963 Indent() << "#pragma omp taskloop";
964 PrintOMPExecutableDirective(Node);
965}
966
967void StmtPrinter::VisitOMPTaskLoopSimdDirective(
969 Indent() << "#pragma omp taskloop simd";
970 PrintOMPExecutableDirective(Node);
971}
972
973void StmtPrinter::VisitOMPMasterTaskLoopDirective(
975 Indent() << "#pragma omp master taskloop";
976 PrintOMPExecutableDirective(Node);
977}
978
979void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
981 Indent() << "#pragma omp masked taskloop";
982 PrintOMPExecutableDirective(Node);
983}
984
985void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
987 Indent() << "#pragma omp master taskloop simd";
988 PrintOMPExecutableDirective(Node);
989}
990
991void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
993 Indent() << "#pragma omp masked taskloop simd";
994 PrintOMPExecutableDirective(Node);
995}
996
997void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
999 Indent() << "#pragma omp parallel master taskloop";
1000 PrintOMPExecutableDirective(Node);
1001}
1002
1003void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
1005 Indent() << "#pragma omp parallel masked taskloop";
1006 PrintOMPExecutableDirective(Node);
1007}
1008
1009void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
1011 Indent() << "#pragma omp parallel master taskloop simd";
1012 PrintOMPExecutableDirective(Node);
1013}
1014
1015void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
1017 Indent() << "#pragma omp parallel masked taskloop simd";
1018 PrintOMPExecutableDirective(Node);
1019}
1020
1021void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1022 Indent() << "#pragma omp distribute";
1023 PrintOMPExecutableDirective(Node);
1024}
1025
1026void StmtPrinter::VisitOMPTargetUpdateDirective(
1028 Indent() << "#pragma omp target update";
1029 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1030}
1031
1032void StmtPrinter::VisitOMPDistributeParallelForDirective(
1034 Indent() << "#pragma omp distribute parallel for";
1035 PrintOMPExecutableDirective(Node);
1036}
1037
1038void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1040 Indent() << "#pragma omp distribute parallel for simd";
1041 PrintOMPExecutableDirective(Node);
1042}
1043
1044void StmtPrinter::VisitOMPDistributeSimdDirective(
1046 Indent() << "#pragma omp distribute simd";
1047 PrintOMPExecutableDirective(Node);
1048}
1049
1050void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1052 Indent() << "#pragma omp target parallel for simd";
1053 PrintOMPExecutableDirective(Node);
1054}
1055
1056void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1057 Indent() << "#pragma omp target simd";
1058 PrintOMPExecutableDirective(Node);
1059}
1060
1061void StmtPrinter::VisitOMPTeamsDistributeDirective(
1063 Indent() << "#pragma omp teams distribute";
1064 PrintOMPExecutableDirective(Node);
1065}
1066
1067void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1069 Indent() << "#pragma omp teams distribute simd";
1070 PrintOMPExecutableDirective(Node);
1071}
1072
1073void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1075 Indent() << "#pragma omp teams distribute parallel for simd";
1076 PrintOMPExecutableDirective(Node);
1077}
1078
1079void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1081 Indent() << "#pragma omp teams distribute parallel for";
1082 PrintOMPExecutableDirective(Node);
1083}
1084
1085void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1086 Indent() << "#pragma omp target teams";
1087 PrintOMPExecutableDirective(Node);
1088}
1089
1090void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1092 Indent() << "#pragma omp target teams distribute";
1093 PrintOMPExecutableDirective(Node);
1094}
1095
1096void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1098 Indent() << "#pragma omp target teams distribute parallel for";
1099 PrintOMPExecutableDirective(Node);
1100}
1101
1102void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1104 Indent() << "#pragma omp target teams distribute parallel for simd";
1105 PrintOMPExecutableDirective(Node);
1106}
1107
1108void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1110 Indent() << "#pragma omp target teams distribute simd";
1111 PrintOMPExecutableDirective(Node);
1112}
1113
1114void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1115 Indent() << "#pragma omp interop";
1116 PrintOMPExecutableDirective(Node);
1117}
1118
1119void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1120 Indent() << "#pragma omp dispatch";
1121 PrintOMPExecutableDirective(Node);
1122}
1123
1124void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1125 Indent() << "#pragma omp masked";
1126 PrintOMPExecutableDirective(Node);
1127}
1128
1129void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1130 Indent() << "#pragma omp loop";
1131 PrintOMPExecutableDirective(Node);
1132}
1133
1134void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1136 Indent() << "#pragma omp teams loop";
1137 PrintOMPExecutableDirective(Node);
1138}
1139
1140void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1142 Indent() << "#pragma omp target teams loop";
1143 PrintOMPExecutableDirective(Node);
1144}
1145
1146void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1148 Indent() << "#pragma omp parallel loop";
1149 PrintOMPExecutableDirective(Node);
1150}
1151
1152void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1154 Indent() << "#pragma omp target parallel loop";
1155 PrintOMPExecutableDirective(Node);
1156}
1157
1158//===----------------------------------------------------------------------===//
1159// OpenACC construct printing methods
1160//===----------------------------------------------------------------------===//
1161void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
1162 Indent() << "#pragma acc " << S->getDirectiveKind();
1163
1164 if (!S->clauses().empty()) {
1165 OS << ' ';
1166 OpenACCClausePrinter Printer(OS, Policy);
1167 Printer.VisitClauseList(S->clauses());
1168 }
1169 OS << '\n';
1170
1171 PrintStmt(S->getStructuredBlock());
1172}
1173
1174void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
1175 Indent() << "#pragma acc loop";
1176
1177 if (!S->clauses().empty()) {
1178 OS << ' ';
1179 OpenACCClausePrinter Printer(OS, Policy);
1180 Printer.VisitClauseList(S->clauses());
1181 }
1182 OS << '\n';
1183
1184 PrintStmt(S->getLoop());
1185}
1186
1187//===----------------------------------------------------------------------===//
1188// Expr printing methods.
1189//===----------------------------------------------------------------------===//
1190
1191void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1192 OS << Node->getBuiltinStr() << "()";
1193}
1194
1195void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
1196 llvm::report_fatal_error("Not implemented");
1197}
1198
1199void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1200 PrintExpr(Node->getSubExpr());
1201}
1202
1203void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1204 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
1205 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1206 return;
1207 }
1208 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) {
1209 TPOD->printAsExpr(OS, Policy);
1210 return;
1211 }
1212 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1213 Qualifier->print(OS, Policy);
1214 if (Node->hasTemplateKeyword())
1215 OS << "template ";
1216 if (Policy.CleanUglifiedParameters &&
1217 isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) &&
1218 Node->getDecl()->getIdentifier())
1219 OS << Node->getDecl()->getIdentifier()->deuglifiedName();
1220 else
1221 Node->getNameInfo().printName(OS, Policy);
1222 if (Node->hasExplicitTemplateArgs()) {
1223 const TemplateParameterList *TPL = nullptr;
1224 if (!Node->hadMultipleCandidates())
1225 if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
1226 TPL = TD->getTemplateParameters();
1227 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1228 }
1229}
1230
1231void StmtPrinter::VisitDependentScopeDeclRefExpr(
1233 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1234 Qualifier->print(OS, Policy);
1235 if (Node->hasTemplateKeyword())
1236 OS << "template ";
1237 OS << Node->getNameInfo();
1238 if (Node->hasExplicitTemplateArgs())
1239 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1240}
1241
1242void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1243 if (Node->getQualifier())
1244 Node->getQualifier()->print(OS, Policy);
1245 if (Node->hasTemplateKeyword())
1246 OS << "template ";
1247 OS << Node->getNameInfo();
1248 if (Node->hasExplicitTemplateArgs())
1249 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1250}
1251
1252static bool isImplicitSelf(const Expr *E) {
1253 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1254 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1255 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1256 DRE->getBeginLoc().isInvalid())
1257 return true;
1258 }
1259 }
1260 return false;
1261}
1262
1263void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1264 if (Node->getBase()) {
1265 if (!Policy.SuppressImplicitBase ||
1266 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1267 PrintExpr(Node->getBase());
1268 OS << (Node->isArrow() ? "->" : ".");
1269 }
1270 }
1271 OS << *Node->getDecl();
1272}
1273
1274void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1275 if (Node->isSuperReceiver())
1276 OS << "super.";
1277 else if (Node->isObjectReceiver() && Node->getBase()) {
1278 PrintExpr(Node->getBase());
1279 OS << ".";
1280 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1281 OS << Node->getClassReceiver()->getName() << ".";
1282 }
1283
1284 if (Node->isImplicitProperty()) {
1285 if (const auto *Getter = Node->getImplicitPropertyGetter())
1286 Getter->getSelector().print(OS);
1287 else
1289 Node->getImplicitPropertySetter()->getSelector());
1290 } else
1291 OS << Node->getExplicitProperty()->getName();
1292}
1293
1294void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1295 PrintExpr(Node->getBaseExpr());
1296 OS << "[";
1297 PrintExpr(Node->getKeyExpr());
1298 OS << "]";
1299}
1300
1301void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1303 OS << "__builtin_sycl_unique_stable_name(";
1304 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1305 OS << ")";
1306}
1307
1308void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1309 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1310}
1311
1312void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1313 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1314}
1315
1316/// Prints the given expression using the original source text. Returns true on
1317/// success, false otherwise.
1318static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1319 const ASTContext *Context) {
1320 if (!Context)
1321 return false;
1322 bool Invalid = false;
1323 StringRef Source = Lexer::getSourceText(
1325 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1326 if (!Invalid) {
1327 OS << Source;
1328 return true;
1329 }
1330 return false;
1331}
1332
1333void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1334 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1335 return;
1336 bool isSigned = Node->getType()->isSignedIntegerType();
1337 OS << toString(Node->getValue(), 10, isSigned);
1338
1339 if (isa<BitIntType>(Node->getType())) {
1340 OS << (isSigned ? "wb" : "uwb");
1341 return;
1342 }
1343
1344 // Emit suffixes. Integer literals are always a builtin integer type.
1345 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1346 default: llvm_unreachable("Unexpected type for integer literal!");
1347 case BuiltinType::Char_S:
1348 case BuiltinType::Char_U: OS << "i8"; break;
1349 case BuiltinType::UChar: OS << "Ui8"; break;
1350 case BuiltinType::SChar: OS << "i8"; break;
1351 case BuiltinType::Short: OS << "i16"; break;
1352 case BuiltinType::UShort: OS << "Ui16"; break;
1353 case BuiltinType::Int: break; // no suffix.
1354 case BuiltinType::UInt: OS << 'U'; break;
1355 case BuiltinType::Long: OS << 'L'; break;
1356 case BuiltinType::ULong: OS << "UL"; break;
1357 case BuiltinType::LongLong: OS << "LL"; break;
1358 case BuiltinType::ULongLong: OS << "ULL"; break;
1359 case BuiltinType::Int128:
1360 break; // no suffix.
1361 case BuiltinType::UInt128:
1362 break; // no suffix.
1363 case BuiltinType::WChar_S:
1364 case BuiltinType::WChar_U:
1365 break; // no suffix
1366 }
1367}
1368
1369void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1370 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1371 return;
1372 OS << Node->getValueAsString(/*Radix=*/10);
1373
1374 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1375 default: llvm_unreachable("Unexpected type for fixed point literal!");
1376 case BuiltinType::ShortFract: OS << "hr"; break;
1377 case BuiltinType::ShortAccum: OS << "hk"; break;
1378 case BuiltinType::UShortFract: OS << "uhr"; break;
1379 case BuiltinType::UShortAccum: OS << "uhk"; break;
1380 case BuiltinType::Fract: OS << "r"; break;
1381 case BuiltinType::Accum: OS << "k"; break;
1382 case BuiltinType::UFract: OS << "ur"; break;
1383 case BuiltinType::UAccum: OS << "uk"; break;
1384 case BuiltinType::LongFract: OS << "lr"; break;
1385 case BuiltinType::LongAccum: OS << "lk"; break;
1386 case BuiltinType::ULongFract: OS << "ulr"; break;
1387 case BuiltinType::ULongAccum: OS << "ulk"; break;
1388 }
1389}
1390
1391static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1392 bool PrintSuffix) {
1393 SmallString<16> Str;
1394 Node->getValue().toString(Str);
1395 OS << Str;
1396 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1397 OS << '.'; // Trailing dot in order to separate from ints.
1398
1399 if (!PrintSuffix)
1400 return;
1401
1402 // Emit suffixes. Float literals are always a builtin float type.
1403 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1404 default: llvm_unreachable("Unexpected type for float literal!");
1405 case BuiltinType::Half: break; // FIXME: suffix?
1406 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1407 case BuiltinType::Double: break; // no suffix.
1408 case BuiltinType::Float16: OS << "F16"; break;
1409 case BuiltinType::Float: OS << 'F'; break;
1410 case BuiltinType::LongDouble: OS << 'L'; break;
1411 case BuiltinType::Float128: OS << 'Q'; break;
1412 }
1413}
1414
1415void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1416 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1417 return;
1418 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1419}
1420
1421void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1422 PrintExpr(Node->getSubExpr());
1423 OS << "i";
1424}
1425
1426void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1427 Str->outputString(OS);
1428}
1429
1430void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1431 OS << "(";
1432 PrintExpr(Node->getSubExpr());
1433 OS << ")";
1434}
1435
1436void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1437 if (!Node->isPostfix()) {
1438 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1439
1440 // Print a space if this is an "identifier operator" like __real, or if
1441 // it might be concatenated incorrectly like '+'.
1442 switch (Node->getOpcode()) {
1443 default: break;
1444 case UO_Real:
1445 case UO_Imag:
1446 case UO_Extension:
1447 OS << ' ';
1448 break;
1449 case UO_Plus:
1450 case UO_Minus:
1451 if (isa<UnaryOperator>(Node->getSubExpr()))
1452 OS << ' ';
1453 break;
1454 }
1455 }
1456 PrintExpr(Node->getSubExpr());
1457
1458 if (Node->isPostfix())
1459 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1460}
1461
1462void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1463 OS << "__builtin_offsetof(";
1464 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1465 OS << ", ";
1466 bool PrintedSomething = false;
1467 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1468 OffsetOfNode ON = Node->getComponent(i);
1469 if (ON.getKind() == OffsetOfNode::Array) {
1470 // Array node
1471 OS << "[";
1472 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1473 OS << "]";
1474 PrintedSomething = true;
1475 continue;
1476 }
1477
1478 // Skip implicit base indirections.
1479 if (ON.getKind() == OffsetOfNode::Base)
1480 continue;
1481
1482 // Field or identifier node.
1483 const IdentifierInfo *Id = ON.getFieldName();
1484 if (!Id)
1485 continue;
1486
1487 if (PrintedSomething)
1488 OS << ".";
1489 else
1490 PrintedSomething = true;
1491 OS << Id->getName();
1492 }
1493 OS << ")";
1494}
1495
1496void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1498 const char *Spelling = getTraitSpelling(Node->getKind());
1499 if (Node->getKind() == UETT_AlignOf) {
1500 if (Policy.Alignof)
1501 Spelling = "alignof";
1502 else if (Policy.UnderscoreAlignof)
1503 Spelling = "_Alignof";
1504 else
1505 Spelling = "__alignof";
1506 }
1507
1508 OS << Spelling;
1509
1510 if (Node->isArgumentType()) {
1511 OS << '(';
1512 Node->getArgumentType().print(OS, Policy);
1513 OS << ')';
1514 } else {
1515 OS << " ";
1516 PrintExpr(Node->getArgumentExpr());
1517 }
1518}
1519
1520void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1521 OS << "_Generic(";
1522 if (Node->isExprPredicate())
1523 PrintExpr(Node->getControllingExpr());
1524 else
1525 Node->getControllingType()->getType().print(OS, Policy);
1526
1527 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1528 OS << ", ";
1529 QualType T = Assoc.getType();
1530 if (T.isNull())
1531 OS << "default";
1532 else
1533 T.print(OS, Policy);
1534 OS << ": ";
1535 PrintExpr(Assoc.getAssociationExpr());
1536 }
1537 OS << ")";
1538}
1539
1540void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1541 PrintExpr(Node->getLHS());
1542 OS << "[";
1543 PrintExpr(Node->getRHS());
1544 OS << "]";
1545}
1546
1547void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1548 PrintExpr(Node->getBase());
1549 OS << "[";
1550 PrintExpr(Node->getRowIdx());
1551 OS << "]";
1552 OS << "[";
1553 PrintExpr(Node->getColumnIdx());
1554 OS << "]";
1555}
1556
1557void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1558 PrintExpr(Node->getBase());
1559 OS << "[";
1560 if (Node->getLowerBound())
1561 PrintExpr(Node->getLowerBound());
1562 if (Node->getColonLocFirst().isValid()) {
1563 OS << ":";
1564 if (Node->getLength())
1565 PrintExpr(Node->getLength());
1566 }
1567 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1568 OS << ":";
1569 if (Node->getStride())
1570 PrintExpr(Node->getStride());
1571 }
1572 OS << "]";
1573}
1574
1575void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1576 OS << "(";
1577 for (Expr *E : Node->getDimensions()) {
1578 OS << "[";
1579 PrintExpr(E);
1580 OS << "]";
1581 }
1582 OS << ")";
1583 PrintExpr(Node->getBase());
1584}
1585
1586void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1587 OS << "iterator(";
1588 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1589 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1590 VD->getType().print(OS, Policy);
1591 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1592 OS << " " << VD->getName() << " = ";
1593 PrintExpr(Range.Begin);
1594 OS << ":";
1595 PrintExpr(Range.End);
1596 if (Range.Step) {
1597 OS << ":";
1598 PrintExpr(Range.Step);
1599 }
1600 if (I < E - 1)
1601 OS << ", ";
1602 }
1603 OS << ")";
1604}
1605
1606void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1607 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1608 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1609 // Don't print any defaulted arguments
1610 break;
1611 }
1612
1613 if (i) OS << ", ";
1614 PrintExpr(Call->getArg(i));
1615 }
1616}
1617
1618void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1619 PrintExpr(Call->getCallee());
1620 OS << "(";
1621 PrintCallArgs(Call);
1622 OS << ")";
1623}
1624
1625static bool isImplicitThis(const Expr *E) {
1626 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1627 return TE->isImplicit();
1628 return false;
1629}
1630
1631void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1632 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1633 PrintExpr(Node->getBase());
1634
1635 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1636 FieldDecl *ParentDecl =
1637 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1638 : nullptr;
1639
1640 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1641 OS << (Node->isArrow() ? "->" : ".");
1642 }
1643
1644 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1645 if (FD->isAnonymousStructOrUnion())
1646 return;
1647
1648 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1649 Qualifier->print(OS, Policy);
1650 if (Node->hasTemplateKeyword())
1651 OS << "template ";
1652 OS << Node->getMemberNameInfo();
1653 const TemplateParameterList *TPL = nullptr;
1654 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1655 if (!Node->hadMultipleCandidates())
1656 if (auto *FTD = FD->getPrimaryTemplate())
1657 TPL = FTD->getTemplateParameters();
1658 } else if (auto *VTSD =
1659 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1660 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1661 if (Node->hasExplicitTemplateArgs())
1662 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1663}
1664
1665void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1666 PrintExpr(Node->getBase());
1667 OS << (Node->isArrow() ? "->isa" : ".isa");
1668}
1669
1670void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1671 PrintExpr(Node->getBase());
1672 OS << ".";
1673 OS << Node->getAccessor().getName();
1674}
1675
1676void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1677 OS << '(';
1678 Node->getTypeAsWritten().print(OS, Policy);
1679 OS << ')';
1680 PrintExpr(Node->getSubExpr());
1681}
1682
1683void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1684 OS << '(';
1685 Node->getType().print(OS, Policy);
1686 OS << ')';
1687 PrintExpr(Node->getInitializer());
1688}
1689
1690void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1691 // No need to print anything, simply forward to the subexpression.
1692 PrintExpr(Node->getSubExpr());
1693}
1694
1695void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1696 PrintExpr(Node->getLHS());
1697 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1698 PrintExpr(Node->getRHS());
1699}
1700
1701void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1702 PrintExpr(Node->getLHS());
1703 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1704 PrintExpr(Node->getRHS());
1705}
1706
1707void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1708 PrintExpr(Node->getCond());
1709 OS << " ? ";
1710 PrintExpr(Node->getLHS());
1711 OS << " : ";
1712 PrintExpr(Node->getRHS());
1713}
1714
1715// GNU extensions.
1716
1717void
1718StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1719 PrintExpr(Node->getCommon());
1720 OS << " ?: ";
1721 PrintExpr(Node->getFalseExpr());
1722}
1723
1724void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1725 OS << "&&" << Node->getLabel()->getName();
1726}
1727
1728void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1729 OS << "(";
1730 PrintRawCompoundStmt(E->getSubStmt());
1731 OS << ")";
1732}
1733
1734void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1735 OS << "__builtin_choose_expr(";
1736 PrintExpr(Node->getCond());
1737 OS << ", ";
1738 PrintExpr(Node->getLHS());
1739 OS << ", ";
1740 PrintExpr(Node->getRHS());
1741 OS << ")";
1742}
1743
1744void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1745 OS << "__null";
1746}
1747
1748void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1749 OS << "__builtin_shufflevector(";
1750 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1751 if (i) OS << ", ";
1752 PrintExpr(Node->getExpr(i));
1753 }
1754 OS << ")";
1755}
1756
1757void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1758 OS << "__builtin_convertvector(";
1759 PrintExpr(Node->getSrcExpr());
1760 OS << ", ";
1761 Node->getType().print(OS, Policy);
1762 OS << ")";
1763}
1764
1765void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1766 if (Node->getSyntacticForm()) {
1767 Visit(Node->getSyntacticForm());
1768 return;
1769 }
1770
1771 OS << "{";
1772 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1773 if (i) OS << ", ";
1774 if (Node->getInit(i))
1775 PrintExpr(Node->getInit(i));
1776 else
1777 OS << "{}";
1778 }
1779 OS << "}";
1780}
1781
1782void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1783 // There's no way to express this expression in any of our supported
1784 // languages, so just emit something terse and (hopefully) clear.
1785 OS << "{";
1786 PrintExpr(Node->getSubExpr());
1787 OS << "}";
1788}
1789
1790void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1791 OS << "*";
1792}
1793
1794void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1795 OS << "(";
1796 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1797 if (i) OS << ", ";
1798 PrintExpr(Node->getExpr(i));
1799 }
1800 OS << ")";
1801}
1802
1803void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1804 bool NeedsEquals = true;
1805 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1806 if (D.isFieldDesignator()) {
1807 if (D.getDotLoc().isInvalid()) {
1808 if (const IdentifierInfo *II = D.getFieldName()) {
1809 OS << II->getName() << ":";
1810 NeedsEquals = false;
1811 }
1812 } else {
1813 OS << "." << D.getFieldName()->getName();
1814 }
1815 } else {
1816 OS << "[";
1817 if (D.isArrayDesignator()) {
1818 PrintExpr(Node->getArrayIndex(D));
1819 } else {
1820 PrintExpr(Node->getArrayRangeStart(D));
1821 OS << " ... ";
1822 PrintExpr(Node->getArrayRangeEnd(D));
1823 }
1824 OS << "]";
1825 }
1826 }
1827
1828 if (NeedsEquals)
1829 OS << " = ";
1830 else
1831 OS << " ";
1832 PrintExpr(Node->getInit());
1833}
1834
1835void StmtPrinter::VisitDesignatedInitUpdateExpr(
1837 OS << "{";
1838 OS << "/*base*/";
1839 PrintExpr(Node->getBase());
1840 OS << ", ";
1841
1842 OS << "/*updater*/";
1843 PrintExpr(Node->getUpdater());
1844 OS << "}";
1845}
1846
1847void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1848 OS << "/*no init*/";
1849}
1850
1851void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1852 if (Node->getType()->getAsCXXRecordDecl()) {
1853 OS << "/*implicit*/";
1854 Node->getType().print(OS, Policy);
1855 OS << "()";
1856 } else {
1857 OS << "/*implicit*/(";
1858 Node->getType().print(OS, Policy);
1859 OS << ')';
1860 if (Node->getType()->isRecordType())
1861 OS << "{}";
1862 else
1863 OS << 0;
1864 }
1865}
1866
1867void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1868 OS << "__builtin_va_arg(";
1869 PrintExpr(Node->getSubExpr());
1870 OS << ", ";
1871 Node->getType().print(OS, Policy);
1872 OS << ")";
1873}
1874
1875void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1876 PrintExpr(Node->getSyntacticForm());
1877}
1878
1879void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1880 const char *Name = nullptr;
1881 switch (Node->getOp()) {
1882#define BUILTIN(ID, TYPE, ATTRS)
1883#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1884 case AtomicExpr::AO ## ID: \
1885 Name = #ID "("; \
1886 break;
1887#include "clang/Basic/Builtins.inc"
1888 }
1889 OS << Name;
1890
1891 // AtomicExpr stores its subexpressions in a permuted order.
1892 PrintExpr(Node->getPtr());
1893 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1894 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1895 Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
1896 Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
1897 Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
1898 OS << ", ";
1899 PrintExpr(Node->getVal1());
1900 }
1901 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1902 Node->isCmpXChg()) {
1903 OS << ", ";
1904 PrintExpr(Node->getVal2());
1905 }
1906 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1907 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1908 OS << ", ";
1909 PrintExpr(Node->getWeak());
1910 }
1911 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1912 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1913 OS << ", ";
1914 PrintExpr(Node->getOrder());
1915 }
1916 if (Node->isCmpXChg()) {
1917 OS << ", ";
1918 PrintExpr(Node->getOrderFail());
1919 }
1920 OS << ")";
1921}
1922
1923// C++
1924void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1925 OverloadedOperatorKind Kind = Node->getOperator();
1926 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1927 if (Node->getNumArgs() == 1) {
1928 OS << getOperatorSpelling(Kind) << ' ';
1929 PrintExpr(Node->getArg(0));
1930 } else {
1931 PrintExpr(Node->getArg(0));
1932 OS << ' ' << getOperatorSpelling(Kind);
1933 }
1934 } else if (Kind == OO_Arrow) {
1935 PrintExpr(Node->getArg(0));
1936 } else if (Kind == OO_Call || Kind == OO_Subscript) {
1937 PrintExpr(Node->getArg(0));
1938 OS << (Kind == OO_Call ? '(' : '[');
1939 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1940 if (ArgIdx > 1)
1941 OS << ", ";
1942 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1943 PrintExpr(Node->getArg(ArgIdx));
1944 }
1945 OS << (Kind == OO_Call ? ')' : ']');
1946 } else if (Node->getNumArgs() == 1) {
1947 OS << getOperatorSpelling(Kind) << ' ';
1948 PrintExpr(Node->getArg(0));
1949 } else if (Node->getNumArgs() == 2) {
1950 PrintExpr(Node->getArg(0));
1951 OS << ' ' << getOperatorSpelling(Kind) << ' ';
1952 PrintExpr(Node->getArg(1));
1953 } else {
1954 llvm_unreachable("unknown overloaded operator");
1955 }
1956}
1957
1958void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1959 // If we have a conversion operator call only print the argument.
1960 CXXMethodDecl *MD = Node->getMethodDecl();
1961 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
1962 PrintExpr(Node->getImplicitObjectArgument());
1963 return;
1964 }
1965 VisitCallExpr(cast<CallExpr>(Node));
1966}
1967
1968void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
1969 PrintExpr(Node->getCallee());
1970 OS << "<<<";
1971 PrintCallArgs(Node->getConfig());
1972 OS << ">>>(";
1973 PrintCallArgs(Node);
1974 OS << ")";
1975}
1976
1977void StmtPrinter::VisitCXXRewrittenBinaryOperator(
1980 Node->getDecomposedForm();
1981 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
1982 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
1983 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
1984}
1985
1986void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1987 OS << Node->getCastName() << '<';
1988 Node->getTypeAsWritten().print(OS, Policy);
1989 OS << ">(";
1990 PrintExpr(Node->getSubExpr());
1991 OS << ")";
1992}
1993
1994void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1995 VisitCXXNamedCastExpr(Node);
1996}
1997
1998void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1999 VisitCXXNamedCastExpr(Node);
2000}
2001
2002void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2003 VisitCXXNamedCastExpr(Node);
2004}
2005
2006void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2007 VisitCXXNamedCastExpr(Node);
2008}
2009
2010void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2011 OS << "__builtin_bit_cast(";
2012 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2013 OS << ", ";
2014 PrintExpr(Node->getSubExpr());
2015 OS << ")";
2016}
2017
2018void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2019 VisitCXXNamedCastExpr(Node);
2020}
2021
2022void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2023 OS << "typeid(";
2024 if (Node->isTypeOperand()) {
2025 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2026 } else {
2027 PrintExpr(Node->getExprOperand());
2028 }
2029 OS << ")";
2030}
2031
2032void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2033 OS << "__uuidof(";
2034 if (Node->isTypeOperand()) {
2035 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2036 } else {
2037 PrintExpr(Node->getExprOperand());
2038 }
2039 OS << ")";
2040}
2041
2042void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2043 PrintExpr(Node->getBaseExpr());
2044 if (Node->isArrow())
2045 OS << "->";
2046 else
2047 OS << ".";
2048 if (NestedNameSpecifier *Qualifier =
2049 Node->getQualifierLoc().getNestedNameSpecifier())
2050 Qualifier->print(OS, Policy);
2051 OS << Node->getPropertyDecl()->getDeclName();
2052}
2053
2054void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2055 PrintExpr(Node->getBase());
2056 OS << "[";
2057 PrintExpr(Node->getIdx());
2058 OS << "]";
2059}
2060
2061void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2062 switch (Node->getLiteralOperatorKind()) {
2064 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2065 break;
2067 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2068 const TemplateArgumentList *Args =
2069 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2070 assert(Args);
2071
2072 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2073 const TemplateParameterList *TPL = nullptr;
2074 if (!DRE->hadMultipleCandidates())
2075 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2076 TPL = TD->getTemplateParameters();
2077 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2078 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2079 OS << "()";
2080 return;
2081 }
2082
2083 const TemplateArgument &Pack = Args->get(0);
2084 for (const auto &P : Pack.pack_elements()) {
2085 char C = (char)P.getAsIntegral().getZExtValue();
2086 OS << C;
2087 }
2088 break;
2089 }
2091 // Print integer literal without suffix.
2092 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2093 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2094 break;
2095 }
2097 // Print floating literal without suffix.
2098 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
2099 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2100 break;
2101 }
2104 PrintExpr(Node->getCookedLiteral());
2105 break;
2106 }
2107 OS << Node->getUDSuffix()->getName();
2108}
2109
2110void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2111 OS << (Node->getValue() ? "true" : "false");
2112}
2113
2114void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2115 OS << "nullptr";
2116}
2117
2118void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2119 OS << "this";
2120}
2121
2122void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2123 if (!Node->getSubExpr())
2124 OS << "throw";
2125 else {
2126 OS << "throw ";
2127 PrintExpr(Node->getSubExpr());
2128 }
2129}
2130
2131void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2132 // Nothing to print: we picked up the default argument.
2133}
2134
2135void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2136 // Nothing to print: we picked up the default initializer.
2137}
2138
2139void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2140 auto TargetType = Node->getType();
2141 auto *Auto = TargetType->getContainedDeducedType();
2142 bool Bare = Auto && Auto->isDeduced();
2143
2144 // Parenthesize deduced casts.
2145 if (Bare)
2146 OS << '(';
2147 TargetType.print(OS, Policy);
2148 if (Bare)
2149 OS << ')';
2150
2151 // No extra braces surrounding the inner construct.
2152 if (!Node->isListInitialization())
2153 OS << '(';
2154 PrintExpr(Node->getSubExpr());
2155 if (!Node->isListInitialization())
2156 OS << ')';
2157}
2158
2159void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2160 PrintExpr(Node->getSubExpr());
2161}
2162
2163void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2164 Node->getType().print(OS, Policy);
2165 if (Node->isStdInitListInitialization())
2166 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2167 else if (Node->isListInitialization())
2168 OS << "{";
2169 else
2170 OS << "(";
2171 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2172 ArgEnd = Node->arg_end();
2173 Arg != ArgEnd; ++Arg) {
2174 if ((*Arg)->isDefaultArgument())
2175 break;
2176 if (Arg != Node->arg_begin())
2177 OS << ", ";
2178 PrintExpr(*Arg);
2179 }
2180 if (Node->isStdInitListInitialization())
2181 /* See above. */;
2182 else if (Node->isListInitialization())
2183 OS << "}";
2184 else
2185 OS << ")";
2186}
2187
2188void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2189 OS << '[';
2190 bool NeedComma = false;
2191 switch (Node->getCaptureDefault()) {
2192 case LCD_None:
2193 break;
2194
2195 case LCD_ByCopy:
2196 OS << '=';
2197 NeedComma = true;
2198 break;
2199
2200 case LCD_ByRef:
2201 OS << '&';
2202 NeedComma = true;
2203 break;
2204 }
2205 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
2206 CEnd = Node->explicit_capture_end();
2207 C != CEnd;
2208 ++C) {
2209 if (C->capturesVLAType())
2210 continue;
2211
2212 if (NeedComma)
2213 OS << ", ";
2214 NeedComma = true;
2215
2216 switch (C->getCaptureKind()) {
2217 case LCK_This:
2218 OS << "this";
2219 break;
2220
2221 case LCK_StarThis:
2222 OS << "*this";
2223 break;
2224
2225 case LCK_ByRef:
2226 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2227 OS << '&';
2228 OS << C->getCapturedVar()->getName();
2229 break;
2230
2231 case LCK_ByCopy:
2232 OS << C->getCapturedVar()->getName();
2233 break;
2234
2235 case LCK_VLAType:
2236 llvm_unreachable("VLA type in explicit captures.");
2237 }
2238
2239 if (C->isPackExpansion())
2240 OS << "...";
2241
2242 if (Node->isInitCapture(C)) {
2243 // Init captures are always VarDecl.
2244 auto *D = cast<VarDecl>(C->getCapturedVar());
2245
2246 llvm::StringRef Pre;
2247 llvm::StringRef Post;
2248 if (D->getInitStyle() == VarDecl::CallInit &&
2249 !isa<ParenListExpr>(D->getInit())) {
2250 Pre = "(";
2251 Post = ")";
2252 } else if (D->getInitStyle() == VarDecl::CInit) {
2253 Pre = " = ";
2254 }
2255
2256 OS << Pre;
2257 PrintExpr(D->getInit());
2258 OS << Post;
2259 }
2260 }
2261 OS << ']';
2262
2263 if (!Node->getExplicitTemplateParameters().empty()) {
2264 Node->getTemplateParameterList()->print(
2265 OS, Node->getLambdaClass()->getASTContext(),
2266 /*OmitTemplateKW*/true);
2267 }
2268
2269 if (Node->hasExplicitParameters()) {
2270 OS << '(';
2271 CXXMethodDecl *Method = Node->getCallOperator();
2272 NeedComma = false;
2273 for (const auto *P : Method->parameters()) {
2274 if (NeedComma) {
2275 OS << ", ";
2276 } else {
2277 NeedComma = true;
2278 }
2279 std::string ParamStr =
2280 (Policy.CleanUglifiedParameters && P->getIdentifier())
2281 ? P->getIdentifier()->deuglifiedName().str()
2282 : P->getNameAsString();
2283 P->getOriginalType().print(OS, Policy, ParamStr);
2284 }
2285 if (Method->isVariadic()) {
2286 if (NeedComma)
2287 OS << ", ";
2288 OS << "...";
2289 }
2290 OS << ')';
2291
2292 if (Node->isMutable())
2293 OS << " mutable";
2294
2295 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2296 Proto->printExceptionSpecification(OS, Policy);
2297
2298 // FIXME: Attributes
2299
2300 // Print the trailing return type if it was specified in the source.
2301 if (Node->hasExplicitResultType()) {
2302 OS << " -> ";
2303 Proto->getReturnType().print(OS, Policy);
2304 }
2305 }
2306
2307 // Print the body.
2308 OS << ' ';
2309 if (Policy.TerseOutput)
2310 OS << "{}";
2311 else
2312 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2313}
2314
2315void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2316 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2317 TSInfo->getType().print(OS, Policy);
2318 else
2319 Node->getType().print(OS, Policy);
2320 OS << "()";
2321}
2322
2323void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2324 if (E->isGlobalNew())
2325 OS << "::";
2326 OS << "new ";
2327 unsigned NumPlace = E->getNumPlacementArgs();
2328 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2329 OS << "(";
2330 PrintExpr(E->getPlacementArg(0));
2331 for (unsigned i = 1; i < NumPlace; ++i) {
2332 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2333 break;
2334 OS << ", ";
2335 PrintExpr(E->getPlacementArg(i));
2336 }
2337 OS << ") ";
2338 }
2339 if (E->isParenTypeId())
2340 OS << "(";
2341 std::string TypeS;
2342 if (E->isArray()) {
2343 llvm::raw_string_ostream s(TypeS);
2344 s << '[';
2345 if (std::optional<Expr *> Size = E->getArraySize())
2346 (*Size)->printPretty(s, Helper, Policy);
2347 s << ']';
2348 }
2349 E->getAllocatedType().print(OS, Policy, TypeS);
2350 if (E->isParenTypeId())
2351 OS << ")";
2352
2353 CXXNewInitializationStyle InitStyle = E->getInitializationStyle();
2354 if (InitStyle != CXXNewInitializationStyle::None) {
2355 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2356 !isa<ParenListExpr>(E->getInitializer());
2357 if (Bare)
2358 OS << "(";
2359 PrintExpr(E->getInitializer());
2360 if (Bare)
2361 OS << ")";
2362 }
2363}
2364
2365void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2366 if (E->isGlobalDelete())
2367 OS << "::";
2368 OS << "delete ";
2369 if (E->isArrayForm())
2370 OS << "[] ";
2371 PrintExpr(E->getArgument());
2372}
2373
2374void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2375 PrintExpr(E->getBase());
2376 if (E->isArrow())
2377 OS << "->";
2378 else
2379 OS << '.';
2380 if (E->getQualifier())
2381 E->getQualifier()->print(OS, Policy);
2382 OS << "~";
2383
2384 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2385 OS << II->getName();
2386 else
2387 E->getDestroyedType().print(OS, Policy);
2388}
2389
2390void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2391 if (E->isListInitialization() && !E->isStdInitListInitialization())
2392 OS << "{";
2393
2394 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2395 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2396 // Don't print any defaulted arguments
2397 break;
2398 }
2399
2400 if (i) OS << ", ";
2401 PrintExpr(E->getArg(i));
2402 }
2403
2404 if (E->isListInitialization() && !E->isStdInitListInitialization())
2405 OS << "}";
2406}
2407
2408void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2409 // Parens are printed by the surrounding context.
2410 OS << "<forwarded>";
2411}
2412
2413void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2414 PrintExpr(E->getSubExpr());
2415}
2416
2417void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2418 // Just forward to the subexpression.
2419 PrintExpr(E->getSubExpr());
2420}
2421
2422void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2424 Node->getTypeAsWritten().print(OS, Policy);
2425 if (!Node->isListInitialization())
2426 OS << '(';
2427 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2428 ++Arg) {
2429 if (Arg != Node->arg_begin())
2430 OS << ", ";
2431 PrintExpr(*Arg);
2432 }
2433 if (!Node->isListInitialization())
2434 OS << ')';
2435}
2436
2437void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2439 if (!Node->isImplicitAccess()) {
2440 PrintExpr(Node->getBase());
2441 OS << (Node->isArrow() ? "->" : ".");
2442 }
2443 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2444 Qualifier->print(OS, Policy);
2445 if (Node->hasTemplateKeyword())
2446 OS << "template ";
2447 OS << Node->getMemberNameInfo();
2448 if (Node->hasExplicitTemplateArgs())
2449 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2450}
2451
2452void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2453 if (!Node->isImplicitAccess()) {
2454 PrintExpr(Node->getBase());
2455 OS << (Node->isArrow() ? "->" : ".");
2456 }
2457 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2458 Qualifier->print(OS, Policy);
2459 if (Node->hasTemplateKeyword())
2460 OS << "template ";
2461 OS << Node->getMemberNameInfo();
2462 if (Node->hasExplicitTemplateArgs())
2463 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2464}
2465
2466void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2467 OS << getTraitSpelling(E->getTrait()) << "(";
2468 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2469 if (I > 0)
2470 OS << ", ";
2471 E->getArg(I)->getType().print(OS, Policy);
2472 }
2473 OS << ")";
2474}
2475
2476void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2477 OS << getTraitSpelling(E->getTrait()) << '(';
2478 E->getQueriedType().print(OS, Policy);
2479 OS << ')';
2480}
2481
2482void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2483 OS << getTraitSpelling(E->getTrait()) << '(';
2484 PrintExpr(E->getQueriedExpression());
2485 OS << ')';
2486}
2487
2488void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2489 OS << "noexcept(";
2490 PrintExpr(E->getOperand());
2491 OS << ")";
2492}
2493
2494void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2495 PrintExpr(E->getPattern());
2496 OS << "...";
2497}
2498
2499void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2500 OS << "sizeof...(" << *E->getPack() << ")";
2501}
2502
2503void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2504 OS << E->getPackIdExpression() << "...[" << E->getIndexExpr() << "]";
2505}
2506
2507void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2509 OS << *Node->getParameterPack();
2510}
2511
2512void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2514 Visit(Node->getReplacement());
2515}
2516
2517void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2518 OS << *E->getParameterPack();
2519}
2520
2521void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2522 PrintExpr(Node->getSubExpr());
2523}
2524
2525void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2526 OS << "(";
2527 if (E->getLHS()) {
2528 PrintExpr(E->getLHS());
2529 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2530 }
2531 OS << "...";
2532 if (E->getRHS()) {
2533 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2534 PrintExpr(E->getRHS());
2535 }
2536 OS << ")";
2537}
2538
2539void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2540 OS << "(";
2541 llvm::interleaveComma(Node->getInitExprs(), OS,
2542 [&](Expr *E) { PrintExpr(E); });
2543 OS << ")";
2544}
2545
2546void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2547 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2548 if (NNS)
2549 NNS.getNestedNameSpecifier()->print(OS, Policy);
2550 if (E->getTemplateKWLoc().isValid())
2551 OS << "template ";
2552 OS << E->getFoundDecl()->getName();
2553 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2554 Policy,
2555 E->getNamedConcept()->getTemplateParameters());
2556}
2557
2558void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2559 OS << "requires ";
2560 auto LocalParameters = E->getLocalParameters();
2561 if (!LocalParameters.empty()) {
2562 OS << "(";
2563 for (ParmVarDecl *LocalParam : LocalParameters) {
2564 PrintRawDecl(LocalParam);
2565 if (LocalParam != LocalParameters.back())
2566 OS << ", ";
2567 }
2568
2569 OS << ") ";
2570 }
2571 OS << "{ ";
2572 auto Requirements = E->getRequirements();
2573 for (concepts::Requirement *Req : Requirements) {
2574 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2575 if (TypeReq->isSubstitutionFailure())
2576 OS << "<<error-type>>";
2577 else
2578 TypeReq->getType()->getType().print(OS, Policy);
2579 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2580 if (ExprReq->isCompound())
2581 OS << "{ ";
2582 if (ExprReq->isExprSubstitutionFailure())
2583 OS << "<<error-expression>>";
2584 else
2585 PrintExpr(ExprReq->getExpr());
2586 if (ExprReq->isCompound()) {
2587 OS << " }";
2588 if (ExprReq->getNoexceptLoc().isValid())
2589 OS << " noexcept";
2590 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2591 if (!RetReq.isEmpty()) {
2592 OS << " -> ";
2593 if (RetReq.isSubstitutionFailure())
2594 OS << "<<error-type>>";
2595 else if (RetReq.isTypeConstraint())
2596 RetReq.getTypeConstraint()->print(OS, Policy);
2597 }
2598 }
2599 } else {
2600 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2601 OS << "requires ";
2602 if (NestedReq->hasInvalidConstraint())
2603 OS << "<<error-expression>>";
2604 else
2605 PrintExpr(NestedReq->getConstraintExpr());
2606 }
2607 OS << "; ";
2608 }
2609 OS << "}";
2610}
2611
2612// C++ Coroutines
2613
2614void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2615 Visit(S->getBody());
2616}
2617
2618void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2619 OS << "co_return";
2620 if (S->getOperand()) {
2621 OS << " ";
2622 Visit(S->getOperand());
2623 }
2624 OS << ";";
2625}
2626
2627void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2628 OS << "co_await ";
2629 PrintExpr(S->getOperand());
2630}
2631
2632void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2633 OS << "co_await ";
2634 PrintExpr(S->getOperand());
2635}
2636
2637void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2638 OS << "co_yield ";
2639 PrintExpr(S->getOperand());
2640}
2641
2642// Obj-C
2643
2644void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2645 OS << "@";
2646 VisitStringLiteral(Node->getString());
2647}
2648
2649void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2650 OS << "@";
2651 Visit(E->getSubExpr());
2652}
2653
2654void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2655 OS << "@[ ";
2657 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2658 if (I != Ch.begin())
2659 OS << ", ";
2660 Visit(*I);
2661 }
2662 OS << " ]";
2663}
2664
2665void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2666 OS << "@{ ";
2667 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2668 if (I > 0)
2669 OS << ", ";
2670
2671 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2672 Visit(Element.Key);
2673 OS << " : ";
2674 Visit(Element.Value);
2675 if (Element.isPackExpansion())
2676 OS << "...";
2677 }
2678 OS << " }";
2679}
2680
2681void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2682 OS << "@encode(";
2683 Node->getEncodedType().print(OS, Policy);
2684 OS << ')';
2685}
2686
2687void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2688 OS << "@selector(";
2689 Node->getSelector().print(OS);
2690 OS << ')';
2691}
2692
2693void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2694 OS << "@protocol(" << *Node->getProtocol() << ')';
2695}
2696
2697void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2698 OS << "[";
2699 switch (Mess->getReceiverKind()) {
2701 PrintExpr(Mess->getInstanceReceiver());
2702 break;
2703
2705 Mess->getClassReceiver().print(OS, Policy);
2706 break;
2707
2710 OS << "Super";
2711 break;
2712 }
2713
2714 OS << ' ';
2715 Selector selector = Mess->getSelector();
2716 if (selector.isUnarySelector()) {
2717 OS << selector.getNameForSlot(0);
2718 } else {
2719 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2720 if (i < selector.getNumArgs()) {
2721 if (i > 0) OS << ' ';
2722 if (selector.getIdentifierInfoForSlot(i))
2723 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2724 else
2725 OS << ":";
2726 }
2727 else OS << ", "; // Handle variadic methods.
2728
2729 PrintExpr(Mess->getArg(i));
2730 }
2731 }
2732 OS << "]";
2733}
2734
2735void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2736 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2737}
2738
2739void
2740StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2741 PrintExpr(E->getSubExpr());
2742}
2743
2744void
2745StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2746 OS << '(' << E->getBridgeKindName();
2747 E->getType().print(OS, Policy);
2748 OS << ')';
2749 PrintExpr(E->getSubExpr());
2750}
2751
2752void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2753 BlockDecl *BD = Node->getBlockDecl();
2754 OS << "^";
2755
2756 const FunctionType *AFT = Node->getFunctionType();
2757
2758 if (isa<FunctionNoProtoType>(AFT)) {
2759 OS << "()";
2760 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2761 OS << '(';
2762 for (BlockDecl::param_iterator AI = BD->param_begin(),
2763 E = BD->param_end(); AI != E; ++AI) {
2764 if (AI != BD->param_begin()) OS << ", ";
2765 std::string ParamStr = (*AI)->getNameAsString();
2766 (*AI)->getType().print(OS, Policy, ParamStr);
2767 }
2768
2769 const auto *FT = cast<FunctionProtoType>(AFT);
2770 if (FT->isVariadic()) {
2771 if (!BD->param_empty()) OS << ", ";
2772 OS << "...";
2773 }
2774 OS << ')';
2775 }
2776 OS << "{ }";
2777}
2778
2779void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2780 PrintExpr(Node->getSourceExpr());
2781}
2782
2783void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2784 // TODO: Print something reasonable for a TypoExpr, if necessary.
2785 llvm_unreachable("Cannot print TypoExpr nodes");
2786}
2787
2788void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2789 OS << "<recovery-expr>(";
2790 const char *Sep = "";
2791 for (Expr *E : Node->subExpressions()) {
2792 OS << Sep;
2793 PrintExpr(E);
2794 Sep = ", ";
2795 }
2796 OS << ')';
2797}
2798
2799void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2800 OS << "__builtin_astype(";
2801 PrintExpr(Node->getSrcExpr());
2802 OS << ", ";
2803 Node->getType().print(OS, Policy);
2804 OS << ")";
2805}
2806
2807//===----------------------------------------------------------------------===//
2808// Stmt method implementations
2809//===----------------------------------------------------------------------===//
2810
2811void Stmt::dumpPretty(const ASTContext &Context) const {
2812 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2813}
2814
2815void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2816 const PrintingPolicy &Policy, unsigned Indentation,
2817 StringRef NL, const ASTContext *Context) const {
2818 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2819 P.Visit(const_cast<Stmt *>(this));
2820}
2821
2822void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2823 const PrintingPolicy &Policy,
2824 unsigned Indentation, StringRef NL,
2825 const ASTContext *Context) const {
2826 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2827 P.PrintControlledStmt(const_cast<Stmt *>(this));
2828}
2829
2830void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2831 const PrintingPolicy &Policy, bool AddQuotes) const {
2832 std::string Buf;
2833 llvm::raw_string_ostream TempOut(Buf);
2834
2835 printPretty(TempOut, Helper, Policy);
2836
2837 Out << JsonFormat(TempOut.str(), AddQuotes);
2838}
2839
2840//===----------------------------------------------------------------------===//
2841// PrinterHelper
2842//===----------------------------------------------------------------------===//
2843
2844// 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:1171
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:1144
SourceRange Range
Definition: SemaObjC.cpp:758
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
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:187
SourceManager & getSourceManager()
Definition: ASTContext.h:721
const LangOptions & getLangOpts() const
Definition: ASTContext.h:797
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4372
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5756
Represents a loop initializing the elements of an array.
Definition: Expr.h:5703
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition: Expr.h:6926
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:6426
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6629
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:2090
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4275
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3860
StringRef getOpcodeStr() const
Definition: Expr.h:3926
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4471
param_iterator param_end()
Definition: Decl.h:4570
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition: Decl.h:4565
param_iterator param_begin()
Definition: Decl.h:4569
bool param_empty() const
Definition: Decl.h:4568
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6365
BreakStmt - This represents a break.
Definition: Stmt.h:2990
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5291
This class is used for builtin types like 'int'.
Definition: Type.h:3023
Kind getKind() const
Definition: Type.h:3071
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:3682
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:4839
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:2064
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:4125
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:4953
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:3556
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:3767
CaseStmt - Represent a case statement.
Definition: Stmt.h:1811
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:4592
Represents a 'co_await' expression.
Definition: ExprCXX.h:5184
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4122
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3428
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1611
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4213
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:2960
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4533
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:5265
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:1502
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:5216
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3322
Represents a single C99 designator.
Definition: Expr.h:5327
Represents a C99 designated initializer expression.
Definition: Expr.h:5284
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2735
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:4867
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3473
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:6305
Represents difference between two FPOptions values.
Definition: LangOptions.h:947
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:4546
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2791
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:4647
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4308
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:3269
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4667
Represents a C11 generic selection.
Definition: Expr.h:5917
AssociationTy< false > Association
Definition: Expr.h:6148
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2872
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:2148
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:5792
IndirectGotoStmt - This represents an indirect goto.
Definition: Stmt.h:2911
Describes an C or C++ initializer list.
Definition: Expr.h:5039
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2041
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:3492
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:4727
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:5612
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition: Stmt.h:1574
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:4179
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:6497
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:7101
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:3029
Represents a __leave statement.
Definition: Stmt.h:3728
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:4465
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4257
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4761
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4417
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:1452
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:4483
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition: ExprCXX.h:4568
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2398
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:7721
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:8607
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
Definition: Expr.h:6777
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:3942
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:4701
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:2594
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:1321