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