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 for (const auto *Attr : Node->getAttrs()) {
296 Attr->printPretty(OS, Policy);
297 }
298
299 PrintStmt(Node->getSubStmt(), 0);
300}
301
302void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
303 if (If->isConsteval()) {
304 OS << "if ";
305 if (If->isNegatedConsteval())
306 OS << "!";
307 OS << "consteval";
308 OS << NL;
309 PrintStmt(If->getThen());
310 if (Stmt *Else = If->getElse()) {
311 Indent();
312 OS << "else";
313 PrintStmt(Else);
314 OS << NL;
315 }
316 return;
317 }
318
319 OS << "if (";
320 if (If->getInit())
321 PrintInitStmt(If->getInit(), 4);
322 if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
323 PrintRawDeclStmt(DS);
324 else
325 PrintExpr(If->getCond());
326 OS << ')';
327
328 if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
329 OS << ' ';
330 PrintRawCompoundStmt(CS);
331 OS << (If->getElse() ? " " : NL);
332 } else {
333 OS << NL;
334 PrintStmt(If->getThen());
335 if (If->getElse()) Indent();
336 }
337
338 if (Stmt *Else = If->getElse()) {
339 OS << "else";
340
341 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
342 OS << ' ';
343 PrintRawCompoundStmt(CS);
344 OS << NL;
345 } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
346 OS << ' ';
347 PrintRawIfStmt(ElseIf);
348 } else {
349 OS << NL;
350 PrintStmt(If->getElse());
351 }
352 }
353}
354
355void StmtPrinter::VisitIfStmt(IfStmt *If) {
356 Indent();
357 PrintRawIfStmt(If);
358}
359
360void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
361 Indent() << "switch (";
362 if (Node->getInit())
363 PrintInitStmt(Node->getInit(), 8);
364 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
365 PrintRawDeclStmt(DS);
366 else
367 PrintExpr(Node->getCond());
368 OS << ")";
369 PrintControlledStmt(Node->getBody());
370}
371
372void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
373 Indent() << "while (";
374 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
375 PrintRawDeclStmt(DS);
376 else
377 PrintExpr(Node->getCond());
378 OS << ")" << NL;
379 PrintStmt(Node->getBody());
380}
381
382void StmtPrinter::VisitDoStmt(DoStmt *Node) {
383 Indent() << "do ";
384 if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
385 PrintRawCompoundStmt(CS);
386 OS << " ";
387 } else {
388 OS << NL;
389 PrintStmt(Node->getBody());
390 Indent();
391 }
392
393 OS << "while (";
394 PrintExpr(Node->getCond());
395 OS << ");" << NL;
396}
397
398void StmtPrinter::VisitForStmt(ForStmt *Node) {
399 Indent() << "for (";
400 if (Node->getInit())
401 PrintInitStmt(Node->getInit(), 5);
402 else
403 OS << (Node->getCond() ? "; " : ";");
404 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
405 PrintRawDeclStmt(DS);
406 else if (Node->getCond())
407 PrintExpr(Node->getCond());
408 OS << ";";
409 if (Node->getInc()) {
410 OS << " ";
411 PrintExpr(Node->getInc());
412 }
413 OS << ")";
414 PrintControlledStmt(Node->getBody());
415}
416
417void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
418 Indent() << "for (";
419 if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
420 PrintRawDeclStmt(DS);
421 else
422 PrintExpr(cast<Expr>(Node->getElement()));
423 OS << " in ";
424 PrintExpr(Node->getCollection());
425 OS << ")";
426 PrintControlledStmt(Node->getBody());
427}
428
429void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
430 Indent() << "for (";
431 if (Node->getInit())
432 PrintInitStmt(Node->getInit(), 5);
433 PrintingPolicy SubPolicy(Policy);
434 SubPolicy.SuppressInitializers = true;
435 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
436 OS << " : ";
437 PrintExpr(Node->getRangeInit());
438 OS << ")";
439 PrintControlledStmt(Node->getBody());
440}
441
442void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
443 Indent();
444 if (Node->isIfExists())
445 OS << "__if_exists (";
446 else
447 OS << "__if_not_exists (";
448
449 if (NestedNameSpecifier *Qualifier
450 = Node->getQualifierLoc().getNestedNameSpecifier())
451 Qualifier->print(OS, Policy);
452
453 OS << Node->getNameInfo() << ") ";
454
455 PrintRawCompoundStmt(Node->getSubStmt());
456}
457
458void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
459 Indent() << "goto " << Node->getLabel()->getName() << ";";
460 if (Policy.IncludeNewlines) OS << NL;
461}
462
463void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
464 Indent() << "goto *";
465 PrintExpr(Node->getTarget());
466 OS << ";";
467 if (Policy.IncludeNewlines) OS << NL;
468}
469
470void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
471 Indent() << "continue;";
472 if (Policy.IncludeNewlines) OS << NL;
473}
474
475void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
476 Indent() << "break;";
477 if (Policy.IncludeNewlines) OS << NL;
478}
479
480void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
481 Indent() << "return";
482 if (Node->getRetValue()) {
483 OS << " ";
484 PrintExpr(Node->getRetValue());
485 }
486 OS << ";";
487 if (Policy.IncludeNewlines) OS << NL;
488}
489
490void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
491 Indent() << "asm ";
492
493 if (Node->isVolatile())
494 OS << "volatile ";
495
496 if (Node->isAsmGoto())
497 OS << "goto ";
498
499 OS << "(";
500 VisitStringLiteral(Node->getAsmString());
501
502 // Outputs
503 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
504 Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)
505 OS << " : ";
506
507 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
508 if (i != 0)
509 OS << ", ";
510
511 if (!Node->getOutputName(i).empty()) {
512 OS << '[';
513 OS << Node->getOutputName(i);
514 OS << "] ";
515 }
516
517 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
518 OS << " (";
519 Visit(Node->getOutputExpr(i));
520 OS << ")";
521 }
522
523 // Inputs
524 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||
525 Node->getNumLabels() != 0)
526 OS << " : ";
527
528 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
529 if (i != 0)
530 OS << ", ";
531
532 if (!Node->getInputName(i).empty()) {
533 OS << '[';
534 OS << Node->getInputName(i);
535 OS << "] ";
536 }
537
538 VisitStringLiteral(Node->getInputConstraintLiteral(i));
539 OS << " (";
540 Visit(Node->getInputExpr(i));
541 OS << ")";
542 }
543
544 // Clobbers
545 if (Node->getNumClobbers() != 0 || Node->getNumLabels())
546 OS << " : ";
547
548 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
549 if (i != 0)
550 OS << ", ";
551
552 VisitStringLiteral(Node->getClobberStringLiteral(i));
553 }
554
555 // Labels
556 if (Node->getNumLabels() != 0)
557 OS << " : ";
558
559 for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {
560 if (i != 0)
561 OS << ", ";
562 OS << Node->getLabelName(i);
563 }
564
565 OS << ");";
566 if (Policy.IncludeNewlines) OS << NL;
567}
568
569void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
570 // FIXME: Implement MS style inline asm statement printer.
571 Indent() << "__asm ";
572 if (Node->hasBraces())
573 OS << "{" << NL;
574 OS << Node->getAsmString() << NL;
575 if (Node->hasBraces())
576 Indent() << "}" << NL;
577}
578
579void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
580 PrintStmt(Node->getCapturedDecl()->getBody());
581}
582
583void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
584 Indent() << "@try";
585 if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
586 PrintRawCompoundStmt(TS);
587 OS << NL;
588 }
589
590 for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) {
591 Indent() << "@catch(";
592 if (Decl *DS = catchStmt->getCatchParamDecl())
593 PrintRawDecl(DS);
594 OS << ")";
595 if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
596 PrintRawCompoundStmt(CS);
597 OS << NL;
598 }
599 }
600
601 if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
602 Indent() << "@finally";
603 if (auto *CS = dyn_cast<CompoundStmt>(FS->getFinallyBody())) {
604 PrintRawCompoundStmt(CS);
605 OS << NL;
606 }
607 }
608}
609
610void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
611}
612
613void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
614 Indent() << "@catch (...) { /* todo */ } " << NL;
615}
616
617void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
618 Indent() << "@throw";
619 if (Node->getThrowExpr()) {
620 OS << " ";
621 PrintExpr(Node->getThrowExpr());
622 }
623 OS << ";" << NL;
624}
625
626void StmtPrinter::VisitObjCAvailabilityCheckExpr(
628 OS << "@available(...)";
629}
630
631void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
632 Indent() << "@synchronized (";
633 PrintExpr(Node->getSynchExpr());
634 OS << ")";
635 PrintRawCompoundStmt(Node->getSynchBody());
636 OS << NL;
637}
638
639void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
640 Indent() << "@autoreleasepool";
641 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getSubStmt()));
642 OS << NL;
643}
644
645void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
646 OS << "catch (";
647 if (Decl *ExDecl = Node->getExceptionDecl())
648 PrintRawDecl(ExDecl);
649 else
650 OS << "...";
651 OS << ") ";
652 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
653}
654
655void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
656 Indent();
657 PrintRawCXXCatchStmt(Node);
658 OS << NL;
659}
660
661void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
662 Indent() << "try ";
663 PrintRawCompoundStmt(Node->getTryBlock());
664 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
665 OS << " ";
666 PrintRawCXXCatchStmt(Node->getHandler(i));
667 }
668 OS << NL;
669}
670
671void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
672 Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
673 PrintRawCompoundStmt(Node->getTryBlock());
674 SEHExceptStmt *E = Node->getExceptHandler();
675 SEHFinallyStmt *F = Node->getFinallyHandler();
676 if(E)
677 PrintRawSEHExceptHandler(E);
678 else {
679 assert(F && "Must have a finally block...");
680 PrintRawSEHFinallyStmt(F);
681 }
682 OS << NL;
683}
684
685void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
686 OS << "__finally ";
687 PrintRawCompoundStmt(Node->getBlock());
688 OS << NL;
689}
690
691void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
692 OS << "__except (";
693 VisitExpr(Node->getFilterExpr());
694 OS << ")" << NL;
695 PrintRawCompoundStmt(Node->getBlock());
696 OS << NL;
697}
698
699void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
700 Indent();
701 PrintRawSEHExceptHandler(Node);
702 OS << NL;
703}
704
705void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
706 Indent();
707 PrintRawSEHFinallyStmt(Node);
708 OS << NL;
709}
710
711void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
712 Indent() << "__leave;";
713 if (Policy.IncludeNewlines) OS << NL;
714}
715
716//===----------------------------------------------------------------------===//
717// OpenMP directives printing methods
718//===----------------------------------------------------------------------===//
719
720void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) {
721 PrintStmt(Node->getLoopStmt());
722}
723
724void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
725 bool ForceNoStmt) {
726 OMPClausePrinter Printer(OS, Policy);
727 ArrayRef<OMPClause *> Clauses = S->clauses();
728 for (auto *Clause : Clauses)
729 if (Clause && !Clause->isImplicit()) {
730 OS << ' ';
731 Printer.Visit(Clause);
732 }
733 OS << NL;
734 if (!ForceNoStmt && S->hasAssociatedStmt())
735 PrintStmt(S->getRawStmt());
736}
737
738void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) {
739 Indent() << "#pragma omp metadirective";
740 PrintOMPExecutableDirective(Node);
741}
742
743void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
744 Indent() << "#pragma omp parallel";
745 PrintOMPExecutableDirective(Node);
746}
747
748void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
749 Indent() << "#pragma omp simd";
750 PrintOMPExecutableDirective(Node);
751}
752
753void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {
754 Indent() << "#pragma omp tile";
755 PrintOMPExecutableDirective(Node);
756}
757
758void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {
759 Indent() << "#pragma omp unroll";
760 PrintOMPExecutableDirective(Node);
761}
762
763void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
764 Indent() << "#pragma omp for";
765 PrintOMPExecutableDirective(Node);
766}
767
768void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
769 Indent() << "#pragma omp for simd";
770 PrintOMPExecutableDirective(Node);
771}
772
773void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
774 Indent() << "#pragma omp sections";
775 PrintOMPExecutableDirective(Node);
776}
777
778void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
779 Indent() << "#pragma omp section";
780 PrintOMPExecutableDirective(Node);
781}
782
783void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {
784 Indent() << "#pragma omp scope";
785 PrintOMPExecutableDirective(Node);
786}
787
788void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
789 Indent() << "#pragma omp single";
790 PrintOMPExecutableDirective(Node);
791}
792
793void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
794 Indent() << "#pragma omp master";
795 PrintOMPExecutableDirective(Node);
796}
797
798void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
799 Indent() << "#pragma omp critical";
800 if (Node->getDirectiveName().getName()) {
801 OS << " (";
802 Node->getDirectiveName().printName(OS, Policy);
803 OS << ")";
804 }
805 PrintOMPExecutableDirective(Node);
806}
807
808void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
809 Indent() << "#pragma omp parallel for";
810 PrintOMPExecutableDirective(Node);
811}
812
813void StmtPrinter::VisitOMPParallelForSimdDirective(
815 Indent() << "#pragma omp parallel for simd";
816 PrintOMPExecutableDirective(Node);
817}
818
819void StmtPrinter::VisitOMPParallelMasterDirective(
821 Indent() << "#pragma omp parallel master";
822 PrintOMPExecutableDirective(Node);
823}
824
825void StmtPrinter::VisitOMPParallelMaskedDirective(
827 Indent() << "#pragma omp parallel masked";
828 PrintOMPExecutableDirective(Node);
829}
830
831void StmtPrinter::VisitOMPParallelSectionsDirective(
833 Indent() << "#pragma omp parallel sections";
834 PrintOMPExecutableDirective(Node);
835}
836
837void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
838 Indent() << "#pragma omp task";
839 PrintOMPExecutableDirective(Node);
840}
841
842void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
843 Indent() << "#pragma omp taskyield";
844 PrintOMPExecutableDirective(Node);
845}
846
847void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
848 Indent() << "#pragma omp barrier";
849 PrintOMPExecutableDirective(Node);
850}
851
852void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
853 Indent() << "#pragma omp taskwait";
854 PrintOMPExecutableDirective(Node);
855}
856
857void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
858 Indent() << "#pragma omp error";
859 PrintOMPExecutableDirective(Node);
860}
861
862void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
863 Indent() << "#pragma omp taskgroup";
864 PrintOMPExecutableDirective(Node);
865}
866
867void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
868 Indent() << "#pragma omp flush";
869 PrintOMPExecutableDirective(Node);
870}
871
872void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
873 Indent() << "#pragma omp depobj";
874 PrintOMPExecutableDirective(Node);
875}
876
877void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
878 Indent() << "#pragma omp scan";
879 PrintOMPExecutableDirective(Node);
880}
881
882void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
883 Indent() << "#pragma omp ordered";
884 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
885}
886
887void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
888 Indent() << "#pragma omp atomic";
889 PrintOMPExecutableDirective(Node);
890}
891
892void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
893 Indent() << "#pragma omp target";
894 PrintOMPExecutableDirective(Node);
895}
896
897void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
898 Indent() << "#pragma omp target data";
899 PrintOMPExecutableDirective(Node);
900}
901
902void StmtPrinter::VisitOMPTargetEnterDataDirective(
904 Indent() << "#pragma omp target enter data";
905 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
906}
907
908void StmtPrinter::VisitOMPTargetExitDataDirective(
910 Indent() << "#pragma omp target exit data";
911 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
912}
913
914void StmtPrinter::VisitOMPTargetParallelDirective(
916 Indent() << "#pragma omp target parallel";
917 PrintOMPExecutableDirective(Node);
918}
919
920void StmtPrinter::VisitOMPTargetParallelForDirective(
922 Indent() << "#pragma omp target parallel for";
923 PrintOMPExecutableDirective(Node);
924}
925
926void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
927 Indent() << "#pragma omp teams";
928 PrintOMPExecutableDirective(Node);
929}
930
931void StmtPrinter::VisitOMPCancellationPointDirective(
933 Indent() << "#pragma omp cancellation point "
934 << getOpenMPDirectiveName(Node->getCancelRegion());
935 PrintOMPExecutableDirective(Node);
936}
937
938void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
939 Indent() << "#pragma omp cancel "
940 << getOpenMPDirectiveName(Node->getCancelRegion());
941 PrintOMPExecutableDirective(Node);
942}
943
944void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
945 Indent() << "#pragma omp taskloop";
946 PrintOMPExecutableDirective(Node);
947}
948
949void StmtPrinter::VisitOMPTaskLoopSimdDirective(
951 Indent() << "#pragma omp taskloop simd";
952 PrintOMPExecutableDirective(Node);
953}
954
955void StmtPrinter::VisitOMPMasterTaskLoopDirective(
957 Indent() << "#pragma omp master taskloop";
958 PrintOMPExecutableDirective(Node);
959}
960
961void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
963 Indent() << "#pragma omp masked taskloop";
964 PrintOMPExecutableDirective(Node);
965}
966
967void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
969 Indent() << "#pragma omp master taskloop simd";
970 PrintOMPExecutableDirective(Node);
971}
972
973void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
975 Indent() << "#pragma omp masked taskloop simd";
976 PrintOMPExecutableDirective(Node);
977}
978
979void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
981 Indent() << "#pragma omp parallel master taskloop";
982 PrintOMPExecutableDirective(Node);
983}
984
985void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
987 Indent() << "#pragma omp parallel masked taskloop";
988 PrintOMPExecutableDirective(Node);
989}
990
991void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
993 Indent() << "#pragma omp parallel master taskloop simd";
994 PrintOMPExecutableDirective(Node);
995}
996
997void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
999 Indent() << "#pragma omp parallel masked taskloop simd";
1000 PrintOMPExecutableDirective(Node);
1001}
1002
1003void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1004 Indent() << "#pragma omp distribute";
1005 PrintOMPExecutableDirective(Node);
1006}
1007
1008void StmtPrinter::VisitOMPTargetUpdateDirective(
1010 Indent() << "#pragma omp target update";
1011 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1012}
1013
1014void StmtPrinter::VisitOMPDistributeParallelForDirective(
1016 Indent() << "#pragma omp distribute parallel for";
1017 PrintOMPExecutableDirective(Node);
1018}
1019
1020void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1022 Indent() << "#pragma omp distribute parallel for simd";
1023 PrintOMPExecutableDirective(Node);
1024}
1025
1026void StmtPrinter::VisitOMPDistributeSimdDirective(
1028 Indent() << "#pragma omp distribute simd";
1029 PrintOMPExecutableDirective(Node);
1030}
1031
1032void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1034 Indent() << "#pragma omp target parallel for simd";
1035 PrintOMPExecutableDirective(Node);
1036}
1037
1038void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1039 Indent() << "#pragma omp target simd";
1040 PrintOMPExecutableDirective(Node);
1041}
1042
1043void StmtPrinter::VisitOMPTeamsDistributeDirective(
1045 Indent() << "#pragma omp teams distribute";
1046 PrintOMPExecutableDirective(Node);
1047}
1048
1049void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1051 Indent() << "#pragma omp teams distribute simd";
1052 PrintOMPExecutableDirective(Node);
1053}
1054
1055void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1057 Indent() << "#pragma omp teams distribute parallel for simd";
1058 PrintOMPExecutableDirective(Node);
1059}
1060
1061void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1063 Indent() << "#pragma omp teams distribute parallel for";
1064 PrintOMPExecutableDirective(Node);
1065}
1066
1067void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1068 Indent() << "#pragma omp target teams";
1069 PrintOMPExecutableDirective(Node);
1070}
1071
1072void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1074 Indent() << "#pragma omp target teams distribute";
1075 PrintOMPExecutableDirective(Node);
1076}
1077
1078void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1080 Indent() << "#pragma omp target teams distribute parallel for";
1081 PrintOMPExecutableDirective(Node);
1082}
1083
1084void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1086 Indent() << "#pragma omp target teams distribute parallel for simd";
1087 PrintOMPExecutableDirective(Node);
1088}
1089
1090void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1092 Indent() << "#pragma omp target teams distribute simd";
1093 PrintOMPExecutableDirective(Node);
1094}
1095
1096void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1097 Indent() << "#pragma omp interop";
1098 PrintOMPExecutableDirective(Node);
1099}
1100
1101void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1102 Indent() << "#pragma omp dispatch";
1103 PrintOMPExecutableDirective(Node);
1104}
1105
1106void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1107 Indent() << "#pragma omp masked";
1108 PrintOMPExecutableDirective(Node);
1109}
1110
1111void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1112 Indent() << "#pragma omp loop";
1113 PrintOMPExecutableDirective(Node);
1114}
1115
1116void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
1118 Indent() << "#pragma omp teams loop";
1119 PrintOMPExecutableDirective(Node);
1120}
1121
1122void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
1124 Indent() << "#pragma omp target teams loop";
1125 PrintOMPExecutableDirective(Node);
1126}
1127
1128void StmtPrinter::VisitOMPParallelGenericLoopDirective(
1130 Indent() << "#pragma omp parallel loop";
1131 PrintOMPExecutableDirective(Node);
1132}
1133
1134void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
1136 Indent() << "#pragma omp target parallel loop";
1137 PrintOMPExecutableDirective(Node);
1138}
1139
1140//===----------------------------------------------------------------------===//
1141// OpenACC construct printing methods
1142//===----------------------------------------------------------------------===//
1143void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
1144 Indent() << "#pragma acc " << S->getDirectiveKind();
1145 // TODO OpenACC: Print Clauses.
1146 PrintStmt(S->getStructuredBlock());
1147}
1148
1149//===----------------------------------------------------------------------===//
1150// Expr printing methods.
1151//===----------------------------------------------------------------------===//
1152
1153void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
1154 OS << Node->getBuiltinStr() << "()";
1155}
1156
1157void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
1158 PrintExpr(Node->getSubExpr());
1159}
1160
1161void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1162 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
1163 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1164 return;
1165 }
1166 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) {
1167 TPOD->printAsExpr(OS, Policy);
1168 return;
1169 }
1170 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1171 Qualifier->print(OS, Policy);
1172 if (Node->hasTemplateKeyword())
1173 OS << "template ";
1174 if (Policy.CleanUglifiedParameters &&
1175 isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) &&
1176 Node->getDecl()->getIdentifier())
1177 OS << Node->getDecl()->getIdentifier()->deuglifiedName();
1178 else
1179 Node->getNameInfo().printName(OS, Policy);
1180 if (Node->hasExplicitTemplateArgs()) {
1181 const TemplateParameterList *TPL = nullptr;
1182 if (!Node->hadMultipleCandidates())
1183 if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
1184 TPL = TD->getTemplateParameters();
1185 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1186 }
1187}
1188
1189void StmtPrinter::VisitDependentScopeDeclRefExpr(
1191 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1192 Qualifier->print(OS, Policy);
1193 if (Node->hasTemplateKeyword())
1194 OS << "template ";
1195 OS << Node->getNameInfo();
1196 if (Node->hasExplicitTemplateArgs())
1197 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1198}
1199
1200void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1201 if (Node->getQualifier())
1202 Node->getQualifier()->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
1210static bool isImplicitSelf(const Expr *E) {
1211 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1212 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1213 if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
1214 DRE->getBeginLoc().isInvalid())
1215 return true;
1216 }
1217 }
1218 return false;
1219}
1220
1221void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1222 if (Node->getBase()) {
1223 if (!Policy.SuppressImplicitBase ||
1224 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1225 PrintExpr(Node->getBase());
1226 OS << (Node->isArrow() ? "->" : ".");
1227 }
1228 }
1229 OS << *Node->getDecl();
1230}
1231
1232void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1233 if (Node->isSuperReceiver())
1234 OS << "super.";
1235 else if (Node->isObjectReceiver() && Node->getBase()) {
1236 PrintExpr(Node->getBase());
1237 OS << ".";
1238 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1239 OS << Node->getClassReceiver()->getName() << ".";
1240 }
1241
1242 if (Node->isImplicitProperty()) {
1243 if (const auto *Getter = Node->getImplicitPropertyGetter())
1244 Getter->getSelector().print(OS);
1245 else
1247 Node->getImplicitPropertySetter()->getSelector());
1248 } else
1249 OS << Node->getExplicitProperty()->getName();
1250}
1251
1252void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1253 PrintExpr(Node->getBaseExpr());
1254 OS << "[";
1255 PrintExpr(Node->getKeyExpr());
1256 OS << "]";
1257}
1258
1259void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1261 OS << "__builtin_sycl_unique_stable_name(";
1262 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1263 OS << ")";
1264}
1265
1266void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1267 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1268}
1269
1270void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1271 CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
1272}
1273
1274/// Prints the given expression using the original source text. Returns true on
1275/// success, false otherwise.
1276static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1277 const ASTContext *Context) {
1278 if (!Context)
1279 return false;
1280 bool Invalid = false;
1281 StringRef Source = Lexer::getSourceText(
1283 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1284 if (!Invalid) {
1285 OS << Source;
1286 return true;
1287 }
1288 return false;
1289}
1290
1291void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1292 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1293 return;
1294 bool isSigned = Node->getType()->isSignedIntegerType();
1295 OS << toString(Node->getValue(), 10, isSigned);
1296
1297 if (isa<BitIntType>(Node->getType())) {
1298 OS << (isSigned ? "wb" : "uwb");
1299 return;
1300 }
1301
1302 // Emit suffixes. Integer literals are always a builtin integer type.
1303 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1304 default: llvm_unreachable("Unexpected type for integer literal!");
1305 case BuiltinType::Char_S:
1306 case BuiltinType::Char_U: OS << "i8"; break;
1307 case BuiltinType::UChar: OS << "Ui8"; break;
1308 case BuiltinType::SChar: OS << "i8"; break;
1309 case BuiltinType::Short: OS << "i16"; break;
1310 case BuiltinType::UShort: OS << "Ui16"; break;
1311 case BuiltinType::Int: break; // no suffix.
1312 case BuiltinType::UInt: OS << 'U'; break;
1313 case BuiltinType::Long: OS << 'L'; break;
1314 case BuiltinType::ULong: OS << "UL"; break;
1315 case BuiltinType::LongLong: OS << "LL"; break;
1316 case BuiltinType::ULongLong: OS << "ULL"; break;
1317 case BuiltinType::Int128:
1318 break; // no suffix.
1319 case BuiltinType::UInt128:
1320 break; // no suffix.
1321 case BuiltinType::WChar_S:
1322 case BuiltinType::WChar_U:
1323 break; // no suffix
1324 }
1325}
1326
1327void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1328 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1329 return;
1330 OS << Node->getValueAsString(/*Radix=*/10);
1331
1332 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1333 default: llvm_unreachable("Unexpected type for fixed point literal!");
1334 case BuiltinType::ShortFract: OS << "hr"; break;
1335 case BuiltinType::ShortAccum: OS << "hk"; break;
1336 case BuiltinType::UShortFract: OS << "uhr"; break;
1337 case BuiltinType::UShortAccum: OS << "uhk"; break;
1338 case BuiltinType::Fract: OS << "r"; break;
1339 case BuiltinType::Accum: OS << "k"; break;
1340 case BuiltinType::UFract: OS << "ur"; break;
1341 case BuiltinType::UAccum: OS << "uk"; break;
1342 case BuiltinType::LongFract: OS << "lr"; break;
1343 case BuiltinType::LongAccum: OS << "lk"; break;
1344 case BuiltinType::ULongFract: OS << "ulr"; break;
1345 case BuiltinType::ULongAccum: OS << "ulk"; break;
1346 }
1347}
1348
1349static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1350 bool PrintSuffix) {
1351 SmallString<16> Str;
1352 Node->getValue().toString(Str);
1353 OS << Str;
1354 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1355 OS << '.'; // Trailing dot in order to separate from ints.
1356
1357 if (!PrintSuffix)
1358 return;
1359
1360 // Emit suffixes. Float literals are always a builtin float type.
1361 switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1362 default: llvm_unreachable("Unexpected type for float literal!");
1363 case BuiltinType::Half: break; // FIXME: suffix?
1364 case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
1365 case BuiltinType::Double: break; // no suffix.
1366 case BuiltinType::Float16: OS << "F16"; break;
1367 case BuiltinType::Float: OS << 'F'; break;
1368 case BuiltinType::LongDouble: OS << 'L'; break;
1369 case BuiltinType::Float128: OS << 'Q'; break;
1370 }
1371}
1372
1373void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1374 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1375 return;
1376 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1377}
1378
1379void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1380 PrintExpr(Node->getSubExpr());
1381 OS << "i";
1382}
1383
1384void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1385 Str->outputString(OS);
1386}
1387
1388void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1389 OS << "(";
1390 PrintExpr(Node->getSubExpr());
1391 OS << ")";
1392}
1393
1394void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1395 if (!Node->isPostfix()) {
1396 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1397
1398 // Print a space if this is an "identifier operator" like __real, or if
1399 // it might be concatenated incorrectly like '+'.
1400 switch (Node->getOpcode()) {
1401 default: break;
1402 case UO_Real:
1403 case UO_Imag:
1404 case UO_Extension:
1405 OS << ' ';
1406 break;
1407 case UO_Plus:
1408 case UO_Minus:
1409 if (isa<UnaryOperator>(Node->getSubExpr()))
1410 OS << ' ';
1411 break;
1412 }
1413 }
1414 PrintExpr(Node->getSubExpr());
1415
1416 if (Node->isPostfix())
1417 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1418}
1419
1420void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1421 OS << "__builtin_offsetof(";
1422 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1423 OS << ", ";
1424 bool PrintedSomething = false;
1425 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1426 OffsetOfNode ON = Node->getComponent(i);
1427 if (ON.getKind() == OffsetOfNode::Array) {
1428 // Array node
1429 OS << "[";
1430 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1431 OS << "]";
1432 PrintedSomething = true;
1433 continue;
1434 }
1435
1436 // Skip implicit base indirections.
1437 if (ON.getKind() == OffsetOfNode::Base)
1438 continue;
1439
1440 // Field or identifier node.
1442 if (!Id)
1443 continue;
1444
1445 if (PrintedSomething)
1446 OS << ".";
1447 else
1448 PrintedSomething = true;
1449 OS << Id->getName();
1450 }
1451 OS << ")";
1452}
1453
1454void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1456 const char *Spelling = getTraitSpelling(Node->getKind());
1457 if (Node->getKind() == UETT_AlignOf) {
1458 if (Policy.Alignof)
1459 Spelling = "alignof";
1460 else if (Policy.UnderscoreAlignof)
1461 Spelling = "_Alignof";
1462 else
1463 Spelling = "__alignof";
1464 }
1465
1466 OS << Spelling;
1467
1468 if (Node->isArgumentType()) {
1469 OS << '(';
1470 Node->getArgumentType().print(OS, Policy);
1471 OS << ')';
1472 } else {
1473 OS << " ";
1474 PrintExpr(Node->getArgumentExpr());
1475 }
1476}
1477
1478void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1479 OS << "_Generic(";
1480 if (Node->isExprPredicate())
1481 PrintExpr(Node->getControllingExpr());
1482 else
1483 Node->getControllingType()->getType().print(OS, Policy);
1484
1485 for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
1486 OS << ", ";
1487 QualType T = Assoc.getType();
1488 if (T.isNull())
1489 OS << "default";
1490 else
1491 T.print(OS, Policy);
1492 OS << ": ";
1493 PrintExpr(Assoc.getAssociationExpr());
1494 }
1495 OS << ")";
1496}
1497
1498void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1499 PrintExpr(Node->getLHS());
1500 OS << "[";
1501 PrintExpr(Node->getRHS());
1502 OS << "]";
1503}
1504
1505void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1506 PrintExpr(Node->getBase());
1507 OS << "[";
1508 PrintExpr(Node->getRowIdx());
1509 OS << "]";
1510 OS << "[";
1511 PrintExpr(Node->getColumnIdx());
1512 OS << "]";
1513}
1514
1515void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
1516 PrintExpr(Node->getBase());
1517 OS << "[";
1518 if (Node->getLowerBound())
1519 PrintExpr(Node->getLowerBound());
1520 if (Node->getColonLocFirst().isValid()) {
1521 OS << ":";
1522 if (Node->getLength())
1523 PrintExpr(Node->getLength());
1524 }
1525 if (Node->getColonLocSecond().isValid()) {
1526 OS << ":";
1527 if (Node->getStride())
1528 PrintExpr(Node->getStride());
1529 }
1530 OS << "]";
1531}
1532
1533void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1534 OS << "(";
1535 for (Expr *E : Node->getDimensions()) {
1536 OS << "[";
1537 PrintExpr(E);
1538 OS << "]";
1539 }
1540 OS << ")";
1541 PrintExpr(Node->getBase());
1542}
1543
1544void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1545 OS << "iterator(";
1546 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1547 auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1548 VD->getType().print(OS, Policy);
1549 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1550 OS << " " << VD->getName() << " = ";
1551 PrintExpr(Range.Begin);
1552 OS << ":";
1553 PrintExpr(Range.End);
1554 if (Range.Step) {
1555 OS << ":";
1556 PrintExpr(Range.Step);
1557 }
1558 if (I < E - 1)
1559 OS << ", ";
1560 }
1561 OS << ")";
1562}
1563
1564void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1565 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1566 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1567 // Don't print any defaulted arguments
1568 break;
1569 }
1570
1571 if (i) OS << ", ";
1572 PrintExpr(Call->getArg(i));
1573 }
1574}
1575
1576void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1577 PrintExpr(Call->getCallee());
1578 OS << "(";
1579 PrintCallArgs(Call);
1580 OS << ")";
1581}
1582
1583static bool isImplicitThis(const Expr *E) {
1584 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1585 return TE->isImplicit();
1586 return false;
1587}
1588
1589void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1590 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1591 PrintExpr(Node->getBase());
1592
1593 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1594 FieldDecl *ParentDecl =
1595 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1596 : nullptr;
1597
1598 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1599 OS << (Node->isArrow() ? "->" : ".");
1600 }
1601
1602 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1603 if (FD->isAnonymousStructOrUnion())
1604 return;
1605
1606 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1607 Qualifier->print(OS, Policy);
1608 if (Node->hasTemplateKeyword())
1609 OS << "template ";
1610 OS << Node->getMemberNameInfo();
1611 const TemplateParameterList *TPL = nullptr;
1612 if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1613 if (!Node->hadMultipleCandidates())
1614 if (auto *FTD = FD->getPrimaryTemplate())
1615 TPL = FTD->getTemplateParameters();
1616 } else if (auto *VTSD =
1617 dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1618 TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
1619 if (Node->hasExplicitTemplateArgs())
1620 printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1621}
1622
1623void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1624 PrintExpr(Node->getBase());
1625 OS << (Node->isArrow() ? "->isa" : ".isa");
1626}
1627
1628void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1629 PrintExpr(Node->getBase());
1630 OS << ".";
1631 OS << Node->getAccessor().getName();
1632}
1633
1634void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1635 OS << '(';
1636 Node->getTypeAsWritten().print(OS, Policy);
1637 OS << ')';
1638 PrintExpr(Node->getSubExpr());
1639}
1640
1641void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1642 OS << '(';
1643 Node->getType().print(OS, Policy);
1644 OS << ')';
1645 PrintExpr(Node->getInitializer());
1646}
1647
1648void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1649 // No need to print anything, simply forward to the subexpression.
1650 PrintExpr(Node->getSubExpr());
1651}
1652
1653void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1654 PrintExpr(Node->getLHS());
1655 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1656 PrintExpr(Node->getRHS());
1657}
1658
1659void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1660 PrintExpr(Node->getLHS());
1661 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1662 PrintExpr(Node->getRHS());
1663}
1664
1665void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1666 PrintExpr(Node->getCond());
1667 OS << " ? ";
1668 PrintExpr(Node->getLHS());
1669 OS << " : ";
1670 PrintExpr(Node->getRHS());
1671}
1672
1673// GNU extensions.
1674
1675void
1676StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1677 PrintExpr(Node->getCommon());
1678 OS << " ?: ";
1679 PrintExpr(Node->getFalseExpr());
1680}
1681
1682void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1683 OS << "&&" << Node->getLabel()->getName();
1684}
1685
1686void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1687 OS << "(";
1688 PrintRawCompoundStmt(E->getSubStmt());
1689 OS << ")";
1690}
1691
1692void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1693 OS << "__builtin_choose_expr(";
1694 PrintExpr(Node->getCond());
1695 OS << ", ";
1696 PrintExpr(Node->getLHS());
1697 OS << ", ";
1698 PrintExpr(Node->getRHS());
1699 OS << ")";
1700}
1701
1702void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1703 OS << "__null";
1704}
1705
1706void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1707 OS << "__builtin_shufflevector(";
1708 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1709 if (i) OS << ", ";
1710 PrintExpr(Node->getExpr(i));
1711 }
1712 OS << ")";
1713}
1714
1715void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1716 OS << "__builtin_convertvector(";
1717 PrintExpr(Node->getSrcExpr());
1718 OS << ", ";
1719 Node->getType().print(OS, Policy);
1720 OS << ")";
1721}
1722
1723void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1724 if (Node->getSyntacticForm()) {
1725 Visit(Node->getSyntacticForm());
1726 return;
1727 }
1728
1729 OS << "{";
1730 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1731 if (i) OS << ", ";
1732 if (Node->getInit(i))
1733 PrintExpr(Node->getInit(i));
1734 else
1735 OS << "{}";
1736 }
1737 OS << "}";
1738}
1739
1740void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1741 // There's no way to express this expression in any of our supported
1742 // languages, so just emit something terse and (hopefully) clear.
1743 OS << "{";
1744 PrintExpr(Node->getSubExpr());
1745 OS << "}";
1746}
1747
1748void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1749 OS << "*";
1750}
1751
1752void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1753 OS << "(";
1754 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1755 if (i) OS << ", ";
1756 PrintExpr(Node->getExpr(i));
1757 }
1758 OS << ")";
1759}
1760
1761void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1762 bool NeedsEquals = true;
1763 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1764 if (D.isFieldDesignator()) {
1765 if (D.getDotLoc().isInvalid()) {
1766 if (const IdentifierInfo *II = D.getFieldName()) {
1767 OS << II->getName() << ":";
1768 NeedsEquals = false;
1769 }
1770 } else {
1771 OS << "." << D.getFieldName()->getName();
1772 }
1773 } else {
1774 OS << "[";
1775 if (D.isArrayDesignator()) {
1776 PrintExpr(Node->getArrayIndex(D));
1777 } else {
1778 PrintExpr(Node->getArrayRangeStart(D));
1779 OS << " ... ";
1780 PrintExpr(Node->getArrayRangeEnd(D));
1781 }
1782 OS << "]";
1783 }
1784 }
1785
1786 if (NeedsEquals)
1787 OS << " = ";
1788 else
1789 OS << " ";
1790 PrintExpr(Node->getInit());
1791}
1792
1793void StmtPrinter::VisitDesignatedInitUpdateExpr(
1795 OS << "{";
1796 OS << "/*base*/";
1797 PrintExpr(Node->getBase());
1798 OS << ", ";
1799
1800 OS << "/*updater*/";
1801 PrintExpr(Node->getUpdater());
1802 OS << "}";
1803}
1804
1805void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1806 OS << "/*no init*/";
1807}
1808
1809void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1810 if (Node->getType()->getAsCXXRecordDecl()) {
1811 OS << "/*implicit*/";
1812 Node->getType().print(OS, Policy);
1813 OS << "()";
1814 } else {
1815 OS << "/*implicit*/(";
1816 Node->getType().print(OS, Policy);
1817 OS << ')';
1818 if (Node->getType()->isRecordType())
1819 OS << "{}";
1820 else
1821 OS << 0;
1822 }
1823}
1824
1825void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1826 OS << "__builtin_va_arg(";
1827 PrintExpr(Node->getSubExpr());
1828 OS << ", ";
1829 Node->getType().print(OS, Policy);
1830 OS << ")";
1831}
1832
1833void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1834 PrintExpr(Node->getSyntacticForm());
1835}
1836
1837void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1838 const char *Name = nullptr;
1839 switch (Node->getOp()) {
1840#define BUILTIN(ID, TYPE, ATTRS)
1841#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1842 case AtomicExpr::AO ## ID: \
1843 Name = #ID "("; \
1844 break;
1845#include "clang/Basic/Builtins.inc"
1846 }
1847 OS << Name;
1848
1849 // AtomicExpr stores its subexpressions in a permuted order.
1850 PrintExpr(Node->getPtr());
1851 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1852 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1853 Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
1854 Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
1855 Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
1856 OS << ", ";
1857 PrintExpr(Node->getVal1());
1858 }
1859 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1860 Node->isCmpXChg()) {
1861 OS << ", ";
1862 PrintExpr(Node->getVal2());
1863 }
1864 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1865 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1866 OS << ", ";
1867 PrintExpr(Node->getWeak());
1868 }
1869 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1870 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1871 OS << ", ";
1872 PrintExpr(Node->getOrder());
1873 }
1874 if (Node->isCmpXChg()) {
1875 OS << ", ";
1876 PrintExpr(Node->getOrderFail());
1877 }
1878 OS << ")";
1879}
1880
1881// C++
1882void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1883 OverloadedOperatorKind Kind = Node->getOperator();
1884 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1885 if (Node->getNumArgs() == 1) {
1886 OS << getOperatorSpelling(Kind) << ' ';
1887 PrintExpr(Node->getArg(0));
1888 } else {
1889 PrintExpr(Node->getArg(0));
1890 OS << ' ' << getOperatorSpelling(Kind);
1891 }
1892 } else if (Kind == OO_Arrow) {
1893 PrintExpr(Node->getArg(0));
1894 } else if (Kind == OO_Call || Kind == OO_Subscript) {
1895 PrintExpr(Node->getArg(0));
1896 OS << (Kind == OO_Call ? '(' : '[');
1897 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1898 if (ArgIdx > 1)
1899 OS << ", ";
1900 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1901 PrintExpr(Node->getArg(ArgIdx));
1902 }
1903 OS << (Kind == OO_Call ? ')' : ']');
1904 } else if (Node->getNumArgs() == 1) {
1905 OS << getOperatorSpelling(Kind) << ' ';
1906 PrintExpr(Node->getArg(0));
1907 } else if (Node->getNumArgs() == 2) {
1908 PrintExpr(Node->getArg(0));
1909 OS << ' ' << getOperatorSpelling(Kind) << ' ';
1910 PrintExpr(Node->getArg(1));
1911 } else {
1912 llvm_unreachable("unknown overloaded operator");
1913 }
1914}
1915
1916void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1917 // If we have a conversion operator call only print the argument.
1918 CXXMethodDecl *MD = Node->getMethodDecl();
1919 if (MD && isa<CXXConversionDecl>(MD)) {
1920 PrintExpr(Node->getImplicitObjectArgument());
1921 return;
1922 }
1923 VisitCallExpr(cast<CallExpr>(Node));
1924}
1925
1926void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
1927 PrintExpr(Node->getCallee());
1928 OS << "<<<";
1929 PrintCallArgs(Node->getConfig());
1930 OS << ">>>(";
1931 PrintCallArgs(Node);
1932 OS << ")";
1933}
1934
1935void StmtPrinter::VisitCXXRewrittenBinaryOperator(
1938 Node->getDecomposedForm();
1939 PrintExpr(const_cast<Expr*>(Decomposed.LHS));
1940 OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
1941 PrintExpr(const_cast<Expr*>(Decomposed.RHS));
1942}
1943
1944void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1945 OS << Node->getCastName() << '<';
1946 Node->getTypeAsWritten().print(OS, Policy);
1947 OS << ">(";
1948 PrintExpr(Node->getSubExpr());
1949 OS << ")";
1950}
1951
1952void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1953 VisitCXXNamedCastExpr(Node);
1954}
1955
1956void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1957 VisitCXXNamedCastExpr(Node);
1958}
1959
1960void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
1961 VisitCXXNamedCastExpr(Node);
1962}
1963
1964void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
1965 VisitCXXNamedCastExpr(Node);
1966}
1967
1968void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
1969 OS << "__builtin_bit_cast(";
1970 Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
1971 OS << ", ";
1972 PrintExpr(Node->getSubExpr());
1973 OS << ")";
1974}
1975
1976void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
1977 VisitCXXNamedCastExpr(Node);
1978}
1979
1980void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
1981 OS << "typeid(";
1982 if (Node->isTypeOperand()) {
1983 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1984 } else {
1985 PrintExpr(Node->getExprOperand());
1986 }
1987 OS << ")";
1988}
1989
1990void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
1991 OS << "__uuidof(";
1992 if (Node->isTypeOperand()) {
1993 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1994 } else {
1995 PrintExpr(Node->getExprOperand());
1996 }
1997 OS << ")";
1998}
1999
2000void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2001 PrintExpr(Node->getBaseExpr());
2002 if (Node->isArrow())
2003 OS << "->";
2004 else
2005 OS << ".";
2006 if (NestedNameSpecifier *Qualifier =
2007 Node->getQualifierLoc().getNestedNameSpecifier())
2008 Qualifier->print(OS, Policy);
2009 OS << Node->getPropertyDecl()->getDeclName();
2010}
2011
2012void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2013 PrintExpr(Node->getBase());
2014 OS << "[";
2015 PrintExpr(Node->getIdx());
2016 OS << "]";
2017}
2018
2019void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2020 switch (Node->getLiteralOperatorKind()) {
2022 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2023 break;
2025 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2026 const TemplateArgumentList *Args =
2027 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2028 assert(Args);
2029
2030 if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2031 const TemplateParameterList *TPL = nullptr;
2032 if (!DRE->hadMultipleCandidates())
2033 if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2034 TPL = TD->getTemplateParameters();
2035 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2036 printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
2037 OS << "()";
2038 return;
2039 }
2040
2041 const TemplateArgument &Pack = Args->get(0);
2042 for (const auto &P : Pack.pack_elements()) {
2043 char C = (char)P.getAsIntegral().getZExtValue();
2044 OS << C;
2045 }
2046 break;
2047 }
2049 // Print integer literal without suffix.
2050 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2051 OS << toString(Int->getValue(), 10, /*isSigned*/false);
2052 break;
2053 }
2055 // Print floating literal without suffix.
2056 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
2057 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2058 break;
2059 }
2062 PrintExpr(Node->getCookedLiteral());
2063 break;
2064 }
2065 OS << Node->getUDSuffix()->getName();
2066}
2067
2068void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2069 OS << (Node->getValue() ? "true" : "false");
2070}
2071
2072void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2073 OS << "nullptr";
2074}
2075
2076void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2077 OS << "this";
2078}
2079
2080void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2081 if (!Node->getSubExpr())
2082 OS << "throw";
2083 else {
2084 OS << "throw ";
2085 PrintExpr(Node->getSubExpr());
2086 }
2087}
2088
2089void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2090 // Nothing to print: we picked up the default argument.
2091}
2092
2093void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2094 // Nothing to print: we picked up the default initializer.
2095}
2096
2097void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2098 auto TargetType = Node->getType();
2099 auto *Auto = TargetType->getContainedDeducedType();
2100 bool Bare = Auto && Auto->isDeduced();
2101
2102 // Parenthesize deduced casts.
2103 if (Bare)
2104 OS << '(';
2105 TargetType.print(OS, Policy);
2106 if (Bare)
2107 OS << ')';
2108
2109 // No extra braces surrounding the inner construct.
2110 if (!Node->isListInitialization())
2111 OS << '(';
2112 PrintExpr(Node->getSubExpr());
2113 if (!Node->isListInitialization())
2114 OS << ')';
2115}
2116
2117void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2118 PrintExpr(Node->getSubExpr());
2119}
2120
2121void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2122 Node->getType().print(OS, Policy);
2123 if (Node->isStdInitListInitialization())
2124 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2125 else if (Node->isListInitialization())
2126 OS << "{";
2127 else
2128 OS << "(";
2129 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2130 ArgEnd = Node->arg_end();
2131 Arg != ArgEnd; ++Arg) {
2132 if ((*Arg)->isDefaultArgument())
2133 break;
2134 if (Arg != Node->arg_begin())
2135 OS << ", ";
2136 PrintExpr(*Arg);
2137 }
2138 if (Node->isStdInitListInitialization())
2139 /* See above. */;
2140 else if (Node->isListInitialization())
2141 OS << "}";
2142 else
2143 OS << ")";
2144}
2145
2146void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2147 OS << '[';
2148 bool NeedComma = false;
2149 switch (Node->getCaptureDefault()) {
2150 case LCD_None:
2151 break;
2152
2153 case LCD_ByCopy:
2154 OS << '=';
2155 NeedComma = true;
2156 break;
2157
2158 case LCD_ByRef:
2159 OS << '&';
2160 NeedComma = true;
2161 break;
2162 }
2163 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
2164 CEnd = Node->explicit_capture_end();
2165 C != CEnd;
2166 ++C) {
2167 if (C->capturesVLAType())
2168 continue;
2169
2170 if (NeedComma)
2171 OS << ", ";
2172 NeedComma = true;
2173
2174 switch (C->getCaptureKind()) {
2175 case LCK_This:
2176 OS << "this";
2177 break;
2178
2179 case LCK_StarThis:
2180 OS << "*this";
2181 break;
2182
2183 case LCK_ByRef:
2184 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2185 OS << '&';
2186 OS << C->getCapturedVar()->getName();
2187 break;
2188
2189 case LCK_ByCopy:
2190 OS << C->getCapturedVar()->getName();
2191 break;
2192
2193 case LCK_VLAType:
2194 llvm_unreachable("VLA type in explicit captures.");
2195 }
2196
2197 if (C->isPackExpansion())
2198 OS << "...";
2199
2200 if (Node->isInitCapture(C)) {
2201 // Init captures are always VarDecl.
2202 auto *D = cast<VarDecl>(C->getCapturedVar());
2203
2204 llvm::StringRef Pre;
2205 llvm::StringRef Post;
2206 if (D->getInitStyle() == VarDecl::CallInit &&
2207 !isa<ParenListExpr>(D->getInit())) {
2208 Pre = "(";
2209 Post = ")";
2210 } else if (D->getInitStyle() == VarDecl::CInit) {
2211 Pre = " = ";
2212 }
2213
2214 OS << Pre;
2215 PrintExpr(D->getInit());
2216 OS << Post;
2217 }
2218 }
2219 OS << ']';
2220
2221 if (!Node->getExplicitTemplateParameters().empty()) {
2222 Node->getTemplateParameterList()->print(
2223 OS, Node->getLambdaClass()->getASTContext(),
2224 /*OmitTemplateKW*/true);
2225 }
2226
2227 if (Node->hasExplicitParameters()) {
2228 OS << '(';
2229 CXXMethodDecl *Method = Node->getCallOperator();
2230 NeedComma = false;
2231 for (const auto *P : Method->parameters()) {
2232 if (NeedComma) {
2233 OS << ", ";
2234 } else {
2235 NeedComma = true;
2236 }
2237 std::string ParamStr =
2238 (Policy.CleanUglifiedParameters && P->getIdentifier())
2239 ? P->getIdentifier()->deuglifiedName().str()
2240 : P->getNameAsString();
2241 P->getOriginalType().print(OS, Policy, ParamStr);
2242 }
2243 if (Method->isVariadic()) {
2244 if (NeedComma)
2245 OS << ", ";
2246 OS << "...";
2247 }
2248 OS << ')';
2249
2250 if (Node->isMutable())
2251 OS << " mutable";
2252
2253 auto *Proto = Method->getType()->castAs<FunctionProtoType>();
2254 Proto->printExceptionSpecification(OS, Policy);
2255
2256 // FIXME: Attributes
2257
2258 // Print the trailing return type if it was specified in the source.
2259 if (Node->hasExplicitResultType()) {
2260 OS << " -> ";
2261 Proto->getReturnType().print(OS, Policy);
2262 }
2263 }
2264
2265 // Print the body.
2266 OS << ' ';
2267 if (Policy.TerseOutput)
2268 OS << "{}";
2269 else
2270 PrintRawCompoundStmt(Node->getCompoundStmtBody());
2271}
2272
2273void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2274 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2275 TSInfo->getType().print(OS, Policy);
2276 else
2277 Node->getType().print(OS, Policy);
2278 OS << "()";
2279}
2280
2281void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2282 if (E->isGlobalNew())
2283 OS << "::";
2284 OS << "new ";
2285 unsigned NumPlace = E->getNumPlacementArgs();
2286 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2287 OS << "(";
2288 PrintExpr(E->getPlacementArg(0));
2289 for (unsigned i = 1; i < NumPlace; ++i) {
2290 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2291 break;
2292 OS << ", ";
2293 PrintExpr(E->getPlacementArg(i));
2294 }
2295 OS << ") ";
2296 }
2297 if (E->isParenTypeId())
2298 OS << "(";
2299 std::string TypeS;
2300 if (E->isArray()) {
2301 llvm::raw_string_ostream s(TypeS);
2302 s << '[';
2303 if (std::optional<Expr *> Size = E->getArraySize())
2304 (*Size)->printPretty(s, Helper, Policy);
2305 s << ']';
2306 }
2307 E->getAllocatedType().print(OS, Policy, TypeS);
2308 if (E->isParenTypeId())
2309 OS << ")";
2310
2312 if (InitStyle != CXXNewInitializationStyle::None) {
2313 bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
2314 !isa<ParenListExpr>(E->getInitializer());
2315 if (Bare)
2316 OS << "(";
2317 PrintExpr(E->getInitializer());
2318 if (Bare)
2319 OS << ")";
2320 }
2321}
2322
2323void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2324 if (E->isGlobalDelete())
2325 OS << "::";
2326 OS << "delete ";
2327 if (E->isArrayForm())
2328 OS << "[] ";
2329 PrintExpr(E->getArgument());
2330}
2331
2332void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2333 PrintExpr(E->getBase());
2334 if (E->isArrow())
2335 OS << "->";
2336 else
2337 OS << '.';
2338 if (E->getQualifier())
2339 E->getQualifier()->print(OS, Policy);
2340 OS << "~";
2341
2343 OS << II->getName();
2344 else
2345 E->getDestroyedType().print(OS, Policy);
2346}
2347
2348void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2350 OS << "{";
2351
2352 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2353 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2354 // Don't print any defaulted arguments
2355 break;
2356 }
2357
2358 if (i) OS << ", ";
2359 PrintExpr(E->getArg(i));
2360 }
2361
2363 OS << "}";
2364}
2365
2366void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2367 // Parens are printed by the surrounding context.
2368 OS << "<forwarded>";
2369}
2370
2371void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2372 PrintExpr(E->getSubExpr());
2373}
2374
2375void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2376 // Just forward to the subexpression.
2377 PrintExpr(E->getSubExpr());
2378}
2379
2380void StmtPrinter::VisitCXXUnresolvedConstructExpr(
2382 Node->getTypeAsWritten().print(OS, Policy);
2383 if (!Node->isListInitialization())
2384 OS << '(';
2385 for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
2386 ++Arg) {
2387 if (Arg != Node->arg_begin())
2388 OS << ", ";
2389 PrintExpr(*Arg);
2390 }
2391 if (!Node->isListInitialization())
2392 OS << ')';
2393}
2394
2395void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2397 if (!Node->isImplicitAccess()) {
2398 PrintExpr(Node->getBase());
2399 OS << (Node->isArrow() ? "->" : ".");
2400 }
2401 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2402 Qualifier->print(OS, Policy);
2403 if (Node->hasTemplateKeyword())
2404 OS << "template ";
2405 OS << Node->getMemberNameInfo();
2406 if (Node->hasExplicitTemplateArgs())
2407 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2408}
2409
2410void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2411 if (!Node->isImplicitAccess()) {
2412 PrintExpr(Node->getBase());
2413 OS << (Node->isArrow() ? "->" : ".");
2414 }
2415 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2416 Qualifier->print(OS, Policy);
2417 if (Node->hasTemplateKeyword())
2418 OS << "template ";
2419 OS << Node->getMemberNameInfo();
2420 if (Node->hasExplicitTemplateArgs())
2421 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2422}
2423
2424void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2425 OS << getTraitSpelling(E->getTrait()) << "(";
2426 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2427 if (I > 0)
2428 OS << ", ";
2429 E->getArg(I)->getType().print(OS, Policy);
2430 }
2431 OS << ")";
2432}
2433
2434void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2435 OS << getTraitSpelling(E->getTrait()) << '(';
2436 E->getQueriedType().print(OS, Policy);
2437 OS << ')';
2438}
2439
2440void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2441 OS << getTraitSpelling(E->getTrait()) << '(';
2442 PrintExpr(E->getQueriedExpression());
2443 OS << ')';
2444}
2445
2446void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2447 OS << "noexcept(";
2448 PrintExpr(E->getOperand());
2449 OS << ")";
2450}
2451
2452void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2453 PrintExpr(E->getPattern());
2454 OS << "...";
2455}
2456
2457void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2458 OS << "sizeof...(" << *E->getPack() << ")";
2459}
2460
2461void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2462 OS << E->getPackIdExpression() << "...[" << E->getIndexExpr() << "]";
2463}
2464
2465void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2467 OS << *Node->getParameterPack();
2468}
2469
2470void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2472 Visit(Node->getReplacement());
2473}
2474
2475void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2476 OS << *E->getParameterPack();
2477}
2478
2479void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2480 PrintExpr(Node->getSubExpr());
2481}
2482
2483void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2484 OS << "(";
2485 if (E->getLHS()) {
2486 PrintExpr(E->getLHS());
2487 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2488 }
2489 OS << "...";
2490 if (E->getRHS()) {
2491 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2492 PrintExpr(E->getRHS());
2493 }
2494 OS << ")";
2495}
2496
2497void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2498 OS << "(";
2499 llvm::interleaveComma(Node->getInitExprs(), OS,
2500 [&](Expr *E) { PrintExpr(E); });
2501 OS << ")";
2502}
2503
2504void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2506 if (NNS)
2507 NNS.getNestedNameSpecifier()->print(OS, Policy);
2508 if (E->getTemplateKWLoc().isValid())
2509 OS << "template ";
2510 OS << E->getFoundDecl()->getName();
2512 Policy,
2514}
2515
2516void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2517 OS << "requires ";
2518 auto LocalParameters = E->getLocalParameters();
2519 if (!LocalParameters.empty()) {
2520 OS << "(";
2521 for (ParmVarDecl *LocalParam : LocalParameters) {
2522 PrintRawDecl(LocalParam);
2523 if (LocalParam != LocalParameters.back())
2524 OS << ", ";
2525 }
2526
2527 OS << ") ";
2528 }
2529 OS << "{ ";
2530 auto Requirements = E->getRequirements();
2531 for (concepts::Requirement *Req : Requirements) {
2532 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2533 if (TypeReq->isSubstitutionFailure())
2534 OS << "<<error-type>>";
2535 else
2536 TypeReq->getType()->getType().print(OS, Policy);
2537 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2538 if (ExprReq->isCompound())
2539 OS << "{ ";
2540 if (ExprReq->isExprSubstitutionFailure())
2541 OS << "<<error-expression>>";
2542 else
2543 PrintExpr(ExprReq->getExpr());
2544 if (ExprReq->isCompound()) {
2545 OS << " }";
2546 if (ExprReq->getNoexceptLoc().isValid())
2547 OS << " noexcept";
2548 const auto &RetReq = ExprReq->getReturnTypeRequirement();
2549 if (!RetReq.isEmpty()) {
2550 OS << " -> ";
2551 if (RetReq.isSubstitutionFailure())
2552 OS << "<<error-type>>";
2553 else if (RetReq.isTypeConstraint())
2554 RetReq.getTypeConstraint()->print(OS, Policy);
2555 }
2556 }
2557 } else {
2558 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2559 OS << "requires ";
2560 if (NestedReq->hasInvalidConstraint())
2561 OS << "<<error-expression>>";
2562 else
2563 PrintExpr(NestedReq->getConstraintExpr());
2564 }
2565 OS << "; ";
2566 }
2567 OS << "}";
2568}
2569
2570// C++ Coroutines
2571
2572void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2573 Visit(S->getBody());
2574}
2575
2576void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2577 OS << "co_return";
2578 if (S->getOperand()) {
2579 OS << " ";
2580 Visit(S->getOperand());
2581 }
2582 OS << ";";
2583}
2584
2585void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2586 OS << "co_await ";
2587 PrintExpr(S->getOperand());
2588}
2589
2590void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2591 OS << "co_await ";
2592 PrintExpr(S->getOperand());
2593}
2594
2595void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2596 OS << "co_yield ";
2597 PrintExpr(S->getOperand());
2598}
2599
2600// Obj-C
2601
2602void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2603 OS << "@";
2604 VisitStringLiteral(Node->getString());
2605}
2606
2607void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2608 OS << "@";
2609 Visit(E->getSubExpr());
2610}
2611
2612void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2613 OS << "@[ ";
2615 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2616 if (I != Ch.begin())
2617 OS << ", ";
2618 Visit(*I);
2619 }
2620 OS << " ]";
2621}
2622
2623void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2624 OS << "@{ ";
2625 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2626 if (I > 0)
2627 OS << ", ";
2628
2630 Visit(Element.Key);
2631 OS << " : ";
2632 Visit(Element.Value);
2633 if (Element.isPackExpansion())
2634 OS << "...";
2635 }
2636 OS << " }";
2637}
2638
2639void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2640 OS << "@encode(";
2641 Node->getEncodedType().print(OS, Policy);
2642 OS << ')';
2643}
2644
2645void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2646 OS << "@selector(";
2647 Node->getSelector().print(OS);
2648 OS << ')';
2649}
2650
2651void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2652 OS << "@protocol(" << *Node->getProtocol() << ')';
2653}
2654
2655void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2656 OS << "[";
2657 switch (Mess->getReceiverKind()) {
2659 PrintExpr(Mess->getInstanceReceiver());
2660 break;
2661
2663 Mess->getClassReceiver().print(OS, Policy);
2664 break;
2665
2668 OS << "Super";
2669 break;
2670 }
2671
2672 OS << ' ';
2673 Selector selector = Mess->getSelector();
2674 if (selector.isUnarySelector()) {
2675 OS << selector.getNameForSlot(0);
2676 } else {
2677 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2678 if (i < selector.getNumArgs()) {
2679 if (i > 0) OS << ' ';
2680 if (selector.getIdentifierInfoForSlot(i))
2681 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2682 else
2683 OS << ":";
2684 }
2685 else OS << ", "; // Handle variadic methods.
2686
2687 PrintExpr(Mess->getArg(i));
2688 }
2689 }
2690 OS << "]";
2691}
2692
2693void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2694 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2695}
2696
2697void
2698StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2699 PrintExpr(E->getSubExpr());
2700}
2701
2702void
2703StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2704 OS << '(' << E->getBridgeKindName();
2705 E->getType().print(OS, Policy);
2706 OS << ')';
2707 PrintExpr(E->getSubExpr());
2708}
2709
2710void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2711 BlockDecl *BD = Node->getBlockDecl();
2712 OS << "^";
2713
2714 const FunctionType *AFT = Node->getFunctionType();
2715
2716 if (isa<FunctionNoProtoType>(AFT)) {
2717 OS << "()";
2718 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2719 OS << '(';
2720 for (BlockDecl::param_iterator AI = BD->param_begin(),
2721 E = BD->param_end(); AI != E; ++AI) {
2722 if (AI != BD->param_begin()) OS << ", ";
2723 std::string ParamStr = (*AI)->getNameAsString();
2724 (*AI)->getType().print(OS, Policy, ParamStr);
2725 }
2726
2727 const auto *FT = cast<FunctionProtoType>(AFT);
2728 if (FT->isVariadic()) {
2729 if (!BD->param_empty()) OS << ", ";
2730 OS << "...";
2731 }
2732 OS << ')';
2733 }
2734 OS << "{ }";
2735}
2736
2737void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2738 PrintExpr(Node->getSourceExpr());
2739}
2740
2741void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2742 // TODO: Print something reasonable for a TypoExpr, if necessary.
2743 llvm_unreachable("Cannot print TypoExpr nodes");
2744}
2745
2746void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2747 OS << "<recovery-expr>(";
2748 const char *Sep = "";
2749 for (Expr *E : Node->subExpressions()) {
2750 OS << Sep;
2751 PrintExpr(E);
2752 Sep = ", ";
2753 }
2754 OS << ')';
2755}
2756
2757void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2758 OS << "__builtin_astype(";
2759 PrintExpr(Node->getSrcExpr());
2760 OS << ", ";
2761 Node->getType().print(OS, Policy);
2762 OS << ")";
2763}
2764
2765//===----------------------------------------------------------------------===//
2766// Stmt method implementations
2767//===----------------------------------------------------------------------===//
2768
2769void Stmt::dumpPretty(const ASTContext &Context) const {
2770 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2771}
2772
2773void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2774 const PrintingPolicy &Policy, unsigned Indentation,
2775 StringRef NL, const ASTContext *Context) const {
2776 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2777 P.Visit(const_cast<Stmt *>(this));
2778}
2779
2780void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2781 const PrintingPolicy &Policy,
2782 unsigned Indentation, StringRef NL,
2783 const ASTContext *Context) const {
2784 StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2785 P.PrintControlledStmt(const_cast<Stmt *>(this));
2786}
2787
2788void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2789 const PrintingPolicy &Policy, bool AddQuotes) const {
2790 std::string Buf;
2791 llvm::raw_string_ostream TempOut(Buf);
2792
2793 printPretty(TempOut, Helper, Policy);
2794
2795 Out << JsonFormat(TempOut.str(), AddQuotes);
2796}
2797
2798//===----------------------------------------------------------------------===//
2799// PrinterHelper
2800//===----------------------------------------------------------------------===//
2801
2802// 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:1110
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines enumerations for expression traits intrinsics.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines several types used to describe C++ lambda expressions that are shared between the parser and ...
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
Defines an enumeration for C++ overloaded operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenMP AST classes for executable directives and clauses.
static bool isImplicitThis(const Expr *E)
static bool isImplicitSelf(const Expr *E)
static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix)
static bool printExprAsWritten(raw_ostream &OS, Expr *E, const ASTContext *Context)
Prints the given expression using the original source text.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
SourceManager & getSourceManager()
Definition: ASTContext.h:700
const LangOptions & getLangOpts() const
Definition: ASTContext.h:770
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4332
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5558
Represents a loop initializing the elements of an array.
Definition: Expr.h:5505
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2663
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2836
ArrayTypeTrait getTrait() const
Definition: ExprCXX.h:2876
QualType getQueriedType() const
Definition: ExprCXX.h:2878
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition: Expr.h:6228
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6431
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:2078
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4235
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3834
StringRef getOpcodeStr() const
Definition: Expr.h:3899
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4459
param_iterator param_end()
Definition: Decl.h:4558
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
Definition: Decl.h:4553
param_iterator param_begin()
Definition: Decl.h:4557
bool param_empty() const
Definition: Decl.h:4556
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6167
BreakStmt - This represents a break.
Definition: Stmt.h:2978
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5251
This class is used for builtin types like 'int'.
Definition: Type.h:2740
Kind getKind() const
Definition: Type.h:2782
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition: Expr.h:3765
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:1475
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:1530
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition: ExprCXX.h:1673
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition: ExprCXX.h:1623
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition: ExprCXX.h:1612
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition: ExprCXX.h:1670
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1254
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1361
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2481
bool isArrayForm() const
Definition: ExprCXX.h:2507
bool isGlobalDelete() const
Definition: ExprCXX.h:2506
Expr * getArgument()
Definition: ExprCXX.h:2522
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition: ExprCXX.h:3645
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:4791
Expr * getRHS() const
Definition: ExprCXX.h:4826
Expr * getLHS() const
Definition: ExprCXX.h:4825
BinaryOperatorKind getOperator() const
Definition: ExprCXX.h:4845
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:1801
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1721
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:2053
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:2224
bool isArray() const
Definition: ExprCXX.h:2332
QualType getAllocatedType() const
Definition: ExprCXX.h:2302
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:2337
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition: ExprCXX.h:2391
Expr * getPlacementArg(unsigned I)
Definition: ExprCXX.h:2371
unsigned getNumPlacementArgs() const
Definition: ExprCXX.h:2362
bool isParenTypeId() const
Definition: ExprCXX.h:2379
bool isGlobalNew() const
Definition: ExprCXX.h:2385
Expr * getInitializer()
The initializer of this new-expression.
Definition: ExprCXX.h:2397
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4088
Expr * getOperand() const
Definition: ExprCXX.h:4105
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:4913
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition: ExprCXX.h:2600
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition: ExprCXX.h:2664
IdentifierInfo * getDestroyedTypeIdentifier() const
In a dependent pseudo-destructor expression for which we do not have full type information on the des...
Definition: ExprCXX.h:2701
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:2658
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:2165
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:1869
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1192
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:3519
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:2819
This captures a statement into a function.
Definition: Stmt.h:3755
CaseStmt - Represent a case statement.
Definition: Stmt.h:1799
Expr * getSubExpr()
Definition: Expr.h:3539
static CharSourceRange getTokenRange(SourceRange R)
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition: Expr.cpp:1002
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4552
Represents a 'co_await' expression.
Definition: ExprCXX.h:5144
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4082
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3419
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1604
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:4173
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:2948
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4493
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:5225
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:1495
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
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:5176
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3285
Represents a single C99 designator.
Definition: Expr.h:5129
Represents a C99 designated initializer expression.
Definition: Expr.h:5086
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2723
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:3436
This represents one expression.
Definition: Expr.h:110
QualType getType() const
Definition: Expr.h:142
An expression trait intrinsic.
Definition: ExprCXX.h:2907
Expr * getQueriedExpression() const
Definition: ExprCXX.h:2946
ExpressionTrait getTrait() const
Definition: ExprCXX.h:2944
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition: Expr.h:6107
Represents difference between two FPOptions values.
Definition: LangOptions.h:870
Represents a member of a struct/union/class.
Definition: Decl.h:3025
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition: Decl.cpp:4527
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2779
const Expr * getSubExpr() const
Definition: Expr.h:1052
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2651
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:4599
VarDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition: ExprCXX.h:4626
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4199
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3799
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:3257
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4627
Represents a C11 generic selection.
Definition: Expr.h:5719
AssociationTy< false > Association
Definition: Expr.h:5950
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2860
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:2136
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:3649
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5594
IndirectGotoStmt - This represents an indirect goto.
Definition: Stmt.h:2899
Describes an C or C++ initializer list.
Definition: Expr.h:4841
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2029
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:1938
llvm::RoundingMode RoundingMode
Definition: LangOptions.h:68
FPExceptionModeKind
Possible floating point exception behavior.
Definition: LangOptions.h:264
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:3480
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:4679
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition: Expr.h:2741
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3182
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:5414
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition: Stmt.h:1567
OpenMP 5.0 [2.1.5, Array Sections].
Definition: ExprOpenMP.h:56
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition: ExprOpenMP.h:148
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:6302
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:275
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:6175
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:6240
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:2464
Helper class for OffsetOfExpr.
Definition: Expr.h:2358
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition: Expr.h:2416
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition: Expr.cpp:1672
@ Array
An index into an array.
Definition: Expr.h:2363
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2370
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:2412
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:104
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4142
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition: ExprCXX.h:4171
Expr * getIndexExpr() const
Definition: ExprCXX.h:4400
Expr * getPackIdExpression() const
Definition: ExprCXX.h:4396
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2129
Represents a parameter to a function.
Definition: Decl.h:1749
[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:6299
A (possibly-)qualified type.
Definition: Type.h:737
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:804
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:6634
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:3017
Represents a __leave statement.
Definition: Stmt.h:3716
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.
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:4425
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4220
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition: ExprCXX.h:4289
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4721
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:4377
CompoundStmt * getSubStmt()
Definition: Expr.h:4394
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:1445
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:1193
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4435
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition: ExprCXX.h:4520
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2386
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:6873
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6884
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2751
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition: ExprCXX.h:2801
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition: ExprCXX.h:2798
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition: ExprCXX.h:2788
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7724
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
Definition: Expr.h:6579
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2567
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2182
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition: Expr.cpp:1385
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3163
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3905
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:4661
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:2582
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.
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:2209
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:278
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:1314