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