Coverage Report

Created: 2024-01-17 10:31

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