ASTConsumers.cpp revision 218893
1193326Sed//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// AST Consumer Implementations. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/Frontend/ASTConsumers.h" 15198092Srdivacky#include "clang/Frontend/DocumentXML.h" 16193326Sed#include "clang/Basic/Diagnostic.h" 17193326Sed#include "clang/Basic/SourceManager.h" 18193326Sed#include "clang/Basic/FileManager.h" 19193326Sed#include "clang/AST/AST.h" 20193326Sed#include "clang/AST/ASTConsumer.h" 21193326Sed#include "clang/AST/ASTContext.h" 22198092Srdivacky#include "clang/AST/RecordLayout.h" 23193326Sed#include "clang/AST/PrettyPrinter.h" 24193326Sed#include "llvm/Module.h" 25193326Sed#include "llvm/Support/Timer.h" 26193326Sed#include "llvm/Support/raw_ostream.h" 27218893Sdim#include "llvm/Support/Path.h" 28193326Sedusing namespace clang; 29193326Sed 30193326Sed//===----------------------------------------------------------------------===// 31193326Sed/// ASTPrinter - Pretty-printer and dumper of ASTs 32193326Sed 33193326Sednamespace { 34193326Sed class ASTPrinter : public ASTConsumer { 35193326Sed llvm::raw_ostream &Out; 36193326Sed bool Dump; 37198092Srdivacky 38193326Sed public: 39198092Srdivacky ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false) 40212904Sdim : Out(o? *o : llvm::outs()), Dump(Dump) { } 41198092Srdivacky 42193326Sed virtual void HandleTranslationUnit(ASTContext &Context) { 43193326Sed PrintingPolicy Policy = Context.PrintingPolicy; 44193326Sed Policy.Dump = Dump; 45195341Sed Context.getTranslationUnitDecl()->print(Out, Policy); 46193326Sed } 47193326Sed }; 48193326Sed} // end anonymous namespace 49193326Sed 50193326SedASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) { 51193326Sed return new ASTPrinter(out); 52193326Sed} 53193326Sed 54193326Sed//===----------------------------------------------------------------------===// 55193326Sed/// ASTPrinterXML - XML-printer of ASTs 56193326Sed 57193326Sednamespace { 58193326Sed class ASTPrinterXML : public ASTConsumer { 59193326Sed DocumentXML Doc; 60193326Sed 61193326Sed public: 62193326Sed ASTPrinterXML(llvm::raw_ostream& o) : Doc("CLANG_XML", o) {} 63198092Srdivacky 64193326Sed void Initialize(ASTContext &Context) { 65193326Sed Doc.initialize(Context); 66193326Sed } 67193326Sed 68193326Sed virtual void HandleTranslationUnit(ASTContext &Ctx) { 69193326Sed Doc.addSubNode("TranslationUnit"); 70198092Srdivacky for (DeclContext::decl_iterator 71195341Sed D = Ctx.getTranslationUnitDecl()->decls_begin(), 72195341Sed DEnd = Ctx.getTranslationUnitDecl()->decls_end(); 73198092Srdivacky D != DEnd; 74193326Sed ++D) 75193326Sed Doc.PrintDecl(*D); 76193326Sed Doc.toParent(); 77193326Sed Doc.finalize(); 78193326Sed } 79193326Sed }; 80193326Sed} // end anonymous namespace 81193326Sed 82193326Sed 83193326SedASTConsumer *clang::CreateASTPrinterXML(llvm::raw_ostream* out) { 84193326Sed return new ASTPrinterXML(out ? *out : llvm::outs()); 85193326Sed} 86198092Srdivacky 87198092SrdivackyASTConsumer *clang::CreateASTDumper() { 88198092Srdivacky return new ASTPrinter(0, true); 89193326Sed} 90193326Sed 91193326Sed//===----------------------------------------------------------------------===// 92193326Sed/// ASTViewer - AST Visualization 93193326Sed 94193326Sednamespace { 95193326Sed class ASTViewer : public ASTConsumer { 96193326Sed ASTContext *Context; 97193326Sed public: 98193326Sed void Initialize(ASTContext &Context) { 99193326Sed this->Context = &Context; 100193326Sed } 101193326Sed 102193326Sed virtual void HandleTopLevelDecl(DeclGroupRef D) { 103193326Sed for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) 104193326Sed HandleTopLevelSingleDecl(*I); 105193326Sed } 106198092Srdivacky 107193326Sed void HandleTopLevelSingleDecl(Decl *D); 108193326Sed }; 109193326Sed} 110193326Sed 111193326Sedvoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) { 112210299Sed if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) { 113210299Sed D->print(llvm::errs()); 114210299Sed 115210299Sed if (Stmt *Body = D->getBody()) { 116198092Srdivacky llvm::errs() << '\n'; 117198092Srdivacky Body->viewAST(); 118198092Srdivacky llvm::errs() << '\n'; 119193326Sed } 120193326Sed } 121193326Sed} 122193326Sed 123193326Sed 124193326SedASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); } 125193326Sed 126193326Sed//===----------------------------------------------------------------------===// 127193326Sed/// DeclContextPrinter - Decl and DeclContext Visualization 128193326Sed 129193326Sednamespace { 130193326Sed 131193326Sedclass DeclContextPrinter : public ASTConsumer { 132193326Sed llvm::raw_ostream& Out; 133193326Sedpublic: 134193326Sed DeclContextPrinter() : Out(llvm::errs()) {} 135193326Sed 136193326Sed void HandleTranslationUnit(ASTContext &C) { 137193326Sed PrintDeclContext(C.getTranslationUnitDecl(), 4); 138193326Sed } 139193326Sed 140193326Sed void PrintDeclContext(const DeclContext* DC, unsigned Indentation); 141193326Sed}; 142193326Sed} // end anonymous namespace 143193326Sed 144198092Srdivackyvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC, 145193326Sed unsigned Indentation) { 146193326Sed // Print DeclContext name. 147193326Sed switch (DC->getDeclKind()) { 148193326Sed case Decl::TranslationUnit: 149193326Sed Out << "[translation unit] " << DC; 150193326Sed break; 151193326Sed case Decl::Namespace: { 152193326Sed Out << "[namespace] "; 153193326Sed const NamespaceDecl* ND = cast<NamespaceDecl>(DC); 154207619Srdivacky Out << ND; 155193326Sed break; 156193326Sed } 157193326Sed case Decl::Enum: { 158193326Sed const EnumDecl* ED = cast<EnumDecl>(DC); 159193326Sed if (ED->isDefinition()) 160193326Sed Out << "[enum] "; 161193326Sed else 162193326Sed Out << "<enum> "; 163207619Srdivacky Out << ED; 164193326Sed break; 165193326Sed } 166193326Sed case Decl::Record: { 167193326Sed const RecordDecl* RD = cast<RecordDecl>(DC); 168193326Sed if (RD->isDefinition()) 169193326Sed Out << "[struct] "; 170193326Sed else 171193326Sed Out << "<struct> "; 172207619Srdivacky Out << RD; 173193326Sed break; 174193326Sed } 175193326Sed case Decl::CXXRecord: { 176193326Sed const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC); 177193326Sed if (RD->isDefinition()) 178193326Sed Out << "[class] "; 179193326Sed else 180193326Sed Out << "<class> "; 181207619Srdivacky Out << RD << ' ' << DC; 182193326Sed break; 183193326Sed } 184193326Sed case Decl::ObjCMethod: 185193326Sed Out << "[objc method]"; 186193326Sed break; 187193326Sed case Decl::ObjCInterface: 188193326Sed Out << "[objc interface]"; 189193326Sed break; 190193326Sed case Decl::ObjCCategory: 191193326Sed Out << "[objc category]"; 192193326Sed break; 193193326Sed case Decl::ObjCProtocol: 194193326Sed Out << "[objc protocol]"; 195193326Sed break; 196193326Sed case Decl::ObjCImplementation: 197193326Sed Out << "[objc implementation]"; 198193326Sed break; 199193326Sed case Decl::ObjCCategoryImpl: 200193326Sed Out << "[objc categoryimpl]"; 201193326Sed break; 202193326Sed case Decl::LinkageSpec: 203193326Sed Out << "[linkage spec]"; 204193326Sed break; 205193326Sed case Decl::Block: 206193326Sed Out << "[block]"; 207193326Sed break; 208193326Sed case Decl::Function: { 209193326Sed const FunctionDecl* FD = cast<FunctionDecl>(DC); 210193326Sed if (FD->isThisDeclarationADefinition()) 211193326Sed Out << "[function] "; 212193326Sed else 213193326Sed Out << "<function> "; 214207619Srdivacky Out << FD; 215193326Sed // Print the parameters. 216193326Sed Out << "("; 217193326Sed bool PrintComma = false; 218198092Srdivacky for (FunctionDecl::param_const_iterator I = FD->param_begin(), 219193326Sed E = FD->param_end(); I != E; ++I) { 220193326Sed if (PrintComma) 221193326Sed Out << ", "; 222193326Sed else 223193326Sed PrintComma = true; 224207619Srdivacky Out << *I; 225193326Sed } 226193326Sed Out << ")"; 227193326Sed break; 228193326Sed } 229193326Sed case Decl::CXXMethod: { 230193326Sed const CXXMethodDecl* D = cast<CXXMethodDecl>(DC); 231194613Sed if (D->isOutOfLine()) 232193326Sed Out << "[c++ method] "; 233193326Sed else if (D->isImplicit()) 234193326Sed Out << "(c++ method) "; 235193326Sed else 236193326Sed Out << "<c++ method> "; 237207619Srdivacky Out << D; 238193326Sed // Print the parameters. 239193326Sed Out << "("; 240193326Sed bool PrintComma = false; 241198092Srdivacky for (FunctionDecl::param_const_iterator I = D->param_begin(), 242193326Sed E = D->param_end(); I != E; ++I) { 243193326Sed if (PrintComma) 244193326Sed Out << ", "; 245193326Sed else 246193326Sed PrintComma = true; 247207619Srdivacky Out << *I; 248193326Sed } 249193326Sed Out << ")"; 250193326Sed 251193326Sed // Check the semantic DeclContext. 252193326Sed const DeclContext* SemaDC = D->getDeclContext(); 253193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 254193326Sed if (SemaDC != LexicalDC) 255193326Sed Out << " [[" << SemaDC << "]]"; 256193326Sed 257193326Sed break; 258193326Sed } 259193326Sed case Decl::CXXConstructor: { 260193326Sed const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC); 261194613Sed if (D->isOutOfLine()) 262193326Sed Out << "[c++ ctor] "; 263193326Sed else if (D->isImplicit()) 264193326Sed Out << "(c++ ctor) "; 265193326Sed else 266193326Sed Out << "<c++ ctor> "; 267207619Srdivacky Out << D; 268193326Sed // Print the parameters. 269193326Sed Out << "("; 270193326Sed bool PrintComma = false; 271198092Srdivacky for (FunctionDecl::param_const_iterator I = D->param_begin(), 272193326Sed E = D->param_end(); I != E; ++I) { 273193326Sed if (PrintComma) 274193326Sed Out << ", "; 275193326Sed else 276193326Sed PrintComma = true; 277207619Srdivacky Out << *I; 278193326Sed } 279193326Sed Out << ")"; 280193326Sed 281193326Sed // Check the semantic DC. 282193326Sed const DeclContext* SemaDC = D->getDeclContext(); 283193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 284193326Sed if (SemaDC != LexicalDC) 285193326Sed Out << " [[" << SemaDC << "]]"; 286193326Sed break; 287193326Sed } 288193326Sed case Decl::CXXDestructor: { 289193326Sed const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC); 290194613Sed if (D->isOutOfLine()) 291193326Sed Out << "[c++ dtor] "; 292193326Sed else if (D->isImplicit()) 293193326Sed Out << "(c++ dtor) "; 294193326Sed else 295193326Sed Out << "<c++ dtor> "; 296207619Srdivacky Out << D; 297193326Sed // Check the semantic DC. 298193326Sed const DeclContext* SemaDC = D->getDeclContext(); 299193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 300193326Sed if (SemaDC != LexicalDC) 301193326Sed Out << " [[" << SemaDC << "]]"; 302193326Sed break; 303193326Sed } 304193326Sed case Decl::CXXConversion: { 305193326Sed const CXXConversionDecl* D = cast<CXXConversionDecl>(DC); 306194613Sed if (D->isOutOfLine()) 307193326Sed Out << "[c++ conversion] "; 308193326Sed else if (D->isImplicit()) 309193326Sed Out << "(c++ conversion) "; 310193326Sed else 311193326Sed Out << "<c++ conversion> "; 312207619Srdivacky Out << D; 313193326Sed // Check the semantic DC. 314193326Sed const DeclContext* SemaDC = D->getDeclContext(); 315193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 316193326Sed if (SemaDC != LexicalDC) 317193326Sed Out << " [[" << SemaDC << "]]"; 318193326Sed break; 319193326Sed } 320193326Sed 321193326Sed default: 322193326Sed assert(0 && "a decl that inherits DeclContext isn't handled"); 323193326Sed } 324193326Sed 325193326Sed Out << "\n"; 326193326Sed 327193326Sed // Print decls in the DeclContext. 328195341Sed for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 329193326Sed I != E; ++I) { 330193326Sed for (unsigned i = 0; i < Indentation; ++i) 331193326Sed Out << " "; 332193326Sed 333193326Sed Decl::Kind DK = I->getKind(); 334193326Sed switch (DK) { 335193326Sed case Decl::Namespace: 336193326Sed case Decl::Enum: 337193326Sed case Decl::Record: 338193326Sed case Decl::CXXRecord: 339193326Sed case Decl::ObjCMethod: 340193326Sed case Decl::ObjCInterface: 341198092Srdivacky case Decl::ObjCCategory: 342193326Sed case Decl::ObjCProtocol: 343193326Sed case Decl::ObjCImplementation: 344193326Sed case Decl::ObjCCategoryImpl: 345193326Sed case Decl::LinkageSpec: 346193326Sed case Decl::Block: 347193326Sed case Decl::Function: 348193326Sed case Decl::CXXMethod: 349193326Sed case Decl::CXXConstructor: 350193326Sed case Decl::CXXDestructor: 351193326Sed case Decl::CXXConversion: 352193326Sed { 353193326Sed DeclContext* DC = cast<DeclContext>(*I); 354193326Sed PrintDeclContext(DC, Indentation+2); 355193326Sed break; 356193326Sed } 357218893Sdim case Decl::IndirectField: { 358218893Sdim IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(*I); 359218893Sdim Out << "<IndirectField> " << IFD << '\n'; 360218893Sdim break; 361218893Sdim } 362218893Sdim case Decl::Label: { 363218893Sdim LabelDecl *LD = cast<LabelDecl>(*I); 364218893Sdim Out << "<Label> " << LD << '\n'; 365218893Sdim break; 366218893Sdim } 367193326Sed case Decl::Field: { 368218893Sdim FieldDecl *FD = cast<FieldDecl>(*I); 369207619Srdivacky Out << "<field> " << FD << '\n'; 370193326Sed break; 371193326Sed } 372193326Sed case Decl::Typedef: { 373193326Sed TypedefDecl* TD = cast<TypedefDecl>(*I); 374207619Srdivacky Out << "<typedef> " << TD << '\n'; 375193326Sed break; 376193326Sed } 377193326Sed case Decl::EnumConstant: { 378193326Sed EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I); 379207619Srdivacky Out << "<enum constant> " << ECD << '\n'; 380193326Sed break; 381193326Sed } 382193326Sed case Decl::Var: { 383193326Sed VarDecl* VD = cast<VarDecl>(*I); 384207619Srdivacky Out << "<var> " << VD << '\n'; 385193326Sed break; 386193326Sed } 387193326Sed case Decl::ImplicitParam: { 388193326Sed ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I); 389207619Srdivacky Out << "<implicit parameter> " << IPD << '\n'; 390193326Sed break; 391193326Sed } 392193326Sed case Decl::ParmVar: { 393193326Sed ParmVarDecl* PVD = cast<ParmVarDecl>(*I); 394207619Srdivacky Out << "<parameter> " << PVD << '\n'; 395193326Sed break; 396193326Sed } 397193326Sed case Decl::ObjCProperty: { 398193326Sed ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I); 399207619Srdivacky Out << "<objc property> " << OPD << '\n'; 400193326Sed break; 401193326Sed } 402200583Srdivacky case Decl::FunctionTemplate: { 403200583Srdivacky FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I); 404207619Srdivacky Out << "<function template> " << FTD << '\n'; 405200583Srdivacky break; 406200583Srdivacky } 407202379Srdivacky case Decl::FileScopeAsm: { 408202379Srdivacky Out << "<file-scope asm>\n"; 409202379Srdivacky break; 410202379Srdivacky } 411202379Srdivacky case Decl::UsingDirective: { 412202379Srdivacky Out << "<using directive>\n"; 413202379Srdivacky break; 414202379Srdivacky } 415202379Srdivacky case Decl::NamespaceAlias: { 416202379Srdivacky NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I); 417207619Srdivacky Out << "<namespace alias> " << NAD << '\n'; 418202379Srdivacky break; 419202379Srdivacky } 420202879Srdivacky case Decl::ClassTemplate: { 421202879Srdivacky ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I); 422207619Srdivacky Out << "<class template> " << CTD << '\n'; 423202879Srdivacky break; 424202879Srdivacky } 425193326Sed default: 426207619Srdivacky Out << "DeclKind: " << DK << '"' << *I << "\"\n"; 427193326Sed assert(0 && "decl unhandled"); 428193326Sed } 429193326Sed } 430193326Sed} 431198092SrdivackyASTConsumer *clang::CreateDeclContextPrinter() { 432198092Srdivacky return new DeclContextPrinter(); 433193326Sed} 434193326Sed 435193326Sed//===----------------------------------------------------------------------===// 436218893Sdim/// ASTDumperXML - In-depth XML dumping. 437193326Sed 438193326Sednamespace { 439218893Sdimclass ASTDumpXML : public ASTConsumer { 440218893Sdim llvm::raw_ostream &OS; 441218893Sdim 442193326Sedpublic: 443218893Sdim ASTDumpXML(llvm::raw_ostream &OS) : OS(OS) {} 444198092Srdivacky 445193326Sed void HandleTranslationUnit(ASTContext &C) { 446218893Sdim C.getTranslationUnitDecl()->dumpXML(OS); 447218893Sdim } 448198092Srdivacky}; 449193326Sed} 450193326Sed 451218893SdimASTConsumer *clang::CreateASTDumperXML(llvm::raw_ostream &OS) { 452218893Sdim return new ASTDumpXML(OS); 453193326Sed} 454