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}
1207
1208void StmtPrinter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {
1209 PrintOpenACCConstruct(S);
1210}
1211
1212void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
1213 Indent() << "#pragma acc wait";
1214 if (!S->getLParenLoc().isInvalid()) {
1215 OS << "(";
1216 if (S->hasDevNumExpr()) {
1217 OS << "devnum: ";
1218 S->getDevNumExpr()->printPretty(OS, nullptr, Policy);
1219 OS << " : ";
1220 }
1221
1222 if (S->hasQueuesTag())
1223 OS << "queues: ";
1224
1225 llvm::interleaveComma(S->getQueueIdExprs(), OS, [&](const Expr *E) {
1226 E->printPretty(OS, nullptr, Policy);
1227 });
1228
1229 OS << ")";
1230 }
1231
1232 PrintOpenACCClauseList(S);
1233 OS << '\n';
1234}
1235
1236//===----------------------------------------------------------------------===//
1237// Expr printing methods.
1238//===----------------------------------------------------------------------===//
1239
1240void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1241 OS << Node->getBuiltinStr() << "()";
1242}
1243
1244void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
1245 llvm::report_fatal_error("Not implemented");
1246}
1247
1248void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1249 PrintExpr(Node->getSubExpr());
1250}
1251
1252void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1253 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
1254 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1255 return;
1256 }
1257 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) {
1258 TPOD->printAsExpr(OS, Policy);
1259 return;
1260 }
1261 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1262 Qualifier->print(OS, Policy);
1263 if (Node->hasTemplateKeyword())
1264 OS << "template ";
1265 if (Policy.CleanUglifiedParameters &&
1266 isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) &&
1267 Node->getDecl()->getIdentifier())
1268 OS << Node->getDecl()->getIdentifier()->deuglifiedName();
1269 else
1270 Node->getNameInfo().printName(OS, Policy);
1271 if (Node->hasExplicitTemplateArgs()) {
1272 const TemplateParameterList *TPL = nullptr;
1273 if (!Node->hadMultipleCandidates())
1274 if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
1275 TPL = TD->getTemplateParameters();
1276 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1277 }
1278}
1279
1280void StmtPrinter::VisitDependentScopeDeclRefExpr(
1282 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1283 Qualifier->print(OS, Policy);
1284 if (Node->hasTemplateKeyword())
1285 OS << "template ";
1286 OS << Node->getNameInfo();
1287 if (Node->hasExplicitTemplateArgs())
1288 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1289}
1290
1291void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1292 if (Node->getQualifier())
1293 Node->getQualifier()->print(OS, Policy);
1294 if (Node->hasTemplateKeyword())
1295 OS << "template ";
1296 OS << Node->getNameInfo();
1297 if (Node->hasExplicitTemplateArgs())
1298 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1299}
1300
1301static bool isImplicitSelf(const Expr *E) {
1302 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1303 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1304 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1305 DRE->getBeginLoc().isInvalid())
1306 return true;
1307 }
1308 }
1309 return false;
1310}
1311
1312void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1313 if (Node->getBase()) {
1314 if (!Policy.SuppressImplicitBase ||
1315 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1316 PrintExpr(Node->getBase());
1317 OS << (Node->isArrow() ? "->" : ".");
1318 }
1319 }
1320 OS << *Node->getDecl();
1321}
1322
1323void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1324 if (Node->isSuperReceiver())
1325 OS << "super.";
1326 else if (Node->isObjectReceiver() && Node->getBase()) {
1327 PrintExpr(Node->getBase());
1328 OS << ".";
1329 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1330 OS << Node->getClassReceiver()->getName() << ".";
1331 }
1332
1333 if (Node->isImplicitProperty()) {
1334 if (const auto *Getter = Node->getImplicitPropertyGetter())
1335 Getter->getSelector().print(OS);
1336 else
1338 Node->getImplicitPropertySetter()->getSelector());
1339 } else
1340 OS << Node->getExplicitProperty()->getName();
1341}
1342
1343void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1344 PrintExpr(Node->getBaseExpr());
1345 OS << "[";
1346 PrintExpr(Node->getKeyExpr());
1347 OS << "]";
1348}
1349
1350void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1352 OS << "__builtin_sycl_unique_stable_name(";
1353 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1354 OS << ")";
1355}
1356
1357void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1358 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1359}
1360
1361void StmtPrinter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *Node) {
1362 OS << '*';
1363}
1364
1365void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1366 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1367}
1368
1369/// Prints the given expression using the original source text. Returns true on
1370/// success, false otherwise.
1371static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1372 const ASTContext *Context) {
1373 if (!Context)
1374 return false;
1375 bool Invalid = false;
1376 StringRef Source = Lexer::getSourceText(
1378 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1379 if (!Invalid) {
1380 OS << Source;
1381 return true;
1382 }
1383 return false;
1384}
1385
1386void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1387 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1388 return;
1389 bool isSigned = Node->getType()->isSignedIntegerType();
1390 OS << toString(Node->getValue(), 10, isSigned);
1391
1392 if (isa<BitIntType>(Node->getType())) {
1393 OS << (isSigned ? "wb" : "uwb");
1394 return;
1395 }
1396
1397 // Emit suffixes. Integer literals are always a builtin integer type.
1398 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1399 default: llvm_unreachable("Unexpected type for integer literal!");
1400 case BuiltinType::Char_S:
1401 case BuiltinType::Char_U: OS << "i8"; break;
1402 case BuiltinType::UChar: OS << "Ui8"; break;
1403 case BuiltinType::SChar: OS << "i8"; break;
1404 case BuiltinType::Short: OS << "i16"; break;
1405 case BuiltinType::UShort: OS << "Ui16"; break;
1406 case BuiltinType::Int: break; // no suffix.
1407 case BuiltinType::UInt: OS << 'U'; break;
1408 case BuiltinType::Long: OS << 'L'; break;
1409 case BuiltinType::ULong: OS << "UL"; break;
1410 case BuiltinType::LongLong: OS << "LL"; break;
1411 case BuiltinType::ULongLong: OS << "ULL"; break;
1412 case BuiltinType::Int128:
1413 break; // no suffix.
1414 case BuiltinType::UInt128:
1415 break; // no suffix.
1416 case BuiltinType::WChar_S:
1417 case BuiltinType::WChar_U:
1418 break; // no suffix
1419 }
1420}
1421
1422void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1423 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1424 return;
1425 OS << Node->getValueAsString(/*Radix=*/10);
1426
1427 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1428 default: llvm_unreachable("Unexpected type for fixed point literal!");
1429 case BuiltinType::ShortFract: OS << "hr"; break;
1430 case BuiltinType::ShortAccum: OS << "hk"; break;
1431 case BuiltinType::UShortFract: OS << "uhr"; break;
1432 case BuiltinType::UShortAccum: OS << "uhk"; break;
1433 case BuiltinType::Fract: OS << "r"; break;
1434 case BuiltinType::Accum: OS << "k"; break;
1435 case BuiltinType::UFract: OS << "ur"; break;
1436 case BuiltinType::UAccum: OS << "uk"; break;
1437 case BuiltinType::LongFract: OS << "lr"; break;
1438 case BuiltinType::LongAccum: OS << "lk"; break;
1439 case BuiltinType::ULongFract: OS << "ulr"; break;
1440 case BuiltinType::ULongAccum: OS << "ulk"; break;
1441 }
1442}
1443
1444static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1445 bool PrintSuffix) {
1446 SmallString<16> Str;
1447 Node->getValue().toString(Str);
1448 OS << Str;
1449 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1450 OS << '.'; // Trailing dot in order to separate from ints.
1451
1452 if (!PrintSuffix)
1453 return;
1454
1455 // Emit suffixes. Float literals are always a builtin float type.
1456 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1457 default: llvm_unreachable("Unexpected type for float literal!");
1458 case BuiltinType::Half: break; // FIXME: suffix?
1459 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1460 case BuiltinType::Double: break; // no suffix.
1461 case BuiltinType::Float16: OS << "F16"; break;
1462 case BuiltinType::Float: OS << 'F'; break;
1463 case BuiltinType::LongDouble: OS << 'L'; break;
1464 case BuiltinType::Float128: OS << 'Q'; break;
1465 }
1466}
1467
1468void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1469 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1470 return;
1471 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1472}
1473
1474void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1475 PrintExpr(Node->getSubExpr());
1476 OS << "i";
1477}
1478
1479void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1480 Str->outputString(OS);
1481}
1482
1483void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1484 OS << "(";
1485 PrintExpr(Node->getSubExpr());
1486 OS << ")";
1487}
1488
1489void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1490 if (!Node->isPostfix()) {
1491 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1492
1493 // Print a space if this is an "identifier operator" like __real, or if
1494 // it might be concatenated incorrectly like '+'.
1495 switch (Node->getOpcode()) {
1496 default: break;
1497 case UO_Real:
1498 case UO_Imag:
1499 case UO_Extension:
1500 OS << ' ';
1501 break;
1502 case UO_Plus:
1503 case UO_Minus:
1504 if (isa<UnaryOperator>(Node->getSubExpr()))
1505 OS << ' ';
1506 break;
1507 }
1508 }
1509 PrintExpr(Node->getSubExpr());
1510
1511 if (Node->isPostfix())
1512 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1513}
1514
1515void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1516 OS << "__builtin_offsetof(";
1517 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1518 OS << ", ";
1519 bool PrintedSomething = false;
1520 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1521 OffsetOfNode ON = Node->getComponent(i);
1522 if (ON.getKind() == OffsetOfNode::Array) {
1523 // Array node
1524 OS << "[";
1525 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1526 OS << "]";
1527 PrintedSomething = true;
1528 continue;
1529 }
1530
1531 // Skip implicit base indirections.
1532 if (ON.getKind() == OffsetOfNode::Base)
1533 continue;
1534
1535 // Field or identifier node.
1536 const IdentifierInfo *Id = ON.getFieldName();
1537 if (!Id)
1538 continue;
1539
1540 if (PrintedSomething)
1541 OS << ".";
1542 else
1543 PrintedSomething = true;
1544 OS << Id->getName();
1545 }
1546 OS << ")";
1547}
1548
1549void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1551 const char *Spelling = getTraitSpelling(Node->getKind());
1552 if (Node->getKind() == UETT_AlignOf) {
1553 if (Policy.Alignof)
1554 Spelling = "alignof";
1555 else if (Policy.UnderscoreAlignof)
1556 Spelling = "_Alignof";
1557 else
1558 Spelling = "__alignof";
1559 }
1560
1561 OS << Spelling;
1562
1563 if (Node->isArgumentType()) {
1564 OS << '(';
1565 Node->getArgumentType().print(OS, Policy);
1566 OS << ')';
1567 } else {
1568 OS << " ";
1569 PrintExpr(Node->getArgumentExpr());
1570 }
1571}
1572
1573void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1574 OS << "_Generic(";
1575 if (Node->isExprPredicate())
1576 PrintExpr(Node->getControllingExpr());
1577 else
1578 Node->getControllingType()->getType().print(OS, Policy);
1579
1580 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1581 OS << ", ";
1582 QualType T = Assoc.getType();
1583 if (T.isNull())
1584 OS << "default";
1585 else
1586 T.print(OS, Policy);
1587 OS << ": ";
1588 PrintExpr(Assoc.getAssociationExpr());
1589 }
1590 OS << ")";
1591}
1592
1593void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1594 PrintExpr(Node->getLHS());
1595 OS << "[";
1596 PrintExpr(Node->getRHS());
1597 OS << "]";
1598}
1599
1600void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1601 PrintExpr(Node->getBase());
1602 OS << "[";
1603 PrintExpr(Node->getRowIdx());
1604 OS << "]";
1605 OS << "[";
1606 PrintExpr(Node->getColumnIdx());
1607 OS << "]";
1608}
1609
1610void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) {
1611 PrintExpr(Node->getBase());
1612 OS << "[";
1613 if (Node->getLowerBound())
1614 PrintExpr(Node->getLowerBound());
1615 if (Node->getColonLocFirst().isValid()) {
1616 OS << ":";
1617 if (Node->getLength())
1618 PrintExpr(Node->getLength());
1619 }
1620 if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) {
1621 OS << ":";
1622 if (Node->getStride())
1623 PrintExpr(Node->getStride());
1624 }
1625 OS << "]";
1626}
1627
1628void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1629 OS << "(";
1630 for (Expr *E : Node->getDimensions()) {
1631 OS << "[";
1632 PrintExpr(E);
1633 OS << "]";
1634 }
1635 OS << ")";
1636 PrintExpr(Node->getBase());
1637}
1638
1639void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1640 OS << "iterator(";
1641 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1642 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1643 VD->getType().print(OS, Policy);
1644 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1645 OS << " " << VD->getName() << " = ";
1646 PrintExpr(Range.Begin);
1647 OS << ":";
1648 PrintExpr(Range.End);
1649 if (Range.Step) {
1650 OS << ":";
1651 PrintExpr(Range.Step);
1652 }
1653 if (I < E - 1)
1654 OS << ", ";
1655 }
1656 OS << ")";
1657}
1658
1659void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1660 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1661 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1662 // Don't print any defaulted arguments
1663 break;
1664 }
1665
1666 if (i) OS << ", ";
1667 PrintExpr(Call->getArg(i));
1668 }
1669}
1670
1671void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1672 PrintExpr(Call->getCallee());
1673 OS << "(";
1674 PrintCallArgs(Call);
1675 OS << ")";
1676}
1677
1678static bool isImplicitThis(const Expr *E) {
1679 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1680 return TE->isImplicit();
1681 return false;
1682}
1683
1684void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1685 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1686 PrintExpr(Node->getBase());
1687
1688 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1689 FieldDecl *ParentDecl =
1690 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1691 : nullptr;
1692
1693 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1694 OS << (Node->isArrow() ? "->" : ".");
1695 }
1696
1697 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1698 if (FD->isAnonymousStructOrUnion())
1699 return;
1700
1701 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1702 Qualifier->print(OS, Policy);
1703 if (Node->hasTemplateKeyword())
1704 OS << "template ";
1705 OS << Node->getMemberNameInfo();
1706 const TemplateParameterList *TPL = nullptr;
1707 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1708 if (!Node->hadMultipleCandidates())
1709 if (auto *FTD = FD->getPrimaryTemplate())
1710 TPL = FTD->getTemplateParameters();
1711 } else if (auto *VTSD =
1712 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1713 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1714 if (Node->hasExplicitTemplateArgs())
1715 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1716}
1717
1718void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1719 PrintExpr(Node->getBase());
1720 OS << (Node->isArrow() ? "->isa" : ".isa");
1721}
1722
1723void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1724 PrintExpr(Node->getBase());
1725 OS << ".";
1726 OS << Node->getAccessor().getName();
1727}
1728
1729void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1730 OS << '(';
1731 Node->getTypeAsWritten().print(OS, Policy);
1732 OS << ')';
1733 PrintExpr(Node->getSubExpr());
1734}
1735
1736void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1737 OS << '(';
1738 Node->getType().print(OS, Policy);
1739 OS << ')';
1740 PrintExpr(Node->getInitializer());
1741}
1742
1743void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1744 // No need to print anything, simply forward to the subexpression.
1745 PrintExpr(Node->getSubExpr());
1746}
1747
1748void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1749 PrintExpr(Node->getLHS());
1750 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1751 PrintExpr(Node->getRHS());
1752}
1753
1754void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1755 PrintExpr(Node->getLHS());
1756 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1757 PrintExpr(Node->getRHS());
1758}
1759
1760void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1761 PrintExpr(Node->getCond());
1762 OS << " ? ";
1763 PrintExpr(Node->getLHS());
1764 OS << " : ";
1765 PrintExpr(Node->getRHS());
1766}
1767
1768// GNU extensions.
1769
1770void
1771StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1772 PrintExpr(Node->getCommon());
1773 OS << " ?: ";
1774 PrintExpr(Node->getFalseExpr());
1775}
1776
1777void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1778 OS << "&&" << Node->getLabel()->getName();
1779}
1780
1781void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1782 OS << "(";
1783 PrintRawCompoundStmt(E->getSubStmt());
1784 OS << ")";
1785}
1786
1787void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1788 OS << "__builtin_choose_expr(";
1789 PrintExpr(Node->getCond());
1790 OS << ", ";
1791 PrintExpr(Node->getLHS());
1792 OS << ", ";
1793 PrintExpr(Node->getRHS());
1794 OS << ")";
1795}
1796
1797void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1798 OS << "__null";
1799}
1800
1801void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1802 OS << "__builtin_shufflevector(";
1803 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1804 if (i) OS << ", ";
1805 PrintExpr(Node->getExpr(i));
1806 }
1807 OS << ")";
1808}
1809
1810void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1811 OS << "__builtin_convertvector(";
1812 PrintExpr(Node->getSrcExpr());
1813 OS << ", ";
1814 Node->getType().print(OS, Policy);
1815 OS << ")";
1816}
1817
1818void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1819 if (Node->getSyntacticForm()) {
1820 Visit(Node->getSyntacticForm());
1821 return;
1822 }
1823
1824 OS << "{";
1825 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1826 if (i) OS << ", ";
1827 if (Node->getInit(i))
1828 PrintExpr(Node->getInit(i));
1829 else
1830 OS << "{}";
1831 }
1832 OS << "}";
1833}
1834
1835void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1836 // There's no way to express this expression in any of our supported
1837 // languages, so just emit something terse and (hopefully) clear.
1838 OS << "{";
1839 PrintExpr(Node->getSubExpr());
1840 OS << "}";
1841}
1842
1843void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1844 OS << "*";
1845}
1846
1847void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1848 OS << "(";
1849 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1850 if (i) OS << ", ";
1851 PrintExpr(Node->getExpr(i));
1852 }
1853 OS << ")";
1854}
1855
1856void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1857 bool NeedsEquals = true;
1858 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1859 if (D.isFieldDesignator()) {
1860 if (D.getDotLoc().isInvalid()) {
1861 if (const IdentifierInfo *II = D.getFieldName()) {
1862 OS << II->getName() << ":";
1863 NeedsEquals = false;
1864 }
1865 } else {
1866 OS << "." << D.getFieldName()->getName();
1867 }
1868 } else {
1869 OS << "[";
1870 if (D.isArrayDesignator()) {
1871 PrintExpr(Node->getArrayIndex(D));
1872 } else {
1873 PrintExpr(Node->getArrayRangeStart(D));
1874 OS << " ... ";
1875 PrintExpr(Node->getArrayRangeEnd(D));
1876 }
1877 OS << "]";
1878 }
1879 }
1880
1881 if (NeedsEquals)
1882 OS << " = ";
1883 else
1884 OS << " ";
1885 PrintExpr(Node->getInit());
1886}
1887
1888void StmtPrinter::VisitDesignatedInitUpdateExpr(
1890 OS << "{";
1891 OS << "/*base*/";
1892 PrintExpr(Node->getBase());
1893 OS << ", ";
1894
1895 OS << "/*updater*/";
1896 PrintExpr(Node->getUpdater());
1897 OS << "}";
1898}
1899
1900void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1901 OS << "/*no init*/";
1902}
1903
1904void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1905 if (Node->getType()->getAsCXXRecordDecl()) {
1906 OS << "/*implicit*/";
1907 Node->getType().print(OS, Policy);
1908 OS << "()";
1909 } else {
1910 OS << "/*implicit*/(";
1911 Node->getType().print(OS, Policy);
1912 OS << ')';
1913 if (Node->getType()->isRecordType())
1914 OS << "{}";
1915 else
1916 OS << 0;
1917 }
1918}
1919
1920void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1921 OS << "__builtin_va_arg(";
1922 PrintExpr(Node->getSubExpr());
1923 OS << ", ";
1924 Node->getType().print(OS, Policy);
1925 OS << ")";
1926}
1927
1928void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1929 PrintExpr(Node->getSyntacticForm());
1930}
1931
1932void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1933 const char *Name = nullptr;
1934 switch (Node->getOp()) {
1935#define BUILTIN(ID, TYPE, ATTRS)
1936#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1937 case AtomicExpr::AO ## ID: \
1938 Name = #ID "("; \
1939 break;
1940#include "clang/Basic/Builtins.inc"
1941 }
1942 OS << Name;
1943
1944 // AtomicExpr stores its subexpressions in a permuted order.
1945 PrintExpr(Node->getPtr());
1946 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1947 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1948 Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
1949 Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
1950 Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
1951 OS << ", ";
1952 PrintExpr(Node->getVal1());
1953 }
1954 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1955 Node->isCmpXChg()) {
1956 OS << ", ";
1957 PrintExpr(Node->getVal2());
1958 }
1959 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1960 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1961 OS << ", ";
1962 PrintExpr(Node->getWeak());
1963 }
1964 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1965 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1966 OS << ", ";
1967 PrintExpr(Node->getOrder());
1968 }
1969 if (Node->isCmpXChg()) {
1970 OS << ", ";
1971 PrintExpr(Node->getOrderFail());
1972 }
1973 OS << ")";
1974}
1975
1976// C++
1977void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1978 OverloadedOperatorKind Kind = Node->getOperator();
1979 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1980 if (Node->getNumArgs() == 1) {
1981 OS << getOperatorSpelling(Kind) << ' ';
1982 PrintExpr(Node->getArg(0));
1983 } else {
1984 PrintExpr(Node->getArg(0));
1985 OS << ' ' << getOperatorSpelling(Kind);
1986 }
1987 } else if (Kind == OO_Arrow) {
1988 PrintExpr(Node->getArg(0));
1989 } else if (Kind == OO_Call || Kind == OO_Subscript) {
1990 PrintExpr(Node->getArg(0));
1991 OS << (Kind == OO_Call ? '(' : '[');
1992 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1993 if (ArgIdx > 1)
1994 OS << ", ";
1995 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1996 PrintExpr(Node->getArg(ArgIdx));
1997 }
1998 OS << (Kind == OO_Call ? ')' : ']');
1999 } else if (Node->getNumArgs() == 1) {
2000 OS << getOperatorSpelling(Kind) << ' ';
2001 PrintExpr(Node->getArg(0));
2002 } else if (Node->getNumArgs() == 2) {
2003 PrintExpr(Node->getArg(0));
2004 OS << ' ' << getOperatorSpelling(Kind) << ' ';
2005 PrintExpr(Node->getArg(1));
2006 } else {
2007 llvm_unreachable("unknown overloaded operator");
2008 }
2009}
2010
2011void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2012 // If we have a conversion operator call only print the argument.
2013 CXXMethodDecl *MD = Node->getMethodDecl();
2014 if (isa_and_nonnull<CXXConversionDecl>(MD)) {
2015 PrintExpr(Node->getImplicitObjectArgument());
2016 return;
2017 }
2018 VisitCallExpr(cast<CallExpr>(Node));
2019}
2020
2021void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2022 PrintExpr(Node->getCallee());
2023 OS << "<<<";
2024 PrintCallArgs(Node->getConfig());
2025 OS << ">>>(";
2026 PrintCallArgs(Node);
2027 OS << ")";
2028}
2029
2030void StmtPrinter::VisitCXXRewrittenBinaryOperator(
2033 Node->getDecomposedForm();
2034 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
2035 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
2036 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
2037}
2038
2039void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2040 OS << Node->getCastName() << '<';
2041 Node->getTypeAsWritten().print(OS, Policy);
2042 OS << ">(";
2043 PrintExpr(Node->getSubExpr());
2044 OS << ")";
2045}
2046
2047void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2048 VisitCXXNamedCastExpr(Node);
2049}
2050
2051void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2052 VisitCXXNamedCastExpr(Node);
2053}
2054
2055void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2056 VisitCXXNamedCastExpr(Node);
2057}
2058
2059void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2060 VisitCXXNamedCastExpr(Node);
2061}
2062
2063void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
2064 OS << "__builtin_bit_cast(";
2065 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
2066 OS << ", ";
2067 PrintExpr(Node->getSubExpr());
2068 OS << ")";
2069}
2070
2071void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
2072 VisitCXXNamedCastExpr(Node);
2073}
2074
2075void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2076 OS << "typeid(";
2077 if (Node->isTypeOperand()) {
2078 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2079 } else {
2080 PrintExpr(Node->getExprOperand());
2081 }
2082 OS << ")";
2083}
2084
2085void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2086 OS << "__uuidof(";
2087 if (Node->isTypeOperand()) {
2088 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2089 } else {
2090 PrintExpr(Node->getExprOperand());
2091 }
2092 OS << ")";
2093}
2094
2095void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2096 PrintExpr(Node->getBaseExpr());
2097 if (Node->isArrow())
2098 OS << "->";
2099 else
2100 OS << ".";
2101 if (NestedNameSpecifier *Qualifier =
2102 Node->getQualifierLoc().getNestedNameSpecifier())
2103 Qualifier->print(OS, Policy);
2104 OS << Node->getPropertyDecl()->getDeclName();
2105}
2106
2107void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2108 PrintExpr(Node->getBase());
2109 OS << "[";
2110 PrintExpr(Node->getIdx());
2111 OS << "]";
2112}
2113
2114void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2115 switch (Node->getLiteralOperatorKind()) {
2117 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2118 break;
2120 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2121 const TemplateArgumentList *Args =
2122 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2123 assert(Args);
2124
2125 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2126 const TemplateParameterList *TPL = nullptr;
2127 if (!DRE->hadMultipleCandidates())
2128 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2129 TPL = TD->getTemplateParameters();
2130 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2131 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2132 OS << "()";
2133 return;
2134 }
2135
2136 const TemplateArgument &Pack = Args->get(0);
2137 for (const auto &P : Pack.pack_elements()) {
2138 char C = (char)P.getAsIntegral().getZExtValue();
2139 OS << C;
2140 }
2141 break;
2142 }
2144 // Print integer literal without suffix.
2145 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2146 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2147 break;
2148 }
2150 // Print floating literal without suffix.
2151 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
2152 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2153 break;
2154 }
2157 PrintExpr(Node->getCookedLiteral());
2158 break;
2159 }
2160 OS << Node->getUDSuffix()->getName();
2161}
2162
2163void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2164 OS << (Node->getValue() ? "true" : "false");
2165}
2166
2167void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2168 OS << "nullptr";
2169}
2170
2171void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2172 OS << "this";
2173}
2174
2175void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2176 if (!Node->getSubExpr())
2177 OS << "throw";
2178 else {
2179 OS << "throw ";
2180 PrintExpr(Node->getSubExpr());
2181 }
2182}
2183
2184void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2185 // Nothing to print: we picked up the default argument.
2186}
2187
2188void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2189 // Nothing to print: we picked up the default initializer.
2190}
2191
2192void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2193 auto TargetType = Node->getType();
2194 auto *Auto = TargetType->getContainedDeducedType();
2195 bool Bare = Auto && Auto->isDeduced();
2196
2197 // Parenthesize deduced casts.
2198 if (Bare)
2199 OS << '(';
2200 TargetType.print(OS, Policy);
2201 if (Bare)
2202 OS << ')';
2203
2204 // No extra braces surrounding the inner construct.
2205 if (!Node->isListInitialization())
2206 OS << '(';
2207 PrintExpr(Node->getSubExpr());
2208 if (!Node->isListInitialization())
2209 OS << ')';
2210}
2211
2212void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2213 PrintExpr(Node->getSubExpr());
2214}
2215
2216void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2217 Node->getType().print(OS, Policy);
2218 if (Node->isStdInitListInitialization())
2219 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2220 else if (Node->isListInitialization())
2221 OS << "{";
2222 else
2223 OS << "(";
2224 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2225 ArgEnd = Node->arg_end();
2226 Arg != ArgEnd; ++Arg) {
2227 if ((*Arg)->isDefaultArgument())
2228 break;
2229 if (Arg != Node->arg_begin())
2230 OS << ", ";
2231 PrintExpr(*Arg);
2232 }
2233 if (Node->isStdInitListInitialization())
2234 /* See above. */;
2235 else if (Node->isListInitialization())
2236 OS << "}";
2237 else
2238 OS << ")";
2239}
2240
2241void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2242 OS << '[';
2243 bool NeedComma = false;
2244 switch (Node->getCaptureDefault()) {
2245 case LCD_None:
2246 break;
2247
2248 case LCD_ByCopy:
2249 OS << '=';
2250 NeedComma = true;
2251 break;
2252
2253 case LCD_ByRef:
2254 OS << '&';
2255 NeedComma = true;
2256 break;
2257 }
2258 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
2259 CEnd = Node->explicit_capture_end();
2260 C != CEnd;
2261 ++C) {
2262 if (C->capturesVLAType())
2263 continue;
2264
2265 if (NeedComma)
2266 OS << ", ";
2267 NeedComma = true;
2268
2269 switch (C->getCaptureKind()) {
2270 case LCK_This:
2271 OS << "this";
2272 break;
2273
2274 case LCK_StarThis:
2275 OS << "*this";
2276 break;
2277
2278 case LCK_ByRef:
2279 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2280 OS << '&';
2281 OS << C->getCapturedVar()->getName();
2282 break;
2283
2284 case LCK_ByCopy:
2285 OS << C->getCapturedVar()->getName();
2286 break;
2287
2288 case LCK_VLAType:
2289 llvm_unreachable("VLA type in explicit captures.");
2290 }
2291
2292 if (C->isPackExpansion())
2293 OS << "...";
2294
2295 if (Node->isInitCapture(C)) {
2296 // Init captures are always VarDecl.
2297 auto *D = cast<VarDecl>(C->getCapturedVar());
2298
2299 llvm::StringRef Pre;
2300 llvm::StringRef Post;
2301 if (D->getInitStyle() == VarDecl::CallInit &&
2302 !isa<ParenListExpr>(D->getInit())) {
2303 Pre = "(";
2304 Post = ")";
2305 } else if (D->getInitStyle() == VarDecl::CInit) {
2306 Pre = " = ";
2307 }
2308
2309 OS << Pre;
2310 PrintExpr(D->getInit());
2311 OS << Post;
2312 }
2313 }
2314 OS << ']';
2315
2316 if (!Node->getExplicitTemplateParameters().empty()) {
2317 Node->getTemplateParameterList()->print(
2318 OS, Node->getLambdaClass()->getASTContext(),
2319 /*OmitTemplateKW*/true);
2320 }
2321
2322 if (Node->hasExplicitParameters()) {
2323 OS << '(';
2324 CXXMethodDecl *Method = Node->getCallOperator();
2325 NeedComma = false;
2326 for (const auto *P : Method->parameters()) {
2327 if (NeedComma) {
2328 OS << ", ";
2329 } else {
2330 NeedComma = true;
2331 }
2332 std::string ParamStr =
2333 (Policy.CleanUglifiedParameters && P->getIdentifier())
2334 ? P->getIdentifier()->deuglifiedName().str()
2335 : P->getNameAsString();
2336 P->getOriginalType().print(OS, Policy, ParamStr);
2337 }
2338 if (Method->isVariadic()) {
2339 if (NeedComma)
2340 OS << ", ";
2341 OS << "...";
2342 }
2343 OS << ')';
2344
2345 if (Node->isMutable())
2346 OS << " mutable";
2347
2348 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2349 Proto->printExceptionSpecification(OS, Policy);
2350
2351 // FIXME: Attributes
2352
2353 // Print the trailing return type if it was specified in the source.
2354 if (Node->hasExplicitResultType()) {
2355 OS << " -> ";
2356 Proto->getReturnType().print(OS, Policy);
2357 }
2358 }
2359
2360 // Print the body.
2361 OS << ' ';
2362 if (Policy.TerseOutput)
2363 OS << "{}";
2364 else
2365 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2366}
2367
2368void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2369 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2370 TSInfo->getType().print(OS, Policy);
2371 else
2372 Node->getType().print(OS, Policy);
2373 OS << "()";
2374}
2375
2376void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2377 if (E->isGlobalNew())
2378 OS << "::";
2379 OS << "new ";
2380 unsigned NumPlace = E->getNumPlacementArgs();
2381 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2382 OS << "(";
2383 PrintExpr(E->getPlacementArg(0));
2384 for (unsigned i = 1; i < NumPlace; ++i) {
2385 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2386 break;
2387 OS << ", ";
2388 PrintExpr(E->getPlacementArg(i));
2389 }
2390 OS << ") ";
2391 }
2392 if (E->isParenTypeId())
2393 OS << "(";
2394 std::string TypeS;
2395 if (E->isArray()) {
2396 llvm::raw_string_ostream s(TypeS);
2397 s << '[';
2398 if (std::optional<Expr *> Size = E->getArraySize())
2399 (*Size)->printPretty(s, Helper, Policy);
2400 s << ']';
2401 }
2402 E->getAllocatedType().print(OS, Policy, TypeS);
2403 if (E->isParenTypeId())
2404 OS << ")";
2405
2406 CXXNewInitializationStyle InitStyle = E->getInitializationStyle();
2407 if (InitStyle != CXXNewInitializationStyle::None) {
2408 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2409 !isa<ParenListExpr>(E->getInitializer());
2410 if (Bare)
2411 OS << "(";
2412 PrintExpr(E->getInitializer());
2413 if (Bare)
2414 OS << ")";
2415 }
2416}
2417
2418void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2419 if (E->isGlobalDelete())
2420 OS << "::";
2421 OS << "delete ";
2422 if (E->isArrayForm())
2423 OS << "[] ";
2424 PrintExpr(E->getArgument());
2425}
2426
2427void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2428 PrintExpr(E->getBase());
2429 if (E->isArrow())
2430 OS << "->";
2431 else
2432 OS << '.';
2433 if (E->getQualifier())
2434 E->getQualifier()->print(OS, Policy);
2435 OS << "~";
2436
2437 if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2438 OS << II->getName();
2439 else
2440 E->getDestroyedType().print(OS, Policy);
2441}
2442
2443void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2444 if (E->isListInitialization() && !E->isStdInitListInitialization())
2445 OS << "{";
2446
2447 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2448 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2449 // Don't print any defaulted arguments
2450 break;
2451 }
2452
2453 if (i) OS << ", ";
2454 PrintExpr(E->getArg(i));
2455 }
2456
2457 if (E->isListInitialization() && !E->isStdInitListInitialization())
2458 OS << "}";
2459}
2460
2461void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2462 // Parens are printed by the surrounding context.
2463 OS << "<forwarded>";
2464}
2465
2466void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2467 PrintExpr(E->getSubExpr());
2468}
2469
2470void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2471 // Just forward to the subexpression.
2472 PrintExpr(E->getSubExpr());
2473}
2474
2475void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2477 Node->getTypeAsWritten().print(OS, Policy);
2478 if (!Node->isListInitialization())
2479 OS << '(';
2480 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2481 ++Arg) {
2482 if (Arg != Node->arg_begin())
2483 OS << ", ";
2484 PrintExpr(*Arg);
2485 }
2486 if (!Node->isListInitialization())
2487 OS << ')';
2488}
2489
2490void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2492 if (!Node->isImplicitAccess()) {
2493 PrintExpr(Node->getBase());
2494 OS << (Node->isArrow() ? "->" : ".");
2495 }
2496 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2497 Qualifier->print(OS, Policy);
2498 if (Node->hasTemplateKeyword())
2499 OS << "template ";
2500 OS << Node->getMemberNameInfo();
2501 if (Node->hasExplicitTemplateArgs())
2502 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2503}
2504
2505void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2506 if (!Node->isImplicitAccess()) {
2507 PrintExpr(Node->getBase());
2508 OS << (Node->isArrow() ? "->" : ".");
2509 }
2510 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2511 Qualifier->print(OS, Policy);
2512 if (Node->hasTemplateKeyword())
2513 OS << "template ";
2514 OS << Node->getMemberNameInfo();
2515 if (Node->hasExplicitTemplateArgs())
2516 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2517}
2518
2519void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2520 OS << getTraitSpelling(E->getTrait()) << "(";
2521 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2522 if (I > 0)
2523 OS << ", ";
2524 E->getArg(I)->getType().print(OS, Policy);
2525 }
2526 OS << ")";
2527}
2528
2529void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2530 OS << getTraitSpelling(E->getTrait()) << '(';
2531 E->getQueriedType().print(OS, Policy);
2532 OS << ')';
2533}
2534
2535void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2536 OS << getTraitSpelling(E->getTrait()) << '(';
2537 PrintExpr(E->getQueriedExpression());
2538 OS << ')';
2539}
2540
2541void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2542 OS << "noexcept(";
2543 PrintExpr(E->getOperand());
2544 OS << ")";
2545}
2546
2547void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2548 PrintExpr(E->getPattern());
2549 OS << "...";
2550}
2551
2552void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2553 OS << "sizeof...(" << *E->getPack() << ")";
2554}
2555
2556void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2557 PrintExpr(E->getPackIdExpression());
2558 OS << "...[";
2559 PrintExpr(E->getIndexExpr());
2560 OS << "]";
2561}
2562
2563void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2565 OS << *Node->getParameterPack();
2566}
2567
2568void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2570 Visit(Node->getReplacement());
2571}
2572
2573void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2574 OS << *E->getParameterPack();
2575}
2576
2577void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2578 PrintExpr(Node->getSubExpr());
2579}
2580
2581void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2582 OS << "(";
2583 if (E->getLHS()) {
2584 PrintExpr(E->getLHS());
2585 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2586 }
2587 OS << "...";
2588 if (E->getRHS()) {
2589 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2590 PrintExpr(E->getRHS());
2591 }
2592 OS << ")";
2593}
2594
2595void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2596 OS << "(";
2597 llvm::interleaveComma(Node->getInitExprs(), OS,
2598 [&](Expr *E) { PrintExpr(E); });
2599 OS << ")";
2600}
2601
2602void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2603 NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2604 if (NNS)
2605 NNS.getNestedNameSpecifier()->print(OS, Policy);
2606 if (E->getTemplateKWLoc().isValid())
2607 OS << "template ";
2608 OS << E->getFoundDecl()->getName();
2609 printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2610 Policy,
2611 E->getNamedConcept()->getTemplateParameters());
2612}
2613
2614void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2615 OS << "requires ";
2616 auto LocalParameters = E->getLocalParameters();
2617 if (!LocalParameters.empty()) {
2618 OS << "(";
2619 for (ParmVarDecl *LocalParam : LocalParameters) {
2620 PrintRawDecl(LocalParam);
2621 if (LocalParam != LocalParameters.back())
2622 OS << ", ";
2623 }
2624
2625 OS << ") ";
2626 }
2627 OS << "{ ";
2628 auto Requirements = E->getRequirements();
2629 for (concepts::Requirement *Req : Requirements) {
2630 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2631 if (TypeReq->isSubstitutionFailure())
2632 OS << "<<error-type>>";
2633 else
2634 TypeReq->getType()->getType().print(OS, Policy);
2635 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2636 if (ExprReq->isCompound())
2637 OS << "{ ";
2638 if (ExprReq->isExprSubstitutionFailure())
2639 OS << "<<error-expression>>";
2640 else
2641 PrintExpr(ExprReq->getExpr());
2642 if (ExprReq->isCompound()) {
2643 OS << " }";
2644 if (ExprReq->getNoexceptLoc().isValid())
2645 OS << " noexcept";
2646 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2647 if (!RetReq.isEmpty()) {
2648 OS << " -> ";
2649 if (RetReq.isSubstitutionFailure())
2650 OS << "<<error-type>>";
2651 else if (RetReq.isTypeConstraint())
2652 RetReq.getTypeConstraint()->print(OS, Policy);
2653 }
2654 }
2655 } else {
2656 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2657 OS << "requires ";
2658 if (NestedReq->hasInvalidConstraint())
2659 OS << "<<error-expression>>";
2660 else
2661 PrintExpr(NestedReq->getConstraintExpr());
2662 }
2663 OS << "; ";
2664 }
2665 OS << "}";
2666}
2667
2668// C++ Coroutines
2669
2670void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2671 Visit(S->getBody());
2672}
2673
2674void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2675 OS << "co_return";
2676 if (S->getOperand()) {
2677 OS << " ";
2678 Visit(S->getOperand());
2679 }
2680 OS << ";";
2681}
2682
2683void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2684 OS << "co_await ";
2685 PrintExpr(S->getOperand());
2686}
2687
2688void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2689 OS << "co_await ";
2690 PrintExpr(S->getOperand());
2691}
2692
2693void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2694 OS << "co_yield ";
2695 PrintExpr(S->getOperand());
2696}
2697
2698// Obj-C
2699
2700void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2701 OS << "@";
2702 VisitStringLiteral(Node->getString());
2703}
2704
2705void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2706 OS << "@";
2707 Visit(E->getSubExpr());
2708}
2709
2710void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2711 OS << "@[ ";
2713 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2714 if (I != Ch.begin())
2715 OS << ", ";
2716 Visit(*I);
2717 }
2718 OS << " ]";
2719}
2720
2721void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2722 OS << "@{ ";
2723 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2724 if (I > 0)
2725 OS << ", ";
2726
2727 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2728 Visit(Element.Key);
2729 OS << " : ";
2730 Visit(Element.Value);
2731 if (Element.isPackExpansion())
2732 OS << "...";
2733 }
2734 OS << " }";
2735}
2736
2737void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2738 OS << "@encode(";
2739 Node->getEncodedType().print(OS, Policy);
2740 OS << ')';
2741}
2742
2743void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2744 OS << "@selector(";
2745 Node->getSelector().print(OS);
2746 OS << ')';
2747}
2748
2749void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2750 OS << "@protocol(" << *Node->getProtocol() << ')';
2751}
2752
2753void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2754 OS << "[";
2755 switch (Mess->getReceiverKind()) {
2757 PrintExpr(Mess->getInstanceReceiver());
2758 break;
2759
2761 Mess->getClassReceiver().print(OS, Policy);
2762 break;
2763
2766 OS << "Super";
2767 break;
2768 }
2769
2770 OS << ' ';
2771 Selector selector = Mess->getSelector();
2772 if (selector.isUnarySelector()) {
2773 OS << selector.getNameForSlot(0);
2774 } else {
2775 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2776 if (i < selector.getNumArgs()) {
2777 if (i > 0) OS << ' ';
2778 if (selector.getIdentifierInfoForSlot(i))
2779 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2780 else
2781 OS << ":";
2782 }
2783 else OS << ", "; // Handle variadic methods.
2784
2785 PrintExpr(Mess->getArg(i));
2786 }
2787 }
2788 OS << "]";
2789}
2790
2791void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2792 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2793}
2794
2795void
2796StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2797 PrintExpr(E->getSubExpr());
2798}
2799
2800void
2801StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2802 OS << '(' << E->getBridgeKindName();
2803 E->getType().print(OS, Policy);
2804 OS << ')';
2805 PrintExpr(E->getSubExpr());
2806}
2807
2808void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2809 BlockDecl *BD = Node->getBlockDecl();
2810 OS << "^";
2811
2812 const FunctionType *AFT = Node->getFunctionType();
2813
2814 if (isa<FunctionNoProtoType>(AFT)) {
2815 OS << "()";
2816 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2817 OS << '(';
2818 for (BlockDecl::param_iterator AI = BD->param_begin(),
2819 E = BD->param_end(); AI != E; ++AI) {
2820 if (AI != BD->param_begin()) OS << ", ";
2821 std::string ParamStr = (*AI)->getNameAsString();
2822 (*AI)->getType().print(OS, Policy, ParamStr);
2823 }
2824
2825 const auto *FT = cast<FunctionProtoType>(AFT);
2826 if (FT->isVariadic()) {
2827 if (!BD->param_empty()) OS << ", ";
2828 OS << "...";
2829 }
2830 OS << ')';
2831 }
2832 OS << "{ }";
2833}
2834
2835void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2836 PrintExpr(Node->getSourceExpr());
2837}
2838
2839void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2840 // TODO: Print something reasonable for a TypoExpr, if necessary.
2841 llvm_unreachable("Cannot print TypoExpr nodes");
2842}
2843
2844void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2845 OS << "<recovery-expr>(";
2846 const char *Sep = "";
2847 for (Expr *E : Node->subExpressions()) {
2848 OS << Sep;
2849 PrintExpr(E);
2850 Sep = ", ";
2851 }
2852 OS << ')';
2853}
2854
2855void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2856 OS << "__builtin_astype(";
2857 PrintExpr(Node->getSrcExpr());
2858 OS << ", ";
2859 Node->getType().print(OS, Policy);
2860 OS << ")";
2861}
2862
2863void StmtPrinter::VisitHLSLOutArgExpr(HLSLOutArgExpr *Node) {
2864 PrintExpr(Node->getArgLValue());
2865}
2866
2867//===----------------------------------------------------------------------===//
2868// Stmt method implementations
2869//===----------------------------------------------------------------------===//
2870
2871void Stmt::dumpPretty(const ASTContext &Context) const {
2872 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2873}
2874
2875void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2876 const PrintingPolicy &Policy, unsigned Indentation,
2877 StringRef NL, const ASTContext *Context) const {
2878 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2879 P.Visit(const_cast<Stmt *>(this));
2880}
2881
2882void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2883 const PrintingPolicy &Policy,
2884 unsigned Indentation, StringRef NL,
2885 const ASTContext *Context) const {
2886 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2887 P.PrintControlledStmt(const_cast<Stmt *>(this));
2888}
2889
2890void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2891 const PrintingPolicy &Policy, bool AddQuotes) const {
2892 std::string Buf;
2893 llvm::raw_string_ostream TempOut(Buf);
2894
2895 printPretty(TempOut, Helper, Policy);
2896
2897 Out << JsonFormat(TempOut.str(), AddQuotes);
2898}
2899
2900//===----------------------------------------------------------------------===//
2901// PrinterHelper
2902//===----------------------------------------------------------------------===//
2903
2904// 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:4474
param_iterator param_end()
Definition: Decl.h:4573
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition: Decl.h:4568
param_iterator param_begin()
Definition: Decl.h:4572
bool param_empty() const
Definition: Decl.h:4571
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:1018
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:5102
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:1700
@ 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:1209
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:7902
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:8800
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:1401
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