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