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