blob: 113cbb48dde4cd5fd8900125693a998a4266c913 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner4b009652007-07-25 00:24:17 +00007//
8//===----------------------------------------------------------------------===//
9//
Chris Lattner95578782007-08-08 22:51:59 +000010// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
11// pretty print the AST back out to C code.
Chris Lattner4b009652007-07-25 00:24:17 +000012//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/StmtVisitor.h"
Douglas Gregor566782a2009-01-06 05:10:23 +000016#include "clang/AST/DeclCXX.h"
Ted Kremenek10364dd2007-10-17 18:36:42 +000017#include "clang/AST/DeclObjC.h"
Ted Kremenek08176a52007-08-31 21:30:12 +000018#include "clang/AST/PrettyPrinter.h"
Chris Lattner4b009652007-07-25 00:24:17 +000019#include "llvm/Support/Compiler.h"
Ted Kremenekdf409eb2007-11-26 22:50:46 +000020#include "llvm/Support/Streams.h"
Ted Kremenek7b6f67b2008-09-13 05:16:45 +000021#include "llvm/Support/Format.h"
Chris Lattner4b009652007-07-25 00:24:17 +000022using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// StmtPrinter Visitor
26//===----------------------------------------------------------------------===//
27
28namespace {
Chris Lattner7ba21fa2007-08-21 04:04:25 +000029 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
Ted Kremenek7b6f67b2008-09-13 05:16:45 +000030 llvm::raw_ostream &OS;
Chris Lattner4b009652007-07-25 00:24:17 +000031 unsigned IndentLevel;
Ted Kremenek08176a52007-08-31 21:30:12 +000032 clang::PrinterHelper* Helper;
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +000033 PrintingPolicy Policy;
34
Chris Lattner4b009652007-07-25 00:24:17 +000035 public:
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +000036 StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper,
37 const PrintingPolicy &Policy = PrintingPolicy(),
38 unsigned Indentation = 0)
39 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy) {}
Chris Lattner4b009652007-07-25 00:24:17 +000040
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +000041 void PrintStmt(Stmt *S) {
42 PrintStmt(S, Policy.Indentation);
43 }
44
45 void PrintStmt(Stmt *S, int SubIndent) {
Chris Lattner4b009652007-07-25 00:24:17 +000046 IndentLevel += SubIndent;
47 if (S && isa<Expr>(S)) {
48 // If this is an expr used in a stmt context, indent and newline it.
49 Indent();
Chris Lattner7ba21fa2007-08-21 04:04:25 +000050 Visit(S);
Chris Lattner4b009652007-07-25 00:24:17 +000051 OS << ";\n";
52 } else if (S) {
Chris Lattner7ba21fa2007-08-21 04:04:25 +000053 Visit(S);
Chris Lattner4b009652007-07-25 00:24:17 +000054 } else {
55 Indent() << "<<<NULL STATEMENT>>>\n";
56 }
57 IndentLevel -= SubIndent;
58 }
Eli Friedmane66ecf52009-05-30 00:19:54 +000059
60 QualType GetBaseType(QualType T);
61 void PrintBaseType(QualType T, TagDecl* TD);
62 void PrintDeclIdentifier(NamedDecl* ND);
Chris Lattner4b009652007-07-25 00:24:17 +000063 void PrintRawCompoundStmt(CompoundStmt *S);
64 void PrintRawDecl(Decl *D);
Ted Kremenek388b2842008-10-06 18:39:36 +000065 void PrintRawDeclStmt(DeclStmt *S);
Mike Stumpc43f4fc2009-02-10 20:16:46 +000066 void PrintFieldDecl(FieldDecl *FD);
Eli Friedmane66ecf52009-05-30 00:19:54 +000067 void PrintEnumConstantDecl(EnumConstantDecl *ECD);
Chris Lattner4b009652007-07-25 00:24:17 +000068 void PrintRawIfStmt(IfStmt *If);
Sebastian Redl237116b2008-12-22 21:35:02 +000069 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
Chris Lattner4b009652007-07-25 00:24:17 +000070
71 void PrintExpr(Expr *E) {
72 if (E)
Chris Lattner7ba21fa2007-08-21 04:04:25 +000073 Visit(E);
Chris Lattner4b009652007-07-25 00:24:17 +000074 else
75 OS << "<null expr>";
76 }
77
Mike Stumpc43f4fc2009-02-10 20:16:46 +000078 llvm::raw_ostream &Indent(int Delta = 0) {
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +000079 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
80 OS << " ";
Chris Lattner4b009652007-07-25 00:24:17 +000081 return OS;
82 }
83
Chris Lattner2af6a802007-08-30 17:59:59 +000084 bool PrintOffsetOfDesignator(Expr *E);
85 void VisitUnaryOffsetOf(UnaryOperator *Node);
86
Ted Kremenek08176a52007-08-31 21:30:12 +000087 void Visit(Stmt* S) {
88 if (Helper && Helper->handledStmt(S,OS))
89 return;
90 else StmtVisitor<StmtPrinter>::Visit(S);
91 }
92
Chris Lattner7ba21fa2007-08-21 04:04:25 +000093 void VisitStmt(Stmt *Node);
Douglas Gregor19330152008-11-14 12:46:07 +000094#define STMT(CLASS, PARENT) \
Chris Lattner7ba21fa2007-08-21 04:04:25 +000095 void Visit##CLASS(CLASS *Node);
Chris Lattner4b009652007-07-25 00:24:17 +000096#include "clang/AST/StmtNodes.def"
97 };
98}
99
100//===----------------------------------------------------------------------===//
101// Stmt printing methods.
102//===----------------------------------------------------------------------===//
103
104void StmtPrinter::VisitStmt(Stmt *Node) {
105 Indent() << "<<unknown stmt type>>\n";
106}
107
108/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
109/// with no newline after the }.
110void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
111 OS << "{\n";
112 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
113 I != E; ++I)
114 PrintStmt(*I);
115
116 Indent() << "}";
117}
118
Eli Friedmane66ecf52009-05-30 00:19:54 +0000119QualType StmtPrinter::GetBaseType(QualType T) {
120 // FIXME: This should be on the Type class!
121 QualType BaseType = T;
122 while (!BaseType->isSpecifierType()) {
123 if (isa<TypedefType>(BaseType))
124 break;
125 else if (const PointerType* PTy = BaseType->getAsPointerType())
126 BaseType = PTy->getPointeeType();
127 else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
128 BaseType = ATy->getElementType();
129 else if (const FunctionType* FTy = BaseType->getAsFunctionType())
130 BaseType = FTy->getResultType();
131 else
132 assert(0 && "Unknown declarator!");
133 }
134 return BaseType;
135}
136
137void StmtPrinter::PrintBaseType(QualType BaseType, TagDecl* TD) {
138 std::string BaseString;
139 if (TD && TD->isDefinition()) {
140 // FIXME: This is an ugly hack; perhaps we can expose something better
141 // from Type.h?
142 if (BaseType.isConstQualified())
143 OS << "const ";
144 PrintRawDecl(TD);
145 OS << " ";
146 } else {
147 BaseType.getAsStringInternal(BaseString, Policy);
148 OS << BaseString << " ";
149 }
150}
151
152void StmtPrinter::PrintDeclIdentifier(NamedDecl* ND) {
153 std::string Name = ND->getNameAsString();
154
155 QualType Ty;
156 if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(ND)) {
157 Ty = TDD->getUnderlyingType();
158 } else if (ValueDecl* VD = dyn_cast<ValueDecl>(ND)) {
159 Ty = VD->getType();
160 } else {
161 assert(0 && "Unexpected decl");
162 }
163
164 PrintingPolicy SubPolicy(Policy);
165 SubPolicy.SuppressTypeSpecifiers = true;
166 Ty.getAsStringInternal(Name, SubPolicy);
167 OS << Name;
168}
169
Chris Lattner4b009652007-07-25 00:24:17 +0000170void StmtPrinter::PrintRawDecl(Decl *D) {
171 // FIXME: Need to complete/beautify this... this code simply shows the
172 // nodes are where they need to be.
173 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
174 OS << "typedef " << localType->getUnderlyingType().getAsString();
Chris Lattner6c5ec622008-11-24 04:00:27 +0000175 OS << " " << localType->getNameAsString();
Chris Lattner4b009652007-07-25 00:24:17 +0000176 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
177 // Emit storage class for vardecls.
178 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
Daniel Dunbar644c15e2009-04-14 02:25:56 +0000179 if (V->getStorageClass() != VarDecl::None)
180 OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
181 << ' ';
Chris Lattner4b009652007-07-25 00:24:17 +0000182 }
183
Chris Lattner6c5ec622008-11-24 04:00:27 +0000184 std::string Name = VD->getNameAsString();
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +0000185 VD->getType().getAsStringInternal(Name, Policy);
Chris Lattner4b009652007-07-25 00:24:17 +0000186 OS << Name;
187
188 // If this is a vardecl with an initializer, emit it.
189 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
190 if (V->getInit()) {
191 OS << " = ";
192 PrintExpr(V->getInit());
193 }
194 }
Steve Naroff3340c232007-11-17 21:21:01 +0000195 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
196 // print a free standing tag decl (e.g. "struct x;").
197 OS << TD->getKindName();
198 OS << " ";
199 if (const IdentifierInfo *II = TD->getIdentifier())
200 OS << II->getName();
Eli Friedmane66ecf52009-05-30 00:19:54 +0000201 if (TD->isDefinition()) {
202 if (RecordDecl *RD = dyn_cast<RecordDecl>(TD)) {
203 OS << "{\n";
204 IndentLevel += 1;
205 // FIXME: The context passed to field_begin/field_end should
206 // never be NULL!
207 ASTContext *Context = 0;
208 for (RecordDecl::field_iterator i = RD->field_begin(*Context);
209 i != RD->field_end(*Context); ++i)
210 PrintFieldDecl(*i);
211 IndentLevel -= 1;
212 Indent() << "}";
213 } else if (EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
214 OS << "{\n";
215 IndentLevel += 1;
216 // FIXME: The context shouldn't be NULL!
217 ASTContext *Context = 0;
218 for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Context);
219 i != ED->enumerator_end(*Context); ++i)
220 PrintEnumConstantDecl(*i);
221 IndentLevel -= 1;
222 Indent() << "}";
Mike Stumpc43f4fc2009-02-10 20:16:46 +0000223 }
224 }
Chris Lattner4b009652007-07-25 00:24:17 +0000225 } else {
Chris Lattner4b009652007-07-25 00:24:17 +0000226 assert(0 && "Unexpected decl");
227 }
228}
229
Mike Stumpc43f4fc2009-02-10 20:16:46 +0000230void StmtPrinter::PrintFieldDecl(FieldDecl *FD) {
Eli Friedmane66ecf52009-05-30 00:19:54 +0000231 Indent();
232 QualType BaseType = GetBaseType(FD->getType());
233 PrintBaseType(BaseType, 0);
234 PrintDeclIdentifier(FD);
235 if (FD->isBitField()) {
236 OS << " : ";
237 PrintExpr(FD->getBitWidth());
238 }
239 OS << ";\n";
240}
241
242void StmtPrinter::PrintEnumConstantDecl(EnumConstantDecl *ECD) {
243 Indent() << ECD->getNameAsString();
244 if (ECD->getInitExpr()) {
245 OS << " = ";
246 PrintExpr(ECD->getInitExpr());
247 }
248 OS << ",\n";
Mike Stumpc43f4fc2009-02-10 20:16:46 +0000249}
250
Ted Kremenek388b2842008-10-06 18:39:36 +0000251void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
Eli Friedmane66ecf52009-05-30 00:19:54 +0000252 DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
253
254 TagDecl* TD = dyn_cast<TagDecl>(*Begin);
255 if (TD)
256 ++Begin;
257
Eli Friedman77ac2162009-05-30 01:45:29 +0000258 if (Begin == End) {
259 PrintRawDecl(TD);
260 return;
261 }
262
Eli Friedmane66ecf52009-05-30 00:19:54 +0000263 if (isa<TypedefDecl>(*Begin))
264 OS << "typedef ";
265 else if (VarDecl *V = dyn_cast<VarDecl>(*Begin)) {
266 switch (V->getStorageClass()) {
267 default: assert(0 && "Unknown storage class!");
268 case VarDecl::None: break;
269 case VarDecl::Auto: OS << "auto "; break;
270 case VarDecl::Register: OS << "register "; break;
271 case VarDecl::Extern: OS << "extern "; break;
272 case VarDecl::Static: OS << "static "; break;
273 case VarDecl::PrivateExtern: OS << "__private_extern__ "; break;
274 }
275 } else if (FunctionDecl *V = dyn_cast<FunctionDecl>(*Begin)) {
276 switch (V->getStorageClass()) {
277 default: assert(0 && "Unknown storage class!");
278 case FunctionDecl::None: break;
279 case FunctionDecl::Extern: OS << "extern "; break;
280 case FunctionDecl::Static: OS << "static "; break;
281 case FunctionDecl::PrivateExtern: OS << "__private_extern__ "; break;
282 }
283 } else {
284 assert(0 && "Unhandled decl");
285 }
286
287 QualType BaseType;
288 if (ValueDecl* VD = dyn_cast<ValueDecl>(*Begin)) {
289 BaseType = VD->getType();
290 } else {
291 BaseType = cast<TypedefDecl>(*Begin)->getUnderlyingType();
292 }
293 BaseType = GetBaseType(BaseType);
294 PrintBaseType(BaseType, TD);
295
Mike Stumpc43f4fc2009-02-10 20:16:46 +0000296 bool isFirst = true;
Eli Friedmane66ecf52009-05-30 00:19:54 +0000297 for ( ; Begin != End; ++Begin) {
Ted Kremenek388b2842008-10-06 18:39:36 +0000298 if (!isFirst) OS << ", ";
299 else isFirst = false;
Eli Friedmane66ecf52009-05-30 00:19:54 +0000300
301 PrintDeclIdentifier(cast<NamedDecl>(*Begin));
Ted Kremenek388b2842008-10-06 18:39:36 +0000302 }
303}
Chris Lattner4b009652007-07-25 00:24:17 +0000304
305void StmtPrinter::VisitNullStmt(NullStmt *Node) {
306 Indent() << ";\n";
307}
308
309void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
Eli Friedmane66ecf52009-05-30 00:19:54 +0000310 Indent();
311 PrintRawDeclStmt(Node);
312 OS << ";\n";
Chris Lattner4b009652007-07-25 00:24:17 +0000313}
314
315void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
316 Indent();
317 PrintRawCompoundStmt(Node);
318 OS << "\n";
319}
320
321void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
322 Indent(-1) << "case ";
323 PrintExpr(Node->getLHS());
324 if (Node->getRHS()) {
325 OS << " ... ";
326 PrintExpr(Node->getRHS());
327 }
328 OS << ":\n";
329
330 PrintStmt(Node->getSubStmt(), 0);
331}
332
333void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
334 Indent(-1) << "default:\n";
335 PrintStmt(Node->getSubStmt(), 0);
336}
337
338void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
339 Indent(-1) << Node->getName() << ":\n";
340 PrintStmt(Node->getSubStmt(), 0);
341}
342
343void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
Sebastian Redlfd835a22009-02-07 20:05:48 +0000344 OS << "if (";
Chris Lattner4b009652007-07-25 00:24:17 +0000345 PrintExpr(If->getCond());
Sebastian Redlfd835a22009-02-07 20:05:48 +0000346 OS << ')';
Chris Lattner4b009652007-07-25 00:24:17 +0000347
348 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
349 OS << ' ';
350 PrintRawCompoundStmt(CS);
351 OS << (If->getElse() ? ' ' : '\n');
352 } else {
353 OS << '\n';
354 PrintStmt(If->getThen());
355 if (If->getElse()) Indent();
356 }
357
358 if (Stmt *Else = If->getElse()) {
359 OS << "else";
360
361 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
362 OS << ' ';
363 PrintRawCompoundStmt(CS);
364 OS << '\n';
365 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
366 OS << ' ';
367 PrintRawIfStmt(ElseIf);
368 } else {
369 OS << '\n';
370 PrintStmt(If->getElse());
371 }
372 }
373}
374
375void StmtPrinter::VisitIfStmt(IfStmt *If) {
376 Indent();
377 PrintRawIfStmt(If);
378}
379
380void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
381 Indent() << "switch (";
382 PrintExpr(Node->getCond());
383 OS << ")";
384
385 // Pretty print compoundstmt bodies (very common).
386 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
387 OS << " ";
388 PrintRawCompoundStmt(CS);
389 OS << "\n";
390 } else {
391 OS << "\n";
392 PrintStmt(Node->getBody());
393 }
394}
395
396void StmtPrinter::VisitSwitchCase(SwitchCase*) {
397 assert(0 && "SwitchCase is an abstract class");
398}
399
400void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
401 Indent() << "while (";
402 PrintExpr(Node->getCond());
403 OS << ")\n";
404 PrintStmt(Node->getBody());
405}
406
407void StmtPrinter::VisitDoStmt(DoStmt *Node) {
Chris Lattnercfe0ff02007-09-15 21:49:37 +0000408 Indent() << "do ";
409 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
410 PrintRawCompoundStmt(CS);
411 OS << " ";
412 } else {
413 OS << "\n";
414 PrintStmt(Node->getBody());
415 Indent();
416 }
417
Eli Friedmanea6a2622009-05-17 01:05:34 +0000418 OS << "while (";
Chris Lattner4b009652007-07-25 00:24:17 +0000419 PrintExpr(Node->getCond());
Eli Friedmanea6a2622009-05-17 01:05:34 +0000420 OS << ");\n";
Chris Lattner4b009652007-07-25 00:24:17 +0000421}
422
423void StmtPrinter::VisitForStmt(ForStmt *Node) {
424 Indent() << "for (";
425 if (Node->getInit()) {
426 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
Ted Kremenek388b2842008-10-06 18:39:36 +0000427 PrintRawDeclStmt(DS);
Chris Lattner4b009652007-07-25 00:24:17 +0000428 else
429 PrintExpr(cast<Expr>(Node->getInit()));
430 }
Chris Lattnercfe0ff02007-09-15 21:49:37 +0000431 OS << ";";
432 if (Node->getCond()) {
433 OS << " ";
Chris Lattner4b009652007-07-25 00:24:17 +0000434 PrintExpr(Node->getCond());
Chris Lattnercfe0ff02007-09-15 21:49:37 +0000435 }
436 OS << ";";
437 if (Node->getInc()) {
438 OS << " ";
Chris Lattner4b009652007-07-25 00:24:17 +0000439 PrintExpr(Node->getInc());
Chris Lattnercfe0ff02007-09-15 21:49:37 +0000440 }
441 OS << ") ";
442
443 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
444 PrintRawCompoundStmt(CS);
445 OS << "\n";
446 } else {
447 OS << "\n";
448 PrintStmt(Node->getBody());
449 }
Chris Lattner4b009652007-07-25 00:24:17 +0000450}
451
Ted Kremenek42730c52008-01-07 19:49:32 +0000452void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
Fariborz Jahanian9e920f32008-01-02 22:54:34 +0000453 Indent() << "for (";
454 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
Ted Kremenek388b2842008-10-06 18:39:36 +0000455 PrintRawDeclStmt(DS);
Fariborz Jahanian9e920f32008-01-02 22:54:34 +0000456 else
457 PrintExpr(cast<Expr>(Node->getElement()));
458 OS << " in ";
459 PrintExpr(Node->getCollection());
460 OS << ") ";
461
462 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
463 PrintRawCompoundStmt(CS);
464 OS << "\n";
465 } else {
466 OS << "\n";
467 PrintStmt(Node->getBody());
468 }
469}
470
Chris Lattner4b009652007-07-25 00:24:17 +0000471void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
472 Indent() << "goto " << Node->getLabel()->getName() << ";\n";
473}
474
475void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
476 Indent() << "goto *";
477 PrintExpr(Node->getTarget());
478 OS << ";\n";
479}
480
481void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
482 Indent() << "continue;\n";
483}
484
485void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
486 Indent() << "break;\n";
487}
488
489
490void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
491 Indent() << "return";
492 if (Node->getRetValue()) {
493 OS << " ";
494 PrintExpr(Node->getRetValue());
495 }
496 OS << ";\n";
497}
498
Chris Lattner8a40a832007-10-29 04:04:16 +0000499
500void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
Anders Carlsson759f45d2007-11-23 23:12:25 +0000501 Indent() << "asm ";
502
503 if (Node->isVolatile())
504 OS << "volatile ";
505
506 OS << "(";
Anders Carlsson076c1112007-11-20 19:21:03 +0000507 VisitStringLiteral(Node->getAsmString());
Anders Carlsson965d5202007-11-22 01:36:19 +0000508
509 // Outputs
510 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
511 Node->getNumClobbers() != 0)
512 OS << " : ";
513
514 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
515 if (i != 0)
516 OS << ", ";
517
518 if (!Node->getOutputName(i).empty()) {
519 OS << '[';
520 OS << Node->getOutputName(i);
521 OS << "] ";
522 }
523
Chris Lattnere8625112009-03-10 04:59:06 +0000524 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
Anders Carlsson965d5202007-11-22 01:36:19 +0000525 OS << " ";
526 Visit(Node->getOutputExpr(i));
527 }
528
529 // Inputs
530 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
531 OS << " : ";
532
533 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
534 if (i != 0)
535 OS << ", ";
536
537 if (!Node->getInputName(i).empty()) {
538 OS << '[';
539 OS << Node->getInputName(i);
540 OS << "] ";
541 }
542
Chris Lattnere8625112009-03-10 04:59:06 +0000543 VisitStringLiteral(Node->getInputConstraintLiteral(i));
Anders Carlsson965d5202007-11-22 01:36:19 +0000544 OS << " ";
545 Visit(Node->getInputExpr(i));
546 }
547
548 // Clobbers
549 if (Node->getNumClobbers() != 0)
550 OS << " : ";
551
552 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
553 if (i != 0)
554 OS << ", ";
555
556 VisitStringLiteral(Node->getClobber(i));
557 }
558
Anders Carlsson076c1112007-11-20 19:21:03 +0000559 OS << ");\n";
Chris Lattner8a40a832007-10-29 04:04:16 +0000560}
561
Ted Kremenek42730c52008-01-07 19:49:32 +0000562void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
Fariborz Jahanian59e9e042007-11-02 18:16:07 +0000563 Indent() << "@try";
564 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
565 PrintRawCompoundStmt(TS);
566 OS << "\n";
567 }
568
Ted Kremenek42730c52008-01-07 19:49:32 +0000569 for (ObjCAtCatchStmt *catchStmt =
570 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
Fariborz Jahanian59e9e042007-11-02 18:16:07 +0000571 catchStmt;
572 catchStmt =
Ted Kremenek42730c52008-01-07 19:49:32 +0000573 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
Fariborz Jahanian59e9e042007-11-02 18:16:07 +0000574 Indent() << "@catch(";
Steve Naroff0e8b96a2009-03-03 19:52:17 +0000575 if (catchStmt->getCatchParamDecl()) {
576 if (Decl *DS = catchStmt->getCatchParamDecl())
577 PrintRawDecl(DS);
Fariborz Jahanian59e9e042007-11-02 18:16:07 +0000578 }
579 OS << ")";
580 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody()))
581 {
582 PrintRawCompoundStmt(CS);
583 OS << "\n";
584 }
585 }
586
Ted Kremenek42730c52008-01-07 19:49:32 +0000587 if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>(
Fariborz Jahanian50b47922007-11-07 00:46:42 +0000588 Node->getFinallyStmt())) {
589 Indent() << "@finally";
590 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
Fariborz Jahanian59e9e042007-11-02 18:16:07 +0000591 OS << "\n";
592 }
Fariborz Jahanian70952482007-11-01 21:12:44 +0000593}
594
Ted Kremenek42730c52008-01-07 19:49:32 +0000595void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
Fariborz Jahanian70952482007-11-01 21:12:44 +0000596}
597
Ted Kremenek42730c52008-01-07 19:49:32 +0000598void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
Fariborz Jahanian70952482007-11-01 21:12:44 +0000599 Indent() << "@catch (...) { /* todo */ } \n";
600}
601
Fariborz Jahanian5f5d6222008-01-30 17:38:29 +0000602void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
Fariborz Jahanian08df2c62007-11-07 02:00:49 +0000603 Indent() << "@throw";
604 if (Node->getThrowExpr()) {
605 OS << " ";
606 PrintExpr(Node->getThrowExpr());
607 }
608 OS << ";\n";
609}
610
Fariborz Jahanian5f5d6222008-01-30 17:38:29 +0000611void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
Fariborz Jahanian993360a2008-01-29 18:21:32 +0000612 Indent() << "@synchronized (";
613 PrintExpr(Node->getSynchExpr());
614 OS << ")";
Fariborz Jahanian5f5d6222008-01-30 17:38:29 +0000615 PrintRawCompoundStmt(Node->getSynchBody());
616 OS << "\n";
Fariborz Jahanian993360a2008-01-29 18:21:32 +0000617}
618
Sebastian Redl237116b2008-12-22 21:35:02 +0000619void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
620 OS << "catch (";
Sebastian Redl743c8162008-12-22 19:15:10 +0000621 if (Decl *ExDecl = Node->getExceptionDecl())
622 PrintRawDecl(ExDecl);
623 else
624 OS << "...";
625 OS << ") ";
626 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
Sebastian Redl237116b2008-12-22 21:35:02 +0000627}
628
629void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
630 Indent();
631 PrintRawCXXCatchStmt(Node);
632 OS << "\n";
633}
634
635void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
636 Indent() << "try ";
637 PrintRawCompoundStmt(Node->getTryBlock());
638 for(unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
639 OS << " ";
640 PrintRawCXXCatchStmt(Node->getHandler(i));
641 }
Sebastian Redl743c8162008-12-22 19:15:10 +0000642 OS << "\n";
643}
644
Chris Lattner4b009652007-07-25 00:24:17 +0000645//===----------------------------------------------------------------------===//
646// Expr printing methods.
647//===----------------------------------------------------------------------===//
648
649void StmtPrinter::VisitExpr(Expr *Node) {
650 OS << "<<unknown expr type>>";
651}
652
653void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
Chris Lattner6c5ec622008-11-24 04:00:27 +0000654 OS << Node->getDecl()->getNameAsString();
Chris Lattner4b009652007-07-25 00:24:17 +0000655}
656
Douglas Gregor7e508262009-03-19 03:51:16 +0000657void StmtPrinter::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *Node) {
Douglas Gregor566782a2009-01-06 05:10:23 +0000658 NamedDecl *D = Node->getDecl();
659
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +0000660 Node->getQualifier()->print(OS, Policy);
Douglas Gregor566782a2009-01-06 05:10:23 +0000661 OS << D->getNameAsString();
662}
663
Douglas Gregor47bde7c2009-03-19 17:26:29 +0000664void StmtPrinter::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *Node) {
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +0000665 Node->getQualifier()->print(OS, Policy);
Douglas Gregor47bde7c2009-03-19 17:26:29 +0000666 OS << Node->getDeclName().getAsString();
667}
668
Steve Naroff5eb2a4a2007-11-12 14:29:37 +0000669void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
Fariborz Jahanian4af72492007-11-12 22:29:28 +0000670 if (Node->getBase()) {
671 PrintExpr(Node->getBase());
672 OS << (Node->isArrow() ? "->" : ".");
673 }
Chris Lattner6c5ec622008-11-24 04:00:27 +0000674 OS << Node->getDecl()->getNameAsString();
Steve Naroff5eb2a4a2007-11-12 14:29:37 +0000675}
676
Steve Naroff05391d22008-05-30 00:40:33 +0000677void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
678 if (Node->getBase()) {
679 PrintExpr(Node->getBase());
680 OS << ".";
681 }
Steve Naroff0e948412008-12-04 16:24:46 +0000682 OS << Node->getProperty()->getNameAsCString();
Steve Naroff05391d22008-05-30 00:40:33 +0000683}
684
Fariborz Jahanianf18d4c82008-11-22 18:39:36 +0000685void StmtPrinter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node) {
686 if (Node->getBase()) {
687 PrintExpr(Node->getBase());
688 OS << ".";
689 }
690 // FIXME: Setter/Getter names
691}
692
Chris Lattner69909292008-08-10 01:53:14 +0000693void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
Chris Lattner4b009652007-07-25 00:24:17 +0000694 switch (Node->getIdentType()) {
695 default:
696 assert(0 && "unknown case");
Chris Lattner69909292008-08-10 01:53:14 +0000697 case PredefinedExpr::Func:
Chris Lattner4b009652007-07-25 00:24:17 +0000698 OS << "__func__";
699 break;
Chris Lattner69909292008-08-10 01:53:14 +0000700 case PredefinedExpr::Function:
Chris Lattner4b009652007-07-25 00:24:17 +0000701 OS << "__FUNCTION__";
702 break;
Chris Lattner69909292008-08-10 01:53:14 +0000703 case PredefinedExpr::PrettyFunction:
Chris Lattner4b009652007-07-25 00:24:17 +0000704 OS << "__PRETTY_FUNCTION__";
705 break;
706 }
707}
708
709void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
Chris Lattner4b009652007-07-25 00:24:17 +0000710 unsigned value = Node->getValue();
Chris Lattner1aaf71c2008-06-07 22:35:38 +0000711 if (Node->isWide())
712 OS << "L";
Chris Lattner4b009652007-07-25 00:24:17 +0000713 switch (value) {
714 case '\\':
715 OS << "'\\\\'";
716 break;
717 case '\'':
718 OS << "'\\''";
719 break;
720 case '\a':
721 // TODO: K&R: the meaning of '\\a' is different in traditional C
722 OS << "'\\a'";
723 break;
724 case '\b':
725 OS << "'\\b'";
726 break;
727 // Nonstandard escape sequence.
728 /*case '\e':
729 OS << "'\\e'";
730 break;*/
731 case '\f':
732 OS << "'\\f'";
733 break;
734 case '\n':
735 OS << "'\\n'";
736 break;
737 case '\r':
738 OS << "'\\r'";
739 break;
740 case '\t':
741 OS << "'\\t'";
742 break;
743 case '\v':
744 OS << "'\\v'";
745 break;
746 default:
Ted Kremenekf91bc1d2008-02-23 00:52:04 +0000747 if (value < 256 && isprint(value)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000748 OS << "'" << (char)value << "'";
749 } else if (value < 256) {
Ted Kremenek7b6f67b2008-09-13 05:16:45 +0000750 OS << "'\\x" << llvm::format("%x", value) << "'";
Chris Lattner4b009652007-07-25 00:24:17 +0000751 } else {
752 // FIXME what to really do here?
753 OS << value;
754 }
755 }
756}
757
758void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
759 bool isSigned = Node->getType()->isSignedIntegerType();
760 OS << Node->getValue().toString(10, isSigned);
761
762 // Emit suffixes. Integer literals are always a builtin integer type.
Chris Lattnerd5a56aa2008-07-26 22:17:49 +0000763 switch (Node->getType()->getAsBuiltinType()->getKind()) {
Chris Lattner4b009652007-07-25 00:24:17 +0000764 default: assert(0 && "Unexpected type for integer literal!");
765 case BuiltinType::Int: break; // no suffix.
766 case BuiltinType::UInt: OS << 'U'; break;
767 case BuiltinType::Long: OS << 'L'; break;
768 case BuiltinType::ULong: OS << "UL"; break;
769 case BuiltinType::LongLong: OS << "LL"; break;
770 case BuiltinType::ULongLong: OS << "ULL"; break;
771 }
772}
773void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
Chris Lattner6a390402007-08-01 00:23:58 +0000774 // FIXME: print value more precisely.
Chris Lattnere0391b22008-06-07 22:13:43 +0000775 OS << Node->getValueAsApproximateDouble();
Chris Lattner4b009652007-07-25 00:24:17 +0000776}
Chris Lattner1de66eb2007-08-26 03:42:43 +0000777
778void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
779 PrintExpr(Node->getSubExpr());
780 OS << "i";
781}
782
Chris Lattner4b009652007-07-25 00:24:17 +0000783void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
784 if (Str->isWide()) OS << 'L';
785 OS << '"';
Anders Carlsson55bfe0d2007-10-15 02:50:23 +0000786
Chris Lattner4b009652007-07-25 00:24:17 +0000787 // FIXME: this doesn't print wstrings right.
788 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
Chris Lattner5919a852009-01-16 19:25:18 +0000789 unsigned char Char = Str->getStrData()[i];
790
791 switch (Char) {
792 default:
793 if (isprint(Char))
794 OS << (char)Char;
795 else // Output anything hard as an octal escape.
796 OS << '\\'
797 << (char)('0'+ ((Char >> 6) & 7))
798 << (char)('0'+ ((Char >> 3) & 7))
799 << (char)('0'+ ((Char >> 0) & 7));
800 break;
801 // Handle some common non-printable cases to make dumps prettier.
Chris Lattner4b009652007-07-25 00:24:17 +0000802 case '\\': OS << "\\\\"; break;
803 case '"': OS << "\\\""; break;
804 case '\n': OS << "\\n"; break;
805 case '\t': OS << "\\t"; break;
806 case '\a': OS << "\\a"; break;
807 case '\b': OS << "\\b"; break;
808 }
809 }
810 OS << '"';
811}
812void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
813 OS << "(";
814 PrintExpr(Node->getSubExpr());
815 OS << ")";
816}
817void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
Chris Lattner2b97b092007-08-23 21:46:40 +0000818 if (!Node->isPostfix()) {
Chris Lattner4b009652007-07-25 00:24:17 +0000819 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
Chris Lattner2b97b092007-08-23 21:46:40 +0000820
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000821 // Print a space if this is an "identifier operator" like __real.
Chris Lattner2b97b092007-08-23 21:46:40 +0000822 switch (Node->getOpcode()) {
823 default: break;
Chris Lattner2b97b092007-08-23 21:46:40 +0000824 case UnaryOperator::Real:
825 case UnaryOperator::Imag:
826 case UnaryOperator::Extension:
827 OS << ' ';
828 break;
829 }
830 }
Chris Lattner4b009652007-07-25 00:24:17 +0000831 PrintExpr(Node->getSubExpr());
832
833 if (Node->isPostfix())
834 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
Chris Lattner4b009652007-07-25 00:24:17 +0000835}
Chris Lattner2af6a802007-08-30 17:59:59 +0000836
837bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
Eli Friedman342d9432009-02-27 06:44:11 +0000838 if (isa<UnaryOperator>(E)) {
Chris Lattner2af6a802007-08-30 17:59:59 +0000839 // Base case, print the type and comma.
840 OS << E->getType().getAsString() << ", ";
841 return true;
842 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
843 PrintOffsetOfDesignator(ASE->getLHS());
844 OS << "[";
845 PrintExpr(ASE->getRHS());
846 OS << "]";
847 return false;
848 } else {
849 MemberExpr *ME = cast<MemberExpr>(E);
850 bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
Chris Lattner6c5ec622008-11-24 04:00:27 +0000851 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString();
Chris Lattner2af6a802007-08-30 17:59:59 +0000852 return false;
853 }
854}
855
856void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
857 OS << "__builtin_offsetof(";
858 PrintOffsetOfDesignator(Node->getSubExpr());
859 OS << ")";
860}
861
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000862void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
863 OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
864 if (Node->isArgumentType())
865 OS << "(" << Node->getArgumentType().getAsString() << ")";
866 else {
867 OS << " ";
868 PrintExpr(Node->getArgumentExpr());
869 }
Chris Lattner4b009652007-07-25 00:24:17 +0000870}
871void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
Ted Kremenek1c1700f2007-08-20 16:18:38 +0000872 PrintExpr(Node->getLHS());
Chris Lattner4b009652007-07-25 00:24:17 +0000873 OS << "[";
Ted Kremenek1c1700f2007-08-20 16:18:38 +0000874 PrintExpr(Node->getRHS());
Chris Lattner4b009652007-07-25 00:24:17 +0000875 OS << "]";
876}
877
878void StmtPrinter::VisitCallExpr(CallExpr *Call) {
879 PrintExpr(Call->getCallee());
880 OS << "(";
881 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
Chris Lattner3e254fb2008-04-08 04:40:51 +0000882 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
883 // Don't print any defaulted arguments
884 break;
885 }
886
Chris Lattner4b009652007-07-25 00:24:17 +0000887 if (i) OS << ", ";
888 PrintExpr(Call->getArg(i));
889 }
890 OS << ")";
891}
892void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
Douglas Gregorbdbbc2d2009-01-08 22:45:41 +0000893 // FIXME: Suppress printing implicit bases (like "this")
894 PrintExpr(Node->getBase());
895 OS << (Node->isArrow() ? "->" : ".");
896 // FIXME: Suppress printing references to unnamed objects
897 // representing anonymous unions/structs
Douglas Gregor82d44772008-12-20 23:49:58 +0000898 OS << Node->getMemberDecl()->getNameAsString();
Chris Lattner4b009652007-07-25 00:24:17 +0000899}
Nate Begemanaf6ed502008-04-18 23:10:10 +0000900void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
Steve Naroffc11705f2007-07-28 23:10:27 +0000901 PrintExpr(Node->getBase());
902 OS << ".";
903 OS << Node->getAccessor().getName();
904}
Argiris Kirtzidisc45e2fb2008-08-18 23:01:59 +0000905void StmtPrinter::VisitCastExpr(CastExpr *) {
906 assert(0 && "CastExpr is an abstract class");
907}
Douglas Gregor21a04f32008-10-27 19:41:14 +0000908void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
909 assert(0 && "ExplicitCastExpr is an abstract class");
910}
Douglas Gregor035d0882008-10-28 15:36:24 +0000911void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
Chris Lattner4b009652007-07-25 00:24:17 +0000912 OS << "(" << Node->getType().getAsString() << ")";
913 PrintExpr(Node->getSubExpr());
914}
915void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
916 OS << "(" << Node->getType().getAsString() << ")";
917 PrintExpr(Node->getInitializer());
918}
919void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
920 // No need to print anything, simply forward to the sub expression.
921 PrintExpr(Node->getSubExpr());
922}
923void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
924 PrintExpr(Node->getLHS());
925 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
926 PrintExpr(Node->getRHS());
927}
Chris Lattner06078d22007-08-25 02:00:02 +0000928void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
929 PrintExpr(Node->getLHS());
930 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
931 PrintExpr(Node->getRHS());
932}
Chris Lattner4b009652007-07-25 00:24:17 +0000933void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
934 PrintExpr(Node->getCond());
Ted Kremenekeecd9e82007-11-26 18:27:54 +0000935
936 if (Node->getLHS()) {
937 OS << " ? ";
938 PrintExpr(Node->getLHS());
939 OS << " : ";
940 }
Douglas Gregor996677c2009-05-30 00:08:05 +0000941 else { // Handle GCC extension where LHS can be NULL.
Ted Kremenekeecd9e82007-11-26 18:27:54 +0000942 OS << " ?: ";
943 }
944
Chris Lattner4b009652007-07-25 00:24:17 +0000945 PrintExpr(Node->getRHS());
946}
947
948// GNU extensions.
949
Chris Lattnera0d03a72007-08-03 17:31:20 +0000950void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
Chris Lattner4b009652007-07-25 00:24:17 +0000951 OS << "&&" << Node->getLabel()->getName();
952}
953
954void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
955 OS << "(";
956 PrintRawCompoundStmt(E->getSubStmt());
957 OS << ")";
958}
959
Steve Naroff63bad2d2007-08-01 22:05:33 +0000960void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
961 OS << "__builtin_types_compatible_p(";
962 OS << Node->getArgType1().getAsString() << ",";
963 OS << Node->getArgType2().getAsString() << ")";
964}
965
Steve Naroff93c53012007-08-03 21:21:27 +0000966void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
967 OS << "__builtin_choose_expr(";
968 PrintExpr(Node->getCond());
Chris Lattner44fcf4f2007-08-04 00:20:15 +0000969 OS << ", ";
Steve Naroff93c53012007-08-03 21:21:27 +0000970 PrintExpr(Node->getLHS());
Chris Lattner44fcf4f2007-08-04 00:20:15 +0000971 OS << ", ";
Steve Naroff93c53012007-08-03 21:21:27 +0000972 PrintExpr(Node->getRHS());
973 OS << ")";
974}
Chris Lattner4b009652007-07-25 00:24:17 +0000975
Douglas Gregorad4b3792008-11-29 04:51:27 +0000976void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
977 OS << "__null";
978}
979
Eli Friedmand0e9d092008-05-14 19:38:39 +0000980void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
981 OS << "__builtin_shufflevector(";
982 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
983 if (i) OS << ", ";
984 PrintExpr(Node->getExpr(i));
985 }
986 OS << ")";
987}
988
Anders Carlsson762b7c72007-08-31 04:56:16 +0000989void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
Douglas Gregor1fa5d0d2009-05-30 00:56:08 +0000990 if (Node->getSyntacticForm()) {
991 Visit(Node->getSyntacticForm());
992 return;
993 }
994
Anders Carlsson762b7c72007-08-31 04:56:16 +0000995 OS << "{ ";
996 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
997 if (i) OS << ", ";
Douglas Gregorf603b472009-01-28 21:54:33 +0000998 if (Node->getInit(i))
999 PrintExpr(Node->getInit(i));
1000 else
1001 OS << "0";
Anders Carlsson762b7c72007-08-31 04:56:16 +00001002 }
1003 OS << " }";
1004}
1005
Douglas Gregorc5a6bdc2009-01-22 00:58:24 +00001006void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
Douglas Gregorf603b472009-01-28 21:54:33 +00001007 for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
1008 DEnd = Node->designators_end();
1009 D != DEnd; ++D) {
1010 if (D->isFieldDesignator()) {
1011 if (D->getDotLoc().isInvalid())
1012 OS << D->getFieldName()->getName() << ":";
1013 else
1014 OS << "." << D->getFieldName()->getName();
1015 } else {
1016 OS << "[";
1017 if (D->isArrayDesignator()) {
1018 PrintExpr(Node->getArrayIndex(*D));
1019 } else {
1020 PrintExpr(Node->getArrayRangeStart(*D));
1021 OS << " ... ";
1022 PrintExpr(Node->getArrayRangeEnd(*D));
1023 }
1024 OS << "]";
1025 }
1026 }
1027
1028 OS << " = ";
1029 PrintExpr(Node->getInit());
Douglas Gregorc5a6bdc2009-01-22 00:58:24 +00001030}
1031
Douglas Gregorc9e012a2009-01-29 17:44:32 +00001032void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
Douglas Gregor996677c2009-05-30 00:08:05 +00001033 if (Policy.CPlusPlus)
1034 OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
1035 else {
1036 OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
1037 if (Node->getType()->isRecordType())
1038 OS << "{}";
1039 else
1040 OS << 0;
1041 }
Douglas Gregorc9e012a2009-01-29 17:44:32 +00001042}
1043
Anders Carlsson36760332007-10-15 20:28:48 +00001044void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1045 OS << "va_arg(";
1046 PrintExpr(Node->getSubExpr());
1047 OS << ", ";
1048 OS << Node->getType().getAsString();
1049 OS << ")";
1050}
1051
Chris Lattner4b009652007-07-25 00:24:17 +00001052// C++
Douglas Gregor65fedaf2008-11-14 16:09:21 +00001053void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1054 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
1055 "",
1056#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1057 Spelling,
1058#include "clang/Basic/OperatorKinds.def"
1059 };
1060
1061 OverloadedOperatorKind Kind = Node->getOperator();
1062 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1063 if (Node->getNumArgs() == 1) {
1064 OS << OpStrings[Kind] << ' ';
1065 PrintExpr(Node->getArg(0));
1066 } else {
1067 PrintExpr(Node->getArg(0));
1068 OS << ' ' << OpStrings[Kind];
1069 }
1070 } else if (Kind == OO_Call) {
1071 PrintExpr(Node->getArg(0));
1072 OS << '(';
1073 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1074 if (ArgIdx > 1)
1075 OS << ", ";
1076 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1077 PrintExpr(Node->getArg(ArgIdx));
1078 }
1079 OS << ')';
1080 } else if (Kind == OO_Subscript) {
1081 PrintExpr(Node->getArg(0));
1082 OS << '[';
1083 PrintExpr(Node->getArg(1));
1084 OS << ']';
1085 } else if (Node->getNumArgs() == 1) {
1086 OS << OpStrings[Kind] << ' ';
1087 PrintExpr(Node->getArg(0));
1088 } else if (Node->getNumArgs() == 2) {
1089 PrintExpr(Node->getArg(0));
1090 OS << ' ' << OpStrings[Kind] << ' ';
1091 PrintExpr(Node->getArg(1));
1092 } else {
1093 assert(false && "unknown overloaded operator");
1094 }
1095}
Chris Lattner4b009652007-07-25 00:24:17 +00001096
Douglas Gregor3257fb52008-12-22 05:46:06 +00001097void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1098 VisitCallExpr(cast<CallExpr>(Node));
1099}
1100
Douglas Gregor21a04f32008-10-27 19:41:14 +00001101void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1102 OS << Node->getCastName() << '<';
1103 OS << Node->getTypeAsWritten().getAsString() << ">(";
Chris Lattner4b009652007-07-25 00:24:17 +00001104 PrintExpr(Node->getSubExpr());
1105 OS << ")";
1106}
1107
Douglas Gregor21a04f32008-10-27 19:41:14 +00001108void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1109 VisitCXXNamedCastExpr(Node);
1110}
1111
1112void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1113 VisitCXXNamedCastExpr(Node);
1114}
1115
1116void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
1117 VisitCXXNamedCastExpr(Node);
1118}
1119
1120void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
1121 VisitCXXNamedCastExpr(Node);
1122}
1123
Sebastian Redlb93b49c2008-11-11 11:37:55 +00001124void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
1125 OS << "typeid(";
1126 if (Node->isTypeOperand()) {
1127 OS << Node->getTypeOperand().getAsString();
1128 } else {
1129 PrintExpr(Node->getExprOperand());
1130 }
1131 OS << ")";
1132}
1133
Chris Lattner4b009652007-07-25 00:24:17 +00001134void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1135 OS << (Node->getValue() ? "true" : "false");
1136}
1137
Sebastian Redl5d0ead72009-05-10 18:38:11 +00001138void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1139 OS << "nullptr";
1140}
1141
Douglas Gregora5b022a2008-11-04 14:32:21 +00001142void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1143 OS << "this";
1144}
1145
Chris Lattnera7447ba2008-02-26 00:51:44 +00001146void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1147 if (Node->getSubExpr() == 0)
1148 OS << "throw";
1149 else {
1150 OS << "throw ";
1151 PrintExpr(Node->getSubExpr());
1152 }
1153}
1154
Chris Lattner3e254fb2008-04-08 04:40:51 +00001155void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1156 // Nothing to print: we picked up the default argument
1157}
1158
Argiris Kirtzidis7a1e7412008-08-22 15:38:55 +00001159void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1160 OS << Node->getType().getAsString();
1161 OS << "(";
1162 PrintExpr(Node->getSubExpr());
1163 OS << ")";
1164}
1165
Douglas Gregor861e7902009-01-16 18:33:17 +00001166void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1167 OS << Node->getType().getAsString();
1168 OS << "(";
1169 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1170 ArgEnd = Node->arg_end();
1171 Arg != ArgEnd; ++Arg) {
1172 if (Arg != Node->arg_begin())
1173 OS << ", ";
1174 PrintExpr(*Arg);
1175 }
1176 OS << ")";
1177}
1178
Argiris Kirtzidis7a1e7412008-08-22 15:38:55 +00001179void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
1180 OS << Node->getType().getAsString() << "()";
1181}
1182
Argiris Kirtzidisdbce6c12008-09-09 23:47:53 +00001183void
1184StmtPrinter::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
1185 PrintRawDecl(E->getVarDecl());
1186}
1187
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001188void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1189 if (E->isGlobalNew())
1190 OS << "::";
1191 OS << "new ";
1192 unsigned NumPlace = E->getNumPlacementArgs();
1193 if (NumPlace > 0) {
1194 OS << "(";
1195 PrintExpr(E->getPlacementArg(0));
1196 for (unsigned i = 1; i < NumPlace; ++i) {
1197 OS << ", ";
1198 PrintExpr(E->getPlacementArg(i));
1199 }
1200 OS << ") ";
1201 }
1202 if (E->isParenTypeId())
1203 OS << "(";
Sebastian Redl516432a2008-12-02 22:08:59 +00001204 std::string TypeS;
1205 if (Expr *Size = E->getArraySize()) {
1206 llvm::raw_string_ostream s(TypeS);
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +00001207 Size->printPretty(s, Helper, Policy);
Sebastian Redl516432a2008-12-02 22:08:59 +00001208 s.flush();
1209 TypeS = "[" + TypeS + "]";
1210 }
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +00001211 E->getAllocatedType().getAsStringInternal(TypeS, Policy);
Sebastian Redl516432a2008-12-02 22:08:59 +00001212 OS << TypeS;
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001213 if (E->isParenTypeId())
1214 OS << ")";
1215
1216 if (E->hasInitializer()) {
1217 OS << "(";
1218 unsigned NumCons = E->getNumConstructorArgs();
1219 if (NumCons > 0) {
1220 PrintExpr(E->getConstructorArg(0));
1221 for (unsigned i = 1; i < NumCons; ++i) {
1222 OS << ", ";
1223 PrintExpr(E->getConstructorArg(i));
1224 }
1225 }
1226 OS << ")";
1227 }
1228}
1229
1230void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1231 if (E->isGlobalDelete())
1232 OS << "::";
1233 OS << "delete ";
1234 if (E->isArrayForm())
1235 OS << "[] ";
1236 PrintExpr(E->getArgument());
1237}
1238
Douglas Gregor4646f9c2009-02-04 15:01:18 +00001239void StmtPrinter::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *E) {
1240 OS << E->getName().getAsString();
Douglas Gregora133e262008-12-06 00:22:45 +00001241}
1242
Anders Carlssondbbab8c2009-04-23 02:32:43 +00001243void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1244 // Nothing to print.
1245}
1246
Anders Carlsson9f4aef72009-05-01 22:18:43 +00001247void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
Anders Carlssonb5d9c472009-04-24 22:47:04 +00001248 // Just forward to the sub expression.
1249 PrintExpr(E->getSubExpr());
1250}
1251
Douglas Gregorf27b7652009-05-20 18:46:25 +00001252void
1253StmtPrinter::VisitCXXUnresolvedConstructExpr(
1254 CXXUnresolvedConstructExpr *Node) {
1255 OS << Node->getTypeAsWritten().getAsString();
1256 OS << "(";
1257 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1258 ArgEnd = Node->arg_end();
1259 Arg != ArgEnd; ++Arg) {
1260 if (Arg != Node->arg_begin())
1261 OS << ", ";
1262 PrintExpr(*Arg);
1263 }
1264 OS << ")";
1265}
1266
Douglas Gregor93b8b0f2009-05-22 21:13:27 +00001267void StmtPrinter::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *Node) {
1268 PrintExpr(Node->getBase());
1269 OS << (Node->isArrow() ? "->" : ".");
1270 OS << Node->getMember().getAsString();
1271}
1272
Sebastian Redl39c0f6f2009-01-05 20:52:13 +00001273static const char *getTypeTraitName(UnaryTypeTrait UTT) {
1274 switch (UTT) {
1275 default: assert(false && "Unknown type trait");
1276 case UTT_HasNothrowAssign: return "__has_nothrow_assign";
1277 case UTT_HasNothrowCopy: return "__has_nothrow_copy";
1278 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1279 case UTT_HasTrivialAssign: return "__has_trivial_assign";
1280 case UTT_HasTrivialCopy: return "__has_trivial_copy";
1281 case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1282 case UTT_HasTrivialDestructor: return "__has_trivial_destructor";
1283 case UTT_HasVirtualDestructor: return "__has_virtual_destructor";
1284 case UTT_IsAbstract: return "__is_abstract";
1285 case UTT_IsClass: return "__is_class";
1286 case UTT_IsEmpty: return "__is_empty";
1287 case UTT_IsEnum: return "__is_enum";
1288 case UTT_IsPOD: return "__is_pod";
1289 case UTT_IsPolymorphic: return "__is_polymorphic";
1290 case UTT_IsUnion: return "__is_union";
1291 }
1292}
1293
1294void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1295 OS << getTypeTraitName(E->getTrait()) << "("
1296 << E->getQueriedType().getAsString() << ")";
1297}
1298
Anders Carlssona66cad42007-08-21 17:43:55 +00001299// Obj-C
1300
1301void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1302 OS << "@";
1303 VisitStringLiteral(Node->getString());
1304}
Chris Lattner4b009652007-07-25 00:24:17 +00001305
Anders Carlsson8be1d402007-08-22 15:14:15 +00001306void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
Chris Lattner6c5ec622008-11-24 04:00:27 +00001307 OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
Anders Carlsson8be1d402007-08-22 15:14:15 +00001308}
1309
Fariborz Jahanianf807c202007-10-16 20:40:23 +00001310void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
Chris Lattner6c5ec622008-11-24 04:00:27 +00001311 OS << "@selector(" << Node->getSelector().getAsString() << ')';
Fariborz Jahanianf807c202007-10-16 20:40:23 +00001312}
1313
Fariborz Jahanianb391e6e2007-10-17 16:58:11 +00001314void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
Chris Lattner6c5ec622008-11-24 04:00:27 +00001315 OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')';
Fariborz Jahanianb391e6e2007-10-17 16:58:11 +00001316}
1317
Steve Naroffc39ca262007-09-18 23:55:05 +00001318void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1319 OS << "[";
Steve Narofffa465d12007-10-02 20:01:56 +00001320 Expr *receiver = Mess->getReceiver();
1321 if (receiver) PrintExpr(receiver);
1322 else OS << Mess->getClassName()->getName();
Ted Kremenekbfec9492008-05-02 17:32:38 +00001323 OS << ' ';
Ted Kremenek2287cee2008-04-16 04:30:16 +00001324 Selector selector = Mess->getSelector();
Steve Narofffa465d12007-10-02 20:01:56 +00001325 if (selector.isUnarySelector()) {
Ted Kremenekbfec9492008-05-02 17:32:38 +00001326 OS << selector.getIdentifierInfoForSlot(0)->getName();
Steve Narofffa465d12007-10-02 20:01:56 +00001327 } else {
1328 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
Ted Kremenekbfec9492008-05-02 17:32:38 +00001329 if (i < selector.getNumArgs()) {
1330 if (i > 0) OS << ' ';
1331 if (selector.getIdentifierInfoForSlot(i))
Chris Lattner6c5ec622008-11-24 04:00:27 +00001332 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
Ted Kremenekbfec9492008-05-02 17:32:38 +00001333 else
1334 OS << ":";
1335 }
1336 else OS << ", "; // Handle variadic methods.
1337
Steve Narofffa465d12007-10-02 20:01:56 +00001338 PrintExpr(Mess->getArg(i));
1339 }
Steve Naroffc39ca262007-09-18 23:55:05 +00001340 }
1341 OS << "]";
1342}
1343
Douglas Gregord8606632008-11-04 14:56:14 +00001344void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1345 OS << "super";
1346}
1347
Steve Naroff52a81c02008-09-03 18:15:37 +00001348void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
Steve Naroff9ac456d2008-10-08 17:01:13 +00001349 BlockDecl *BD = Node->getBlockDecl();
Steve Naroff52a81c02008-09-03 18:15:37 +00001350 OS << "^";
1351
1352 const FunctionType *AFT = Node->getFunctionType();
1353
Douglas Gregor4fa58902009-02-26 23:50:07 +00001354 if (isa<FunctionNoProtoType>(AFT)) {
Steve Naroff52a81c02008-09-03 18:15:37 +00001355 OS << "()";
Douglas Gregor4fa58902009-02-26 23:50:07 +00001356 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
Steve Naroff52a81c02008-09-03 18:15:37 +00001357 OS << '(';
1358 std::string ParamStr;
Steve Naroff9ac456d2008-10-08 17:01:13 +00001359 for (BlockDecl::param_iterator AI = BD->param_begin(),
1360 E = BD->param_end(); AI != E; ++AI) {
1361 if (AI != BD->param_begin()) OS << ", ";
Chris Lattner6c5ec622008-11-24 04:00:27 +00001362 ParamStr = (*AI)->getNameAsString();
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +00001363 (*AI)->getType().getAsStringInternal(ParamStr, Policy);
Steve Naroff52a81c02008-09-03 18:15:37 +00001364 OS << ParamStr;
1365 }
1366
Douglas Gregor4fa58902009-02-26 23:50:07 +00001367 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
Steve Naroff52a81c02008-09-03 18:15:37 +00001368 if (FT->isVariadic()) {
Steve Naroff9ac456d2008-10-08 17:01:13 +00001369 if (!BD->param_empty()) OS << ", ";
Steve Naroff52a81c02008-09-03 18:15:37 +00001370 OS << "...";
1371 }
1372 OS << ')';
1373 }
1374}
1375
Steve Naroff52a81c02008-09-03 18:15:37 +00001376void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
Chris Lattner6c5ec622008-11-24 04:00:27 +00001377 OS << Node->getDecl()->getNameAsString();
Steve Naroff52a81c02008-09-03 18:15:37 +00001378}
Chris Lattner4b009652007-07-25 00:24:17 +00001379//===----------------------------------------------------------------------===//
1380// Stmt method implementations
1381//===----------------------------------------------------------------------===//
1382
Chris Lattner95578782007-08-08 22:51:59 +00001383void Stmt::dumpPretty() const {
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +00001384 printPretty(llvm::errs(), 0, PrintingPolicy());
Chris Lattner4b009652007-07-25 00:24:17 +00001385}
1386
Mike Stumpc43f4fc2009-02-10 20:16:46 +00001387void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper,
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +00001388 const PrintingPolicy &Policy,
1389 unsigned Indentation) const {
Chris Lattner4b009652007-07-25 00:24:17 +00001390 if (this == 0) {
1391 OS << "<NULL>";
1392 return;
1393 }
1394
Douglas Gregor996677c2009-05-30 00:08:05 +00001395 if (Policy.Dump) {
1396 dump();
1397 return;
1398 }
1399
Douglas Gregor3bf3bbc2009-05-29 20:38:28 +00001400 StmtPrinter P(OS, Helper, Policy, Indentation);
Chris Lattner7ba21fa2007-08-21 04:04:25 +00001401 P.Visit(const_cast<Stmt*>(this));
Chris Lattner4b009652007-07-25 00:24:17 +00001402}
Ted Kremenek08176a52007-08-31 21:30:12 +00001403
1404//===----------------------------------------------------------------------===//
1405// PrinterHelper
1406//===----------------------------------------------------------------------===//
1407
1408// Implement virtual destructor.
Gabor Greif61ce98c2007-09-11 15:32:40 +00001409PrinterHelper::~PrinterHelper() {}