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