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