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