ASTConsumers.cpp revision 195341
1221828Sgrehan//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===// 2221828Sgrehan// 3221828Sgrehan// The LLVM Compiler Infrastructure 4221828Sgrehan// 5221828Sgrehan// This file is distributed under the University of Illinois Open Source 6221828Sgrehan// License. See LICENSE.TXT for details. 7221828Sgrehan// 8221828Sgrehan//===----------------------------------------------------------------------===// 9221828Sgrehan// 10221828Sgrehan// AST Consumer Implementations. 11221828Sgrehan// 12221828Sgrehan//===----------------------------------------------------------------------===// 13221828Sgrehan 14221828Sgrehan#include "clang/Frontend/ASTConsumers.h" 15221828Sgrehan#include "clang/Frontend/DocumentXML.h" 16221828Sgrehan#include "clang/Frontend/PathDiagnosticClients.h" 17221828Sgrehan#include "clang/Basic/Diagnostic.h" 18221828Sgrehan#include "clang/Basic/SourceManager.h" 19221828Sgrehan#include "clang/Basic/FileManager.h" 20221828Sgrehan#include "clang/AST/AST.h" 21221828Sgrehan#include "clang/AST/ASTConsumer.h" 22221828Sgrehan#include "clang/AST/ASTContext.h" 23221828Sgrehan#include "clang/AST/PrettyPrinter.h" 24221828Sgrehan#include "clang/CodeGen/ModuleBuilder.h" 25221828Sgrehan#include "llvm/Module.h" 26221828Sgrehan#include "llvm/Support/Streams.h" 27221828Sgrehan#include "llvm/Support/Timer.h" 28221828Sgrehan#include "llvm/Support/raw_ostream.h" 29221828Sgrehan#include "llvm/System/Path.h" 30221828Sgrehanusing namespace clang; 31221828Sgrehan 32221828Sgrehan//===----------------------------------------------------------------------===// 33234695Sgrehan/// ASTPrinter - Pretty-printer and dumper of ASTs 34221828Sgrehan 35221828Sgrehannamespace { 36221828Sgrehan class ASTPrinter : public ASTConsumer { 37221828Sgrehan llvm::raw_ostream &Out; 38221828Sgrehan bool Dump; 39221828Sgrehan 40221828Sgrehan public: 41221828Sgrehan ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false) 42256072Sneel : Out(o? *o : llvm::errs()), Dump(Dump) { } 43221828Sgrehan 44221828Sgrehan virtual void HandleTranslationUnit(ASTContext &Context) { 45221828Sgrehan PrintingPolicy Policy = Context.PrintingPolicy; 46221828Sgrehan Policy.Dump = Dump; 47221828Sgrehan Context.getTranslationUnitDecl()->print(Out, Policy); 48256072Sneel } 49256072Sneel }; 50256072Sneel} // end anonymous namespace 51256072Sneel 52256072SneelASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) { 53256072Sneel return new ASTPrinter(out); 54221828Sgrehan} 55261275Sjhb 56221828Sgrehan//===----------------------------------------------------------------------===// 57221828Sgrehan/// ASTPrinterXML - XML-printer of ASTs 58241489Sneel 59262350Sjhbnamespace { 60221914Sjhb class ASTPrinterXML : public ASTConsumer { 61256072Sneel DocumentXML Doc; 62221828Sgrehan 63221828Sgrehan public: 64261088Sjhb ASTPrinterXML(llvm::raw_ostream& o) : Doc("CLANG_XML", o) {} 65268976Sjhb 66261088Sjhb void Initialize(ASTContext &Context) { 67268976Sjhb Doc.initialize(Context); 68256072Sneel } 69242275Sneel 70221828Sgrehan virtual void HandleTranslationUnit(ASTContext &Ctx) { 71221828Sgrehan Doc.addSubNode("TranslationUnit"); 72268891Sjhb for (DeclContext::decl_iterator 73268891Sjhb D = Ctx.getTranslationUnitDecl()->decls_begin(), 74261088Sjhb DEnd = Ctx.getTranslationUnitDecl()->decls_end(); 75261088Sjhb D != DEnd; 76221828Sgrehan ++D) 77276429Sneel { 78284894Sneel Doc.PrintDecl(*D); 79221828Sgrehan } 80221828Sgrehan Doc.toParent(); 81242065Sneel Doc.finalize(); 82221828Sgrehan } 83221828Sgrehan }; 84221828Sgrehan} // end anonymous namespace 85221828Sgrehan 86221828Sgrehan 87221828SgrehanASTConsumer *clang::CreateASTPrinterXML(llvm::raw_ostream* out) { 88270071Sgrehan return new ASTPrinterXML(out ? *out : llvm::outs()); 89270071Sgrehan} 90270071Sgrehan 91270071SgrehanASTConsumer *clang::CreateASTDumper() { 92270071Sgrehan return new ASTPrinter(0, true); 93270071Sgrehan} 94270071Sgrehan 95221828Sgrehan//===----------------------------------------------------------------------===// 96270071Sgrehan/// ASTViewer - AST Visualization 97270071Sgrehan 98270071Sgrehannamespace { 99284900Sneel class ASTViewer : public ASTConsumer { 100270071Sgrehan ASTContext *Context; 101270071Sgrehan public: 102270159Sgrehan void Initialize(ASTContext &Context) { 103270071Sgrehan this->Context = &Context; 104270071Sgrehan } 105270071Sgrehan 106284894Sneel virtual void HandleTopLevelDecl(DeclGroupRef D) { 107284894Sneel for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) 108284894Sneel HandleTopLevelSingleDecl(*I); 109270071Sgrehan } 110270071Sgrehan 111270071Sgrehan void HandleTopLevelSingleDecl(Decl *D); 112270071Sgrehan }; 113284894Sneel} 114221828Sgrehan 115221828Sgrehanvoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) { 116270071Sgrehan if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 117242065Sneel FD->print(llvm::errs()); 118242065Sneel 119242065Sneel if (FD->getBodyIfAvailable()) { 120256072Sneel llvm::cerr << '\n'; 121241489Sneel FD->getBodyIfAvailable()->viewAST(); 122256072Sneel llvm::cerr << '\n'; 123295124Sgrehan } 124295124Sgrehan return; 125295124Sgrehan } 126295124Sgrehan 127295124Sgrehan if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 128295124Sgrehan MD->print(llvm::errs()); 129295124Sgrehan 130256072Sneel if (MD->getBody()) { 131256072Sneel llvm::cerr << '\n'; 132295124Sgrehan MD->getBody()->viewAST(); 133295124Sgrehan llvm::cerr << '\n'; 134295124Sgrehan } 135295124Sgrehan } 136256072Sneel} 137295124Sgrehan 138221828Sgrehan 139270071SgrehanASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); } 140270071Sgrehan 141270071Sgrehan//===----------------------------------------------------------------------===// 142270071Sgrehan/// DeclContextPrinter - Decl and DeclContext Visualization 143270071Sgrehan 144270071Sgrehannamespace { 145221828Sgrehan 146270071Sgrehanclass DeclContextPrinter : public ASTConsumer { 147270071Sgrehan llvm::raw_ostream& Out; 148270071Sgrehanpublic: 149270071Sgrehan DeclContextPrinter() : Out(llvm::errs()) {} 150270071Sgrehan 151270071Sgrehan void HandleTranslationUnit(ASTContext &C) { 152276429Sneel PrintDeclContext(C.getTranslationUnitDecl(), 4); 153284894Sneel } 154270071Sgrehan 155270071Sgrehan void PrintDeclContext(const DeclContext* DC, unsigned Indentation); 156270071Sgrehan}; 157270071Sgrehan} // end anonymous namespace 158270071Sgrehan 159270071Sgrehanvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC, 160270071Sgrehan unsigned Indentation) { 161270071Sgrehan // Print DeclContext name. 162270071Sgrehan switch (DC->getDeclKind()) { 163295124Sgrehan case Decl::TranslationUnit: 164295124Sgrehan Out << "[translation unit] " << DC; 165270071Sgrehan break; 166270071Sgrehan case Decl::Namespace: { 167270071Sgrehan Out << "[namespace] "; 168221828Sgrehan const NamespaceDecl* ND = cast<NamespaceDecl>(DC); 169221828Sgrehan Out << ND->getNameAsString(); 170249396Sneel break; 171249396Sneel } 172221828Sgrehan case Decl::Enum: { 173266339Sjhb const EnumDecl* ED = cast<EnumDecl>(DC); 174221828Sgrehan if (ED->isDefinition()) 175261275Sjhb Out << "[enum] "; 176221828Sgrehan else 177256072Sneel Out << "<enum> "; 178284900Sneel Out << ED->getNameAsString(); 179284900Sneel break; 180221828Sgrehan } 181256072Sneel case Decl::Record: { 182256072Sneel const RecordDecl* RD = cast<RecordDecl>(DC); 183256072Sneel if (RD->isDefinition()) 184256072Sneel Out << "[struct] "; 185221828Sgrehan else 186221828Sgrehan Out << "<struct> "; 187221828Sgrehan Out << RD->getNameAsString(); 188221828Sgrehan break; 189221828Sgrehan } 190221828Sgrehan case Decl::CXXRecord: { 191221828Sgrehan const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC); 192221828Sgrehan if (RD->isDefinition()) 193221828Sgrehan Out << "[class] "; 194221828Sgrehan else 195221828Sgrehan Out << "<class> "; 196221828Sgrehan Out << RD->getNameAsString() << " " << DC; 197266339Sjhb break; 198266339Sjhb } 199266339Sjhb case Decl::ObjCMethod: 200266339Sjhb Out << "[objc method]"; 201221828Sgrehan break; 202245021Sneel case Decl::ObjCInterface: 203245021Sneel Out << "[objc interface]"; 204221828Sgrehan break; 205221828Sgrehan case Decl::ObjCCategory: 206221828Sgrehan Out << "[objc category]"; 207221828Sgrehan break; 208248389Sneel case Decl::ObjCProtocol: 209221828Sgrehan Out << "[objc protocol]"; 210266339Sjhb break; 211266339Sjhb case Decl::ObjCImplementation: 212268935Sjhb Out << "[objc implementation]"; 213268935Sjhb break; 214268935Sjhb case Decl::ObjCCategoryImpl: 215268935Sjhb Out << "[objc categoryimpl]"; 216268935Sjhb break; 217268935Sjhb case Decl::LinkageSpec: 218268935Sjhb Out << "[linkage spec]"; 219268935Sjhb break; 220268935Sjhb case Decl::Block: 221268935Sjhb Out << "[block]"; 222266339Sjhb break; 223266339Sjhb case Decl::Function: { 224266339Sjhb const FunctionDecl* FD = cast<FunctionDecl>(DC); 225266339Sjhb if (FD->isThisDeclarationADefinition()) 226276403Sneel Out << "[function] "; 227276403Sneel else 228276403Sneel Out << "<function> "; 229276403Sneel Out << FD->getNameAsString(); 230276403Sneel // Print the parameters. 231284899Sneel Out << "("; 232284899Sneel bool PrintComma = false; 233284899Sneel for (FunctionDecl::param_const_iterator I = FD->param_begin(), 234284899Sneel E = FD->param_end(); I != E; ++I) { 235284899Sneel if (PrintComma) 236295124Sgrehan Out << ", "; 237295124Sgrehan else 238284900Sneel PrintComma = true; 239284900Sneel Out << (*I)->getNameAsString(); 240284900Sneel } 241284900Sneel Out << ")"; 242284900Sneel break; 243284900Sneel } 244284900Sneel case Decl::CXXMethod: { 245284900Sneel const CXXMethodDecl* D = cast<CXXMethodDecl>(DC); 246284900Sneel if (D->isOutOfLine()) 247284900Sneel Out << "[c++ method] "; 248284900Sneel else if (D->isImplicit()) 249284900Sneel Out << "(c++ method) "; 250284900Sneel else 251284900Sneel Out << "<c++ method> "; 252284900Sneel Out << D->getNameAsString(); 253284900Sneel // Print the parameters. 254284900Sneel Out << "("; 255284900Sneel bool PrintComma = false; 256284900Sneel for (FunctionDecl::param_const_iterator I = D->param_begin(), 257284900Sneel E = D->param_end(); I != E; ++I) { 258284900Sneel if (PrintComma) 259284900Sneel Out << ", "; 260221828Sgrehan else 261270071Sgrehan PrintComma = true; 262221828Sgrehan Out << (*I)->getNameAsString(); 263266339Sjhb } 264266339Sjhb Out << ")"; 265266339Sjhb 266270071Sgrehan // Check the semantic DeclContext. 267270071Sgrehan const DeclContext* SemaDC = D->getDeclContext(); 268270071Sgrehan const DeclContext* LexicalDC = D->getLexicalDeclContext(); 269270071Sgrehan if (SemaDC != LexicalDC) 270221828Sgrehan Out << " [[" << SemaDC << "]]"; 271221828Sgrehan 272221828Sgrehan break; 273270071Sgrehan } 274221828Sgrehan case Decl::CXXConstructor: { 275221828Sgrehan const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC); 276270071Sgrehan if (D->isOutOfLine()) 277270071Sgrehan Out << "[c++ ctor] "; 278270071Sgrehan else if (D->isImplicit()) 279270071Sgrehan Out << "(c++ ctor) "; 280221828Sgrehan else 281221828Sgrehan Out << "<c++ ctor> "; 282270071Sgrehan Out << D->getNameAsString(); 283270071Sgrehan // Print the parameters. 284270071Sgrehan Out << "("; 285270071Sgrehan bool PrintComma = false; 286270071Sgrehan for (FunctionDecl::param_const_iterator I = D->param_begin(), 287270071Sgrehan E = D->param_end(); I != E; ++I) { 288270071Sgrehan if (PrintComma) 289270071Sgrehan Out << ", "; 290270071Sgrehan else 291270071Sgrehan PrintComma = true; 292266339Sjhb Out << (*I)->getNameAsString(); 293267447Sjhb } 294284900Sneel Out << ")"; 295270159Sgrehan 296270071Sgrehan // Check the semantic DC. 297270071Sgrehan const DeclContext* SemaDC = D->getDeclContext(); 298270071Sgrehan const DeclContext* LexicalDC = D->getLexicalDeclContext(); 299267427Sjhb if (SemaDC != LexicalDC) 300234695Sgrehan Out << " [[" << SemaDC << "]]"; 301270071Sgrehan break; 302221828Sgrehan } 303221828Sgrehan case Decl::CXXDestructor: { 304276403Sneel const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC); 305276403Sneel if (D->isOutOfLine()) 306276403Sneel Out << "[c++ dtor] "; 307276403Sneel else if (D->isImplicit()) 308276403Sneel Out << "(c++ dtor) "; 309276403Sneel else 310276403Sneel Out << "<c++ dtor> "; 311240894Sneel Out << D->getNameAsString(); 312240894Sneel // Check the semantic DC. 313240894Sneel const DeclContext* SemaDC = D->getDeclContext(); 314240894Sneel const DeclContext* LexicalDC = D->getLexicalDeclContext(); 315240894Sneel if (SemaDC != LexicalDC) 316240894Sneel Out << " [[" << SemaDC << "]]"; 317240894Sneel break; 318240894Sneel } 319240894Sneel case Decl::CXXConversion: { 320240894Sneel const CXXConversionDecl* D = cast<CXXConversionDecl>(DC); 321240894Sneel if (D->isOutOfLine()) 322240894Sneel Out << "[c++ conversion] "; 323240894Sneel else if (D->isImplicit()) 324261275Sjhb Out << "(c++ conversion) "; 325261275Sjhb else 326261275Sjhb Out << "<c++ conversion> "; 327261275Sjhb Out << D->getNameAsString(); 328261275Sjhb // Check the semantic DC. 329261275Sjhb const DeclContext* SemaDC = D->getDeclContext(); 330221828Sgrehan const DeclContext* LexicalDC = D->getLexicalDeclContext(); 331221828Sgrehan if (SemaDC != LexicalDC) 332221828Sgrehan Out << " [[" << SemaDC << "]]"; 333221828Sgrehan break; 334221828Sgrehan } 335242275Sneel 336221828Sgrehan default: 337266339Sjhb assert(0 && "a decl that inherits DeclContext isn't handled"); 338266339Sjhb } 339266339Sjhb 340266339Sjhb Out << "\n"; 341221828Sgrehan 342221828Sgrehan // Print decls in the DeclContext. 343221828Sgrehan for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 344221828Sgrehan I != E; ++I) { 345221828Sgrehan for (unsigned i = 0; i < Indentation; ++i) 346221828Sgrehan Out << " "; 347221828Sgrehan 348221828Sgrehan Decl::Kind DK = I->getKind(); 349221828Sgrehan switch (DK) { 350221828Sgrehan case Decl::Namespace: 351221828Sgrehan case Decl::Enum: 352261275Sjhb case Decl::Record: 353221828Sgrehan case Decl::CXXRecord: 354266339Sjhb case Decl::ObjCMethod: 355221828Sgrehan case Decl::ObjCInterface: 356221828Sgrehan case Decl::ObjCCategory: 357221828Sgrehan case Decl::ObjCProtocol: 358221828Sgrehan case Decl::ObjCImplementation: 359221828Sgrehan case Decl::ObjCCategoryImpl: 360221828Sgrehan case Decl::LinkageSpec: 361221828Sgrehan case Decl::Block: 362221828Sgrehan case Decl::Function: 363221828Sgrehan case Decl::CXXMethod: 364221828Sgrehan case Decl::CXXConstructor: 365284899Sneel case Decl::CXXDestructor: 366267070Sjhb case Decl::CXXConversion: 367221828Sgrehan { 368249396Sneel DeclContext* DC = cast<DeclContext>(*I); 369249396Sneel PrintDeclContext(DC, Indentation+2); 370221828Sgrehan break; 371221828Sgrehan } 372241454Sneel case Decl::Field: { 373241454Sneel FieldDecl* FD = cast<FieldDecl>(*I); 374261275Sjhb Out << "<field> " << FD->getNameAsString() << "\n"; 375241454Sneel break; 376266339Sjhb } 377266339Sjhb case Decl::Typedef: { 378241454Sneel TypedefDecl* TD = cast<TypedefDecl>(*I); 379253854Sgrehan Out << "<typedef> " << TD->getNameAsString() << "\n"; 380253854Sgrehan break; 381253854Sgrehan } 382253854Sgrehan case Decl::EnumConstant: { 383253854Sgrehan EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I); 384253854Sgrehan Out << "<enum constant> " << ECD->getNameAsString() << "\n"; 385241454Sneel break; 386221828Sgrehan } 387221828Sgrehan case Decl::Var: { 388221828Sgrehan VarDecl* VD = cast<VarDecl>(*I); 389221828Sgrehan Out << "<var> " << VD->getNameAsString() << "\n"; 390221828Sgrehan break; 391221828Sgrehan } 392221828Sgrehan case Decl::ImplicitParam: { 393221828Sgrehan ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I); 394221828Sgrehan Out << "<implicit parameter> " << IPD->getNameAsString() << "\n"; 395221828Sgrehan break; 396221828Sgrehan } 397221828Sgrehan case Decl::ParmVar: { 398221828Sgrehan ParmVarDecl* PVD = cast<ParmVarDecl>(*I); 399221828Sgrehan Out << "<parameter> " << PVD->getNameAsString() << "\n"; 400221828Sgrehan break; 401245704Sneel } 402245704Sneel case Decl::OriginalParmVar: { 403245704Sneel OriginalParmVarDecl* OPVD = cast<OriginalParmVarDecl>(*I); 404245704Sneel Out << "<original parameter> " << OPVD->getNameAsString() << "\n"; 405245704Sneel break; 406245704Sneel } 407245704Sneel case Decl::ObjCProperty: { 408221828Sgrehan ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I); 409245704Sneel Out << "<objc property> " << OPD->getNameAsString() << "\n"; 410221828Sgrehan break; 411221828Sgrehan } 412270071Sgrehan default: 413270071Sgrehan fprintf(stderr, "DeclKind: %d \"%s\"\n", DK, I->getDeclKindName()); 414270071Sgrehan assert(0 && "decl unhandled"); 415270071Sgrehan } 416270071Sgrehan } 417270071Sgrehan} 418270071SgrehanASTConsumer *clang::CreateDeclContextPrinter() { 419270071Sgrehan return new DeclContextPrinter(); 420270071Sgrehan} 421270071Sgrehan 422270071Sgrehan//===----------------------------------------------------------------------===// 423276429Sneel/// InheritanceViewer - C++ Inheritance Visualization 424284894Sneel 425284894Sneelnamespace { 426270071Sgrehanclass InheritanceViewer : public ASTConsumer { 427270071Sgrehan const std::string clsname; 428270071Sgrehanpublic: 429270071Sgrehan InheritanceViewer(const std::string& cname) : clsname(cname) {} 430270071Sgrehan 431270071Sgrehan void HandleTranslationUnit(ASTContext &C) { 432270071Sgrehan for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I) 433270071Sgrehan if (RecordType *T = dyn_cast<RecordType>(*I)) { 434270071Sgrehan if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(T->getDecl())) { 435270071Sgrehan // FIXME: This lookup needs to be generalized to handle namespaces and 436249396Sneel // (when we support them) templates. 437249396Sneel if (D->getNameAsString() == clsname) { 438221828Sgrehan D->viewInheritance(C); 439221828Sgrehan } 440256072Sneel } 441221828Sgrehan } 442249396Sneel } 443249396Sneel}; 444249396Sneel} 445249396Sneel 446249396SneelASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) { 447249396Sneel return new InheritanceViewer(clsname); 448249396Sneel} 449221828Sgrehan