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" 15193326Sed#include "clang/AST/AST.h" 16193326Sed#include "clang/AST/ASTConsumer.h" 17193326Sed#include "clang/AST/ASTContext.h" 18239462Sdim#include "clang/AST/PrettyPrinter.h" 19198092Srdivacky#include "clang/AST/RecordLayout.h" 20239462Sdim#include "clang/AST/RecursiveASTVisitor.h" 21249423Sdim#include "clang/Basic/Diagnostic.h" 22249423Sdim#include "clang/Basic/FileManager.h" 23249423Sdim#include "clang/Basic/SourceManager.h" 24249423Sdim#include "llvm/IR/Module.h" 25239462Sdim#include "llvm/Support/Path.h" 26249423Sdim#include "llvm/Support/Timer.h" 27239462Sdim#include "llvm/Support/raw_ostream.h" 28193326Sedusing namespace clang; 29193326Sed 30193326Sed//===----------------------------------------------------------------------===// 31193326Sed/// ASTPrinter - Pretty-printer and dumper of ASTs 32193326Sed 33193326Sednamespace { 34239462Sdim class ASTPrinter : public ASTConsumer, 35239462Sdim public RecursiveASTVisitor<ASTPrinter> { 36239462Sdim typedef RecursiveASTVisitor<ASTPrinter> base; 37239462Sdim 38239462Sdim public: 39239462Sdim ASTPrinter(raw_ostream *Out = NULL, bool Dump = false, 40263508Sdim StringRef FilterString = "", bool DumpLookups = false) 41239462Sdim : Out(Out ? *Out : llvm::outs()), Dump(Dump), 42263508Sdim FilterString(FilterString), DumpLookups(DumpLookups) {} 43239462Sdim 44239462Sdim virtual void HandleTranslationUnit(ASTContext &Context) { 45239462Sdim TranslationUnitDecl *D = Context.getTranslationUnitDecl(); 46239462Sdim 47263508Sdim if (FilterString.empty()) 48263508Sdim return print(D); 49239462Sdim 50239462Sdim TraverseDecl(D); 51239462Sdim } 52239462Sdim 53239462Sdim bool shouldWalkTypesOfTypeLocs() const { return false; } 54239462Sdim 55239462Sdim bool TraverseDecl(Decl *D) { 56243830Sdim if (D != NULL && filterMatches(D)) { 57249423Sdim bool ShowColors = Out.has_colors(); 58249423Sdim if (ShowColors) 59249423Sdim Out.changeColor(raw_ostream::BLUE); 60249423Sdim Out << (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n"; 61249423Sdim if (ShowColors) 62249423Sdim Out.resetColor(); 63263508Sdim print(D); 64243830Sdim Out << "\n"; 65239462Sdim // Don't traverse child nodes to avoid output duplication. 66239462Sdim return true; 67239462Sdim } 68239462Sdim return base::TraverseDecl(D); 69239462Sdim } 70239462Sdim 71239462Sdim private: 72239462Sdim std::string getName(Decl *D) { 73239462Sdim if (isa<NamedDecl>(D)) 74239462Sdim return cast<NamedDecl>(D)->getQualifiedNameAsString(); 75239462Sdim return ""; 76239462Sdim } 77239462Sdim bool filterMatches(Decl *D) { 78239462Sdim return getName(D).find(FilterString) != std::string::npos; 79239462Sdim } 80263508Sdim void print(Decl *D) { 81263508Sdim if (DumpLookups) { 82263508Sdim if (DeclContext *DC = dyn_cast<DeclContext>(D)) 83263508Sdim DC->dumpLookups(Out); 84263508Sdim else 85263508Sdim Out << "Not a DeclContext\n"; 86263508Sdim } else if (Dump) 87263508Sdim D->dump(Out); 88263508Sdim else 89263508Sdim D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true); 90263508Sdim } 91239462Sdim 92226633Sdim raw_ostream &Out; 93193326Sed bool Dump; 94239462Sdim std::string FilterString; 95263508Sdim bool DumpLookups; 96239462Sdim }; 97198092Srdivacky 98239462Sdim class ASTDeclNodeLister : public ASTConsumer, 99239462Sdim public RecursiveASTVisitor<ASTDeclNodeLister> { 100193326Sed public: 101239462Sdim ASTDeclNodeLister(raw_ostream *Out = NULL) 102239462Sdim : Out(Out ? *Out : llvm::outs()) {} 103198092Srdivacky 104193326Sed virtual void HandleTranslationUnit(ASTContext &Context) { 105239462Sdim TraverseDecl(Context.getTranslationUnitDecl()); 106193326Sed } 107239462Sdim 108239462Sdim bool shouldWalkTypesOfTypeLocs() const { return false; } 109239462Sdim 110239462Sdim virtual bool VisitNamedDecl(NamedDecl *D) { 111249423Sdim D->printQualifiedName(Out); 112249423Sdim Out << '\n'; 113239462Sdim return true; 114239462Sdim } 115239462Sdim 116239462Sdim private: 117239462Sdim raw_ostream &Out; 118193326Sed }; 119193326Sed} // end anonymous namespace 120193326Sed 121239462SdimASTConsumer *clang::CreateASTPrinter(raw_ostream *Out, 122239462Sdim StringRef FilterString) { 123239462Sdim return new ASTPrinter(Out, /*Dump=*/ false, FilterString); 124193326Sed} 125193326Sed 126263508SdimASTConsumer *clang::CreateASTDumper(StringRef FilterString, bool DumpLookups) { 127263508Sdim return new ASTPrinter(0, /*Dump=*/ true, FilterString, DumpLookups); 128193326Sed} 129193326Sed 130239462SdimASTConsumer *clang::CreateASTDeclNodeLister() { 131239462Sdim return new ASTDeclNodeLister(0); 132239462Sdim} 133239462Sdim 134193326Sed//===----------------------------------------------------------------------===// 135193326Sed/// ASTViewer - AST Visualization 136193326Sed 137193326Sednamespace { 138193326Sed class ASTViewer : public ASTConsumer { 139193326Sed ASTContext *Context; 140193326Sed public: 141193326Sed void Initialize(ASTContext &Context) { 142193326Sed this->Context = &Context; 143193326Sed } 144193326Sed 145234353Sdim virtual bool HandleTopLevelDecl(DeclGroupRef D) { 146193326Sed for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) 147193326Sed HandleTopLevelSingleDecl(*I); 148234353Sdim return true; 149193326Sed } 150198092Srdivacky 151193326Sed void HandleTopLevelSingleDecl(Decl *D); 152193326Sed }; 153193326Sed} 154193326Sed 155193326Sedvoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) { 156210299Sed if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) { 157210299Sed D->print(llvm::errs()); 158210299Sed 159210299Sed if (Stmt *Body = D->getBody()) { 160198092Srdivacky llvm::errs() << '\n'; 161198092Srdivacky Body->viewAST(); 162198092Srdivacky llvm::errs() << '\n'; 163193326Sed } 164193326Sed } 165193326Sed} 166193326Sed 167193326Sed 168193326SedASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); } 169193326Sed 170193326Sed//===----------------------------------------------------------------------===// 171193326Sed/// DeclContextPrinter - Decl and DeclContext Visualization 172193326Sed 173193326Sednamespace { 174193326Sed 175193326Sedclass DeclContextPrinter : public ASTConsumer { 176226633Sdim raw_ostream& Out; 177193326Sedpublic: 178193326Sed DeclContextPrinter() : Out(llvm::errs()) {} 179193326Sed 180193326Sed void HandleTranslationUnit(ASTContext &C) { 181193326Sed PrintDeclContext(C.getTranslationUnitDecl(), 4); 182193326Sed } 183193326Sed 184193326Sed void PrintDeclContext(const DeclContext* DC, unsigned Indentation); 185193326Sed}; 186193326Sed} // end anonymous namespace 187193326Sed 188198092Srdivackyvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC, 189193326Sed unsigned Indentation) { 190193326Sed // Print DeclContext name. 191193326Sed switch (DC->getDeclKind()) { 192193326Sed case Decl::TranslationUnit: 193193326Sed Out << "[translation unit] " << DC; 194193326Sed break; 195193326Sed case Decl::Namespace: { 196193326Sed Out << "[namespace] "; 197193326Sed const NamespaceDecl* ND = cast<NamespaceDecl>(DC); 198226633Sdim Out << *ND; 199193326Sed break; 200193326Sed } 201193326Sed case Decl::Enum: { 202193326Sed const EnumDecl* ED = cast<EnumDecl>(DC); 203226633Sdim if (ED->isCompleteDefinition()) 204193326Sed Out << "[enum] "; 205193326Sed else 206193326Sed Out << "<enum> "; 207226633Sdim Out << *ED; 208193326Sed break; 209193326Sed } 210193326Sed case Decl::Record: { 211193326Sed const RecordDecl* RD = cast<RecordDecl>(DC); 212226633Sdim if (RD->isCompleteDefinition()) 213193326Sed Out << "[struct] "; 214193326Sed else 215193326Sed Out << "<struct> "; 216226633Sdim Out << *RD; 217193326Sed break; 218193326Sed } 219193326Sed case Decl::CXXRecord: { 220193326Sed const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC); 221226633Sdim if (RD->isCompleteDefinition()) 222193326Sed Out << "[class] "; 223193326Sed else 224193326Sed Out << "<class> "; 225226633Sdim Out << *RD << ' ' << DC; 226193326Sed break; 227193326Sed } 228193326Sed case Decl::ObjCMethod: 229193326Sed Out << "[objc method]"; 230193326Sed break; 231193326Sed case Decl::ObjCInterface: 232193326Sed Out << "[objc interface]"; 233193326Sed break; 234193326Sed case Decl::ObjCCategory: 235193326Sed Out << "[objc category]"; 236193326Sed break; 237193326Sed case Decl::ObjCProtocol: 238193326Sed Out << "[objc protocol]"; 239193326Sed break; 240193326Sed case Decl::ObjCImplementation: 241193326Sed Out << "[objc implementation]"; 242193326Sed break; 243193326Sed case Decl::ObjCCategoryImpl: 244193326Sed Out << "[objc categoryimpl]"; 245193326Sed break; 246193326Sed case Decl::LinkageSpec: 247193326Sed Out << "[linkage spec]"; 248193326Sed break; 249193326Sed case Decl::Block: 250193326Sed Out << "[block]"; 251193326Sed break; 252193326Sed case Decl::Function: { 253193326Sed const FunctionDecl* FD = cast<FunctionDecl>(DC); 254223017Sdim if (FD->doesThisDeclarationHaveABody()) 255193326Sed Out << "[function] "; 256193326Sed else 257193326Sed Out << "<function> "; 258226633Sdim Out << *FD; 259193326Sed // Print the parameters. 260193326Sed Out << "("; 261193326Sed bool PrintComma = false; 262198092Srdivacky for (FunctionDecl::param_const_iterator I = FD->param_begin(), 263193326Sed E = FD->param_end(); I != E; ++I) { 264193326Sed if (PrintComma) 265193326Sed Out << ", "; 266193326Sed else 267193326Sed PrintComma = true; 268226633Sdim Out << **I; 269193326Sed } 270193326Sed Out << ")"; 271193326Sed break; 272193326Sed } 273193326Sed case Decl::CXXMethod: { 274193326Sed const CXXMethodDecl* D = cast<CXXMethodDecl>(DC); 275194613Sed if (D->isOutOfLine()) 276193326Sed Out << "[c++ method] "; 277193326Sed else if (D->isImplicit()) 278193326Sed Out << "(c++ method) "; 279193326Sed else 280193326Sed Out << "<c++ method> "; 281226633Sdim Out << *D; 282193326Sed // Print the parameters. 283193326Sed Out << "("; 284193326Sed bool PrintComma = false; 285198092Srdivacky for (FunctionDecl::param_const_iterator I = D->param_begin(), 286193326Sed E = D->param_end(); I != E; ++I) { 287193326Sed if (PrintComma) 288193326Sed Out << ", "; 289193326Sed else 290193326Sed PrintComma = true; 291226633Sdim Out << **I; 292193326Sed } 293193326Sed Out << ")"; 294193326Sed 295193326Sed // Check the semantic DeclContext. 296193326Sed const DeclContext* SemaDC = D->getDeclContext(); 297193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 298193326Sed if (SemaDC != LexicalDC) 299193326Sed Out << " [[" << SemaDC << "]]"; 300193326Sed 301193326Sed break; 302193326Sed } 303193326Sed case Decl::CXXConstructor: { 304193326Sed const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC); 305194613Sed if (D->isOutOfLine()) 306193326Sed Out << "[c++ ctor] "; 307193326Sed else if (D->isImplicit()) 308193326Sed Out << "(c++ ctor) "; 309193326Sed else 310193326Sed Out << "<c++ ctor> "; 311226633Sdim Out << *D; 312193326Sed // Print the parameters. 313193326Sed Out << "("; 314193326Sed bool PrintComma = false; 315198092Srdivacky for (FunctionDecl::param_const_iterator I = D->param_begin(), 316193326Sed E = D->param_end(); I != E; ++I) { 317193326Sed if (PrintComma) 318193326Sed Out << ", "; 319193326Sed else 320193326Sed PrintComma = true; 321226633Sdim Out << **I; 322193326Sed } 323193326Sed Out << ")"; 324193326Sed 325193326Sed // Check the semantic DC. 326193326Sed const DeclContext* SemaDC = D->getDeclContext(); 327193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 328193326Sed if (SemaDC != LexicalDC) 329193326Sed Out << " [[" << SemaDC << "]]"; 330193326Sed break; 331193326Sed } 332193326Sed case Decl::CXXDestructor: { 333193326Sed const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC); 334194613Sed if (D->isOutOfLine()) 335193326Sed Out << "[c++ dtor] "; 336193326Sed else if (D->isImplicit()) 337193326Sed Out << "(c++ dtor) "; 338193326Sed else 339193326Sed Out << "<c++ dtor> "; 340226633Sdim Out << *D; 341193326Sed // Check the semantic DC. 342193326Sed const DeclContext* SemaDC = D->getDeclContext(); 343193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 344193326Sed if (SemaDC != LexicalDC) 345193326Sed Out << " [[" << SemaDC << "]]"; 346193326Sed break; 347193326Sed } 348193326Sed case Decl::CXXConversion: { 349193326Sed const CXXConversionDecl* D = cast<CXXConversionDecl>(DC); 350194613Sed if (D->isOutOfLine()) 351193326Sed Out << "[c++ conversion] "; 352193326Sed else if (D->isImplicit()) 353193326Sed Out << "(c++ conversion) "; 354193326Sed else 355193326Sed Out << "<c++ conversion> "; 356226633Sdim Out << *D; 357193326Sed // Check the semantic DC. 358193326Sed const DeclContext* SemaDC = D->getDeclContext(); 359193326Sed const DeclContext* LexicalDC = D->getLexicalDeclContext(); 360193326Sed if (SemaDC != LexicalDC) 361193326Sed Out << " [[" << SemaDC << "]]"; 362193326Sed break; 363193326Sed } 364193326Sed 365193326Sed default: 366226633Sdim llvm_unreachable("a decl that inherits DeclContext isn't handled"); 367193326Sed } 368193326Sed 369193326Sed Out << "\n"; 370193326Sed 371193326Sed // Print decls in the DeclContext. 372195341Sed for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 373193326Sed I != E; ++I) { 374193326Sed for (unsigned i = 0; i < Indentation; ++i) 375193326Sed Out << " "; 376193326Sed 377193326Sed Decl::Kind DK = I->getKind(); 378193326Sed switch (DK) { 379193326Sed case Decl::Namespace: 380193326Sed case Decl::Enum: 381193326Sed case Decl::Record: 382193326Sed case Decl::CXXRecord: 383193326Sed case Decl::ObjCMethod: 384193326Sed case Decl::ObjCInterface: 385198092Srdivacky case Decl::ObjCCategory: 386193326Sed case Decl::ObjCProtocol: 387193326Sed case Decl::ObjCImplementation: 388193326Sed case Decl::ObjCCategoryImpl: 389193326Sed case Decl::LinkageSpec: 390193326Sed case Decl::Block: 391193326Sed case Decl::Function: 392193326Sed case Decl::CXXMethod: 393193326Sed case Decl::CXXConstructor: 394193326Sed case Decl::CXXDestructor: 395193326Sed case Decl::CXXConversion: 396193326Sed { 397193326Sed DeclContext* DC = cast<DeclContext>(*I); 398193326Sed PrintDeclContext(DC, Indentation+2); 399193326Sed break; 400193326Sed } 401218893Sdim case Decl::IndirectField: { 402218893Sdim IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(*I); 403226633Sdim Out << "<IndirectField> " << *IFD << '\n'; 404218893Sdim break; 405218893Sdim } 406218893Sdim case Decl::Label: { 407218893Sdim LabelDecl *LD = cast<LabelDecl>(*I); 408226633Sdim Out << "<Label> " << *LD << '\n'; 409218893Sdim break; 410218893Sdim } 411193326Sed case Decl::Field: { 412218893Sdim FieldDecl *FD = cast<FieldDecl>(*I); 413226633Sdim Out << "<field> " << *FD << '\n'; 414193326Sed break; 415193326Sed } 416221345Sdim case Decl::Typedef: 417221345Sdim case Decl::TypeAlias: { 418221345Sdim TypedefNameDecl* TD = cast<TypedefNameDecl>(*I); 419226633Sdim Out << "<typedef> " << *TD << '\n'; 420193326Sed break; 421193326Sed } 422193326Sed case Decl::EnumConstant: { 423193326Sed EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I); 424226633Sdim Out << "<enum constant> " << *ECD << '\n'; 425193326Sed break; 426193326Sed } 427193326Sed case Decl::Var: { 428193326Sed VarDecl* VD = cast<VarDecl>(*I); 429226633Sdim Out << "<var> " << *VD << '\n'; 430193326Sed break; 431193326Sed } 432193326Sed case Decl::ImplicitParam: { 433193326Sed ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I); 434226633Sdim Out << "<implicit parameter> " << *IPD << '\n'; 435193326Sed break; 436193326Sed } 437193326Sed case Decl::ParmVar: { 438193326Sed ParmVarDecl* PVD = cast<ParmVarDecl>(*I); 439226633Sdim Out << "<parameter> " << *PVD << '\n'; 440193326Sed break; 441193326Sed } 442193326Sed case Decl::ObjCProperty: { 443193326Sed ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I); 444226633Sdim Out << "<objc property> " << *OPD << '\n'; 445193326Sed break; 446193326Sed } 447200583Srdivacky case Decl::FunctionTemplate: { 448200583Srdivacky FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I); 449226633Sdim Out << "<function template> " << *FTD << '\n'; 450200583Srdivacky break; 451200583Srdivacky } 452202379Srdivacky case Decl::FileScopeAsm: { 453202379Srdivacky Out << "<file-scope asm>\n"; 454202379Srdivacky break; 455202379Srdivacky } 456202379Srdivacky case Decl::UsingDirective: { 457202379Srdivacky Out << "<using directive>\n"; 458202379Srdivacky break; 459202379Srdivacky } 460202379Srdivacky case Decl::NamespaceAlias: { 461202379Srdivacky NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I); 462226633Sdim Out << "<namespace alias> " << *NAD << '\n'; 463202379Srdivacky break; 464202379Srdivacky } 465202879Srdivacky case Decl::ClassTemplate: { 466202879Srdivacky ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I); 467226633Sdim Out << "<class template> " << *CTD << '\n'; 468202879Srdivacky break; 469202879Srdivacky } 470249423Sdim case Decl::OMPThreadPrivate: { 471249423Sdim Out << "<omp threadprivate> " << '"' << *I << "\"\n"; 472249423Sdim break; 473249423Sdim } 474193326Sed default: 475207619Srdivacky Out << "DeclKind: " << DK << '"' << *I << "\"\n"; 476226633Sdim llvm_unreachable("decl unhandled"); 477193326Sed } 478193326Sed } 479193326Sed} 480198092SrdivackyASTConsumer *clang::CreateDeclContextPrinter() { 481198092Srdivacky return new DeclContextPrinter(); 482193326Sed} 483