clang API Documentation
00001 //===--- StmtDumper.cpp - Dumping implementation for Stmt ASTs ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the Stmt::dump/Stmt::print methods, which dump out the 00011 // AST in a form that exposes type details and other fields. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/AST/StmtVisitor.h" 00016 #include "clang/AST/DeclObjC.h" 00017 #include "clang/AST/DeclCXX.h" 00018 #include "clang/AST/PrettyPrinter.h" 00019 #include "clang/Basic/SourceManager.h" 00020 #include "llvm/Support/raw_ostream.h" 00021 using namespace clang; 00022 00023 //===----------------------------------------------------------------------===// 00024 // StmtDumper Visitor 00025 //===----------------------------------------------------------------------===// 00026 00027 namespace { 00028 class StmtDumper : public StmtVisitor<StmtDumper> { 00029 SourceManager *SM; 00030 raw_ostream &OS; 00031 unsigned IndentLevel; 00032 00033 /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump 00034 /// the first few levels of an AST. This keeps track of how many ast levels 00035 /// are left. 00036 unsigned MaxDepth; 00037 00038 /// LastLocFilename/LastLocLine - Keep track of the last location we print 00039 /// out so that we can print out deltas from then on out. 00040 const char *LastLocFilename; 00041 unsigned LastLocLine; 00042 00043 public: 00044 StmtDumper(SourceManager *sm, raw_ostream &os, unsigned maxDepth) 00045 : SM(sm), OS(os), IndentLevel(0-1), MaxDepth(maxDepth) { 00046 LastLocFilename = ""; 00047 LastLocLine = ~0U; 00048 } 00049 00050 void DumpSubTree(Stmt *S) { 00051 // Prune the recursion if not using dump all. 00052 if (MaxDepth == 0) return; 00053 00054 ++IndentLevel; 00055 if (S) { 00056 if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) 00057 VisitDeclStmt(DS); 00058 else { 00059 Visit(S); 00060 00061 // Print out children. 00062 Stmt::child_range CI = S->children(); 00063 if (CI) { 00064 while (CI) { 00065 OS << '\n'; 00066 DumpSubTree(*CI++); 00067 } 00068 } 00069 } 00070 OS << ')'; 00071 } else { 00072 Indent(); 00073 OS << "<<<NULL>>>"; 00074 } 00075 --IndentLevel; 00076 } 00077 00078 void DumpDeclarator(Decl *D); 00079 00080 void Indent() const { 00081 for (int i = 0, e = IndentLevel; i < e; ++i) 00082 OS << " "; 00083 } 00084 00085 void DumpType(QualType T) { 00086 SplitQualType T_split = T.split(); 00087 OS << "'" << QualType::getAsString(T_split) << "'"; 00088 00089 if (!T.isNull()) { 00090 // If the type is sugared, also dump a (shallow) desugared type. 00091 SplitQualType D_split = T.getSplitDesugaredType(); 00092 if (T_split != D_split) 00093 OS << ":'" << QualType::getAsString(D_split) << "'"; 00094 } 00095 } 00096 void DumpDeclRef(Decl *node); 00097 void DumpStmt(const Stmt *Node) { 00098 Indent(); 00099 OS << "(" << Node->getStmtClassName() 00100 << " " << (void*)Node; 00101 DumpSourceRange(Node); 00102 } 00103 void DumpValueKind(ExprValueKind K) { 00104 switch (K) { 00105 case VK_RValue: break; 00106 case VK_LValue: OS << " lvalue"; break; 00107 case VK_XValue: OS << " xvalue"; break; 00108 } 00109 } 00110 void DumpObjectKind(ExprObjectKind K) { 00111 switch (K) { 00112 case OK_Ordinary: break; 00113 case OK_BitField: OS << " bitfield"; break; 00114 case OK_ObjCProperty: OS << " objcproperty"; break; 00115 case OK_ObjCSubscript: OS << " objcsubscript"; break; 00116 case OK_VectorComponent: OS << " vectorcomponent"; break; 00117 } 00118 } 00119 void DumpExpr(const Expr *Node) { 00120 DumpStmt(Node); 00121 OS << ' '; 00122 DumpType(Node->getType()); 00123 DumpValueKind(Node->getValueKind()); 00124 DumpObjectKind(Node->getObjectKind()); 00125 } 00126 void DumpSourceRange(const Stmt *Node); 00127 void DumpLocation(SourceLocation Loc); 00128 00129 // Stmts. 00130 void VisitStmt(Stmt *Node); 00131 void VisitDeclStmt(DeclStmt *Node); 00132 void VisitLabelStmt(LabelStmt *Node); 00133 void VisitGotoStmt(GotoStmt *Node); 00134 00135 // Exprs 00136 void VisitExpr(Expr *Node); 00137 void VisitCastExpr(CastExpr *Node); 00138 void VisitDeclRefExpr(DeclRefExpr *Node); 00139 void VisitPredefinedExpr(PredefinedExpr *Node); 00140 void VisitCharacterLiteral(CharacterLiteral *Node); 00141 void VisitIntegerLiteral(IntegerLiteral *Node); 00142 void VisitFloatingLiteral(FloatingLiteral *Node); 00143 void VisitStringLiteral(StringLiteral *Str); 00144 void VisitUnaryOperator(UnaryOperator *Node); 00145 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node); 00146 void VisitMemberExpr(MemberExpr *Node); 00147 void VisitExtVectorElementExpr(ExtVectorElementExpr *Node); 00148 void VisitBinaryOperator(BinaryOperator *Node); 00149 void VisitCompoundAssignOperator(CompoundAssignOperator *Node); 00150 void VisitAddrLabelExpr(AddrLabelExpr *Node); 00151 void VisitBlockExpr(BlockExpr *Node); 00152 void VisitOpaqueValueExpr(OpaqueValueExpr *Node); 00153 00154 // C++ 00155 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 00156 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node); 00157 void VisitCXXThisExpr(CXXThisExpr *Node); 00158 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node); 00159 void VisitCXXConstructExpr(CXXConstructExpr *Node); 00160 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node); 00161 void VisitExprWithCleanups(ExprWithCleanups *Node); 00162 void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node); 00163 void DumpCXXTemporary(CXXTemporary *Temporary); 00164 00165 // ObjC 00166 void VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node); 00167 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node); 00168 void VisitObjCMessageExpr(ObjCMessageExpr* Node); 00169 void VisitObjCBoxedExpr(ObjCBoxedExpr* Node); 00170 void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); 00171 void VisitObjCProtocolExpr(ObjCProtocolExpr *Node); 00172 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node); 00173 void VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node); 00174 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); 00175 void VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node); 00176 }; 00177 } 00178 00179 //===----------------------------------------------------------------------===// 00180 // Utilities 00181 //===----------------------------------------------------------------------===// 00182 00183 void StmtDumper::DumpLocation(SourceLocation Loc) { 00184 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 00185 00186 // The general format we print out is filename:line:col, but we drop pieces 00187 // that haven't changed since the last loc printed. 00188 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 00189 00190 if (PLoc.isInvalid()) { 00191 OS << "<invalid sloc>"; 00192 return; 00193 } 00194 00195 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 00196 OS << PLoc.getFilename() << ':' << PLoc.getLine() 00197 << ':' << PLoc.getColumn(); 00198 LastLocFilename = PLoc.getFilename(); 00199 LastLocLine = PLoc.getLine(); 00200 } else if (PLoc.getLine() != LastLocLine) { 00201 OS << "line" << ':' << PLoc.getLine() 00202 << ':' << PLoc.getColumn(); 00203 LastLocLine = PLoc.getLine(); 00204 } else { 00205 OS << "col" << ':' << PLoc.getColumn(); 00206 } 00207 } 00208 00209 void StmtDumper::DumpSourceRange(const Stmt *Node) { 00210 // Can't translate locations if a SourceManager isn't available. 00211 if (SM == 0) return; 00212 00213 // TODO: If the parent expression is available, we can print a delta vs its 00214 // location. 00215 SourceRange R = Node->getSourceRange(); 00216 00217 OS << " <"; 00218 DumpLocation(R.getBegin()); 00219 if (R.getBegin() != R.getEnd()) { 00220 OS << ", "; 00221 DumpLocation(R.getEnd()); 00222 } 00223 OS << ">"; 00224 00225 // <t2.c:123:421[blah], t2.c:412:321> 00226 00227 } 00228 00229 00230 //===----------------------------------------------------------------------===// 00231 // Stmt printing methods. 00232 //===----------------------------------------------------------------------===// 00233 00234 void StmtDumper::VisitStmt(Stmt *Node) { 00235 DumpStmt(Node); 00236 } 00237 00238 void StmtDumper::DumpDeclarator(Decl *D) { 00239 // FIXME: Need to complete/beautify this... this code simply shows the 00240 // nodes are where they need to be. 00241 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) { 00242 OS << "\"typedef " << localType->getUnderlyingType().getAsString() 00243 << ' ' << *localType << '"'; 00244 } else if (TypeAliasDecl *localType = dyn_cast<TypeAliasDecl>(D)) { 00245 OS << "\"using " << *localType << " = " 00246 << localType->getUnderlyingType().getAsString() << '"'; 00247 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 00248 OS << "\""; 00249 // Emit storage class for vardecls. 00250 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 00251 if (V->getStorageClass() != SC_None) 00252 OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass()) 00253 << " "; 00254 } 00255 00256 std::string Name = VD->getNameAsString(); 00257 VD->getType().getAsStringInternal(Name, 00258 PrintingPolicy(VD->getASTContext().getLangOpts())); 00259 OS << Name; 00260 00261 // If this is a vardecl with an initializer, emit it. 00262 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 00263 if (V->getInit()) { 00264 OS << " =\n"; 00265 DumpSubTree(V->getInit()); 00266 } 00267 } 00268 OS << '"'; 00269 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 00270 // print a free standing tag decl (e.g. "struct x;"). 00271 const char *tagname; 00272 if (const IdentifierInfo *II = TD->getIdentifier()) 00273 tagname = II->getNameStart(); 00274 else 00275 tagname = "<anonymous>"; 00276 OS << '"' << TD->getKindName() << ' ' << tagname << ";\""; 00277 // FIXME: print tag bodies. 00278 } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) { 00279 // print using-directive decl (e.g. "using namespace x;") 00280 const char *ns; 00281 if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier()) 00282 ns = II->getNameStart(); 00283 else 00284 ns = "<anonymous>"; 00285 OS << '"' << UD->getDeclKindName() << ns << ";\""; 00286 } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) { 00287 // print using decl (e.g. "using std::string;") 00288 const char *tn = UD->isTypeName() ? "typename " : ""; 00289 OS << '"' << UD->getDeclKindName() << tn; 00290 UD->getQualifier()->print(OS, 00291 PrintingPolicy(UD->getASTContext().getLangOpts())); 00292 OS << ";\""; 00293 } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) { 00294 OS << "label " << *LD; 00295 } else if (StaticAssertDecl *SAD = dyn_cast<StaticAssertDecl>(D)) { 00296 OS << "\"static_assert(\n"; 00297 DumpSubTree(SAD->getAssertExpr()); 00298 OS << ",\n"; 00299 DumpSubTree(SAD->getMessage()); 00300 OS << ");\""; 00301 } else { 00302 llvm_unreachable("Unexpected decl"); 00303 } 00304 } 00305 00306 void StmtDumper::VisitDeclStmt(DeclStmt *Node) { 00307 DumpStmt(Node); 00308 OS << "\n"; 00309 for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end(); 00310 DI != DE; ++DI) { 00311 Decl* D = *DI; 00312 ++IndentLevel; 00313 Indent(); 00314 OS << (void*) D << " "; 00315 DumpDeclarator(D); 00316 if (DI+1 != DE) 00317 OS << "\n"; 00318 --IndentLevel; 00319 } 00320 } 00321 00322 void StmtDumper::VisitLabelStmt(LabelStmt *Node) { 00323 DumpStmt(Node); 00324 OS << " '" << Node->getName() << "'"; 00325 } 00326 00327 void StmtDumper::VisitGotoStmt(GotoStmt *Node) { 00328 DumpStmt(Node); 00329 OS << " '" << Node->getLabel()->getName() 00330 << "':" << (void*)Node->getLabel(); 00331 } 00332 00333 //===----------------------------------------------------------------------===// 00334 // Expr printing methods. 00335 //===----------------------------------------------------------------------===// 00336 00337 void StmtDumper::VisitExpr(Expr *Node) { 00338 DumpExpr(Node); 00339 } 00340 00341 static void DumpBasePath(raw_ostream &OS, CastExpr *Node) { 00342 if (Node->path_empty()) 00343 return; 00344 00345 OS << " ("; 00346 bool First = true; 00347 for (CastExpr::path_iterator 00348 I = Node->path_begin(), E = Node->path_end(); I != E; ++I) { 00349 const CXXBaseSpecifier *Base = *I; 00350 if (!First) 00351 OS << " -> "; 00352 00353 const CXXRecordDecl *RD = 00354 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 00355 00356 if (Base->isVirtual()) 00357 OS << "virtual "; 00358 OS << RD->getName(); 00359 First = false; 00360 } 00361 00362 OS << ')'; 00363 } 00364 00365 void StmtDumper::VisitCastExpr(CastExpr *Node) { 00366 DumpExpr(Node); 00367 OS << " <" << Node->getCastKindName(); 00368 DumpBasePath(OS, Node); 00369 OS << ">"; 00370 } 00371 00372 void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { 00373 DumpExpr(Node); 00374 00375 OS << " "; 00376 DumpDeclRef(Node->getDecl()); 00377 if (Node->getDecl() != Node->getFoundDecl()) { 00378 OS << " ("; 00379 DumpDeclRef(Node->getFoundDecl()); 00380 OS << ")"; 00381 } 00382 } 00383 00384 void StmtDumper::DumpDeclRef(Decl *d) { 00385 OS << d->getDeclKindName() << ' ' << (void*) d; 00386 00387 if (NamedDecl *nd = dyn_cast<NamedDecl>(d)) { 00388 OS << " '"; 00389 nd->getDeclName().printName(OS); 00390 OS << "'"; 00391 } 00392 00393 if (ValueDecl *vd = dyn_cast<ValueDecl>(d)) { 00394 OS << ' '; DumpType(vd->getType()); 00395 } 00396 } 00397 00398 void StmtDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 00399 DumpExpr(Node); 00400 OS << " ("; 00401 if (!Node->requiresADL()) OS << "no "; 00402 OS << "ADL) = '" << Node->getName() << '\''; 00403 00404 UnresolvedLookupExpr::decls_iterator 00405 I = Node->decls_begin(), E = Node->decls_end(); 00406 if (I == E) OS << " empty"; 00407 for (; I != E; ++I) 00408 OS << " " << (void*) *I; 00409 } 00410 00411 void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 00412 DumpExpr(Node); 00413 00414 OS << " " << Node->getDecl()->getDeclKindName() 00415 << "Decl='" << *Node->getDecl() 00416 << "' " << (void*)Node->getDecl(); 00417 if (Node->isFreeIvar()) 00418 OS << " isFreeIvar"; 00419 } 00420 00421 void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) { 00422 DumpExpr(Node); 00423 switch (Node->getIdentType()) { 00424 default: llvm_unreachable("unknown case"); 00425 case PredefinedExpr::Func: OS << " __func__"; break; 00426 case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 00427 case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 00428 } 00429 } 00430 00431 void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) { 00432 DumpExpr(Node); 00433 OS << " " << Node->getValue(); 00434 } 00435 00436 void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) { 00437 DumpExpr(Node); 00438 00439 bool isSigned = Node->getType()->isSignedIntegerType(); 00440 OS << " " << Node->getValue().toString(10, isSigned); 00441 } 00442 void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) { 00443 DumpExpr(Node); 00444 OS << " " << Node->getValueAsApproximateDouble(); 00445 } 00446 00447 void StmtDumper::VisitStringLiteral(StringLiteral *Str) { 00448 DumpExpr(Str); 00449 // FIXME: this doesn't print wstrings right. 00450 OS << " "; 00451 switch (Str->getKind()) { 00452 case StringLiteral::Ascii: break; // No prefix 00453 case StringLiteral::Wide: OS << 'L'; break; 00454 case StringLiteral::UTF8: OS << "u8"; break; 00455 case StringLiteral::UTF16: OS << 'u'; break; 00456 case StringLiteral::UTF32: OS << 'U'; break; 00457 } 00458 OS << '"'; 00459 OS.write_escaped(Str->getString()); 00460 OS << '"'; 00461 } 00462 00463 void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) { 00464 DumpExpr(Node); 00465 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 00466 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 00467 } 00468 void StmtDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) { 00469 DumpExpr(Node); 00470 switch(Node->getKind()) { 00471 case UETT_SizeOf: 00472 OS << " sizeof "; 00473 break; 00474 case UETT_AlignOf: 00475 OS << " __alignof "; 00476 break; 00477 case UETT_VecStep: 00478 OS << " vec_step "; 00479 break; 00480 } 00481 if (Node->isArgumentType()) 00482 DumpType(Node->getArgumentType()); 00483 } 00484 00485 void StmtDumper::VisitMemberExpr(MemberExpr *Node) { 00486 DumpExpr(Node); 00487 OS << " " << (Node->isArrow() ? "->" : ".") 00488 << *Node->getMemberDecl() << ' ' 00489 << (void*)Node->getMemberDecl(); 00490 } 00491 void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 00492 DumpExpr(Node); 00493 OS << " " << Node->getAccessor().getNameStart(); 00494 } 00495 void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) { 00496 DumpExpr(Node); 00497 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 00498 } 00499 void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 00500 DumpExpr(Node); 00501 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 00502 << "' ComputeLHSTy="; 00503 DumpType(Node->getComputationLHSType()); 00504 OS << " ComputeResultTy="; 00505 DumpType(Node->getComputationResultType()); 00506 } 00507 00508 void StmtDumper::VisitBlockExpr(BlockExpr *Node) { 00509 DumpExpr(Node); 00510 00511 BlockDecl *block = Node->getBlockDecl(); 00512 OS << " decl=" << block; 00513 00514 IndentLevel++; 00515 if (block->capturesCXXThis()) { 00516 OS << '\n'; Indent(); OS << "(capture this)"; 00517 } 00518 for (BlockDecl::capture_iterator 00519 i = block->capture_begin(), e = block->capture_end(); i != e; ++i) { 00520 OS << '\n'; 00521 Indent(); 00522 OS << "(capture "; 00523 if (i->isByRef()) OS << "byref "; 00524 if (i->isNested()) OS << "nested "; 00525 if (i->getVariable()) 00526 DumpDeclRef(i->getVariable()); 00527 if (i->hasCopyExpr()) DumpSubTree(i->getCopyExpr()); 00528 OS << ")"; 00529 } 00530 IndentLevel--; 00531 00532 OS << '\n'; 00533 DumpSubTree(block->getBody()); 00534 } 00535 00536 void StmtDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { 00537 DumpExpr(Node); 00538 00539 if (Expr *Source = Node->getSourceExpr()) { 00540 OS << '\n'; 00541 DumpSubTree(Source); 00542 } 00543 } 00544 00545 // GNU extensions. 00546 00547 void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) { 00548 DumpExpr(Node); 00549 OS << " " << Node->getLabel()->getName() 00550 << " " << (void*)Node->getLabel(); 00551 } 00552 00553 //===----------------------------------------------------------------------===// 00554 // C++ Expressions 00555 //===----------------------------------------------------------------------===// 00556 00557 void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 00558 DumpExpr(Node); 00559 OS << " " << Node->getCastName() 00560 << "<" << Node->getTypeAsWritten().getAsString() << ">" 00561 << " <" << Node->getCastKindName(); 00562 DumpBasePath(OS, Node); 00563 OS << ">"; 00564 } 00565 00566 void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 00567 DumpExpr(Node); 00568 OS << " " << (Node->getValue() ? "true" : "false"); 00569 } 00570 00571 void StmtDumper::VisitCXXThisExpr(CXXThisExpr *Node) { 00572 DumpExpr(Node); 00573 OS << " this"; 00574 } 00575 00576 void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 00577 DumpExpr(Node); 00578 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 00579 << " <" << Node->getCastKindName() << ">"; 00580 } 00581 00582 void StmtDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) { 00583 DumpExpr(Node); 00584 CXXConstructorDecl *Ctor = Node->getConstructor(); 00585 DumpType(Ctor->getType()); 00586 if (Node->isElidable()) 00587 OS << " elidable"; 00588 if (Node->requiresZeroInitialization()) 00589 OS << " zeroing"; 00590 } 00591 00592 void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 00593 DumpExpr(Node); 00594 OS << " "; 00595 DumpCXXTemporary(Node->getTemporary()); 00596 } 00597 00598 void StmtDumper::VisitExprWithCleanups(ExprWithCleanups *Node) { 00599 DumpExpr(Node); 00600 ++IndentLevel; 00601 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) { 00602 OS << "\n"; 00603 Indent(); 00604 OS << "(cleanup "; 00605 DumpDeclRef(Node->getObject(i)); 00606 OS << ")"; 00607 } 00608 --IndentLevel; 00609 } 00610 00611 void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) { 00612 OS << "(CXXTemporary " << (void *)Temporary << ")"; 00613 } 00614 00615 //===----------------------------------------------------------------------===// 00616 // Obj-C Expressions 00617 //===----------------------------------------------------------------------===// 00618 00619 void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) { 00620 DumpExpr(Node); 00621 OS << " selector=" << Node->getSelector().getAsString(); 00622 switch (Node->getReceiverKind()) { 00623 case ObjCMessageExpr::Instance: 00624 break; 00625 00626 case ObjCMessageExpr::Class: 00627 OS << " class="; 00628 DumpType(Node->getClassReceiver()); 00629 break; 00630 00631 case ObjCMessageExpr::SuperInstance: 00632 OS << " super (instance)"; 00633 break; 00634 00635 case ObjCMessageExpr::SuperClass: 00636 OS << " super (class)"; 00637 break; 00638 } 00639 } 00640 00641 void StmtDumper::VisitObjCBoxedExpr(ObjCBoxedExpr* Node) { 00642 DumpExpr(Node); 00643 OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString(); 00644 } 00645 00646 void StmtDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) { 00647 DumpStmt(Node); 00648 if (VarDecl *CatchParam = Node->getCatchParamDecl()) { 00649 OS << " catch parm = "; 00650 DumpDeclarator(CatchParam); 00651 } else { 00652 OS << " catch all"; 00653 } 00654 } 00655 00656 void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 00657 DumpExpr(Node); 00658 OS << " "; 00659 DumpType(Node->getEncodedType()); 00660 } 00661 00662 void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 00663 DumpExpr(Node); 00664 00665 OS << " " << Node->getSelector().getAsString(); 00666 } 00667 00668 void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 00669 DumpExpr(Node); 00670 00671 OS << ' ' <<* Node->getProtocol(); 00672 } 00673 00674 void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 00675 DumpExpr(Node); 00676 if (Node->isImplicitProperty()) { 00677 OS << " Kind=MethodRef Getter=\""; 00678 if (Node->getImplicitPropertyGetter()) 00679 OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 00680 else 00681 OS << "(null)"; 00682 00683 OS << "\" Setter=\""; 00684 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 00685 OS << Setter->getSelector().getAsString(); 00686 else 00687 OS << "(null)"; 00688 OS << "\""; 00689 } else { 00690 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 00691 } 00692 00693 if (Node->isSuperReceiver()) 00694 OS << " super"; 00695 00696 OS << " Messaging="; 00697 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 00698 OS << "Getter&Setter"; 00699 else if (Node->isMessagingGetter()) 00700 OS << "Getter"; 00701 else if (Node->isMessagingSetter()) 00702 OS << "Setter"; 00703 } 00704 00705 void StmtDumper::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) { 00706 DumpExpr(Node); 00707 if (Node->isArraySubscriptRefExpr()) 00708 OS << " Kind=ArraySubscript GetterForArray=\""; 00709 else 00710 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 00711 if (Node->getAtIndexMethodDecl()) 00712 OS << Node->getAtIndexMethodDecl()->getSelector().getAsString(); 00713 else 00714 OS << "(null)"; 00715 00716 if (Node->isArraySubscriptRefExpr()) 00717 OS << "\" SetterForArray=\""; 00718 else 00719 OS << "\" SetterForDictionary=\""; 00720 if (Node->setAtIndexMethodDecl()) 00721 OS << Node->setAtIndexMethodDecl()->getSelector().getAsString(); 00722 else 00723 OS << "(null)"; 00724 } 00725 00726 void StmtDumper::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { 00727 DumpExpr(Node); 00728 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 00729 } 00730 00731 //===----------------------------------------------------------------------===// 00732 // Stmt method implementations 00733 //===----------------------------------------------------------------------===// 00734 00735 /// dump - This does a local dump of the specified AST fragment. It dumps the 00736 /// specified node and a few nodes underneath it, but not the whole subtree. 00737 /// This is useful in a debugger. 00738 void Stmt::dump(SourceManager &SM) const { 00739 dump(llvm::errs(), SM); 00740 } 00741 00742 void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 00743 StmtDumper P(&SM, OS, 4); 00744 P.DumpSubTree(const_cast<Stmt*>(this)); 00745 OS << "\n"; 00746 } 00747 00748 /// dump - This does a local dump of the specified AST fragment. It dumps the 00749 /// specified node and a few nodes underneath it, but not the whole subtree. 00750 /// This is useful in a debugger. 00751 void Stmt::dump() const { 00752 StmtDumper P(0, llvm::errs(), 4); 00753 P.DumpSubTree(const_cast<Stmt*>(this)); 00754 llvm::errs() << "\n"; 00755 } 00756 00757 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 00758 void Stmt::dumpAll(SourceManager &SM) const { 00759 StmtDumper P(&SM, llvm::errs(), ~0U); 00760 P.DumpSubTree(const_cast<Stmt*>(this)); 00761 llvm::errs() << "\n"; 00762 } 00763 00764 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 00765 void Stmt::dumpAll() const { 00766 StmtDumper P(0, llvm::errs(), ~0U); 00767 P.DumpSubTree(const_cast<Stmt*>(this)); 00768 llvm::errs() << "\n"; 00769 }