Coverage Report

Created: 2022-05-14 11:35

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