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