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