diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 888250e599..8c98ed4ea6 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -534,6 +534,35 @@ namespace { ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); } +//===----------------------------------------------------------------------===// +/// InheritanceViewer - C++ Inheritance Visualization + +namespace { +class InheritanceViewer : public ASTConsumer { + const std::string clsname; +public: + InheritanceViewer(const std::string& cname) : clsname(cname) {} + + void HandleTranslationUnit(TranslationUnit& TU) { + ASTContext& C = TU.getContext(); + for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I) + if (CXXRecordType *T = dyn_cast(*I)) { + CXXRecordDecl* D = T->getDecl(); + // FIXME: This lookup needs to be generalized to handle namespaces and + // (when we support them) templates. + if (D->getName() == clsname) { + QualType QT(T, 0); + QT.viewInheritance(C); + } + } + } +}; +} + +ASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) { + return new InheritanceViewer(clsname); +} + //===----------------------------------------------------------------------===// // AST Serializer diff --git a/Driver/ASTConsumers.h b/Driver/ASTConsumers.h index bc76df5f53..97adfb30c8 100644 --- a/Driver/ASTConsumers.h +++ b/Driver/ASTConsumers.h @@ -70,6 +70,9 @@ ASTConsumer *CreateBlockRewriter(const std::string& InFile, const std::string& OutFile, Diagnostic &Diags, const LangOptions &LangOpts); + +ASTConsumer *CreateInheritanceViewer(const std::string& clsname); + } // end clang namespace #include "AnalysisConsumer.h" diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 6d3f0b3843..47d422dcbc 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -90,7 +90,8 @@ enum ProgActions { DumpTokens, // Dump out preprocessed tokens. DumpRawTokens, // Dump out raw tokens. RunAnalysis, // Run one or more source code analyses. - GeneratePCH // Generate precompiled header. + GeneratePCH, // Generate precompiled header. + InheritanceView // View C++ inheritance for a specified class. }; static llvm::cl::opt @@ -176,7 +177,16 @@ NoCaretDiagnostics("fno-caret-diagnostics", //===----------------------------------------------------------------------===// -// Analyzer Options +// C++ Visualization. +//===----------------------------------------------------------------------===// + +static llvm::cl::opt +InheritanceViewCls("cxx-inheritance-view", + llvm::cl::value_desc("class name"), + llvm::cl::desc("View C++ inhertance for a specified class")); + +//===----------------------------------------------------------------------===// +// Analyzer Options. //===----------------------------------------------------------------------===// static llvm::cl::opt @@ -1143,6 +1153,9 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, case EmitHTML: return CreateHTMLPrinter(OutputFile, Diag, PP, PPF); + case InheritanceView: + return CreateInheritanceViewer(InheritanceViewCls); + case TestSerialization: return CreateSerializationTest(Diag, FileMgr); @@ -1428,6 +1441,8 @@ int main(int argc, char **argv) { // Are we invoking one or more source analyses? if (!AnalysisList.empty() && ProgAction == ParseSyntaxOnly) ProgAction = RunAnalysis; + else if (!InheritanceViewCls.empty()) // C++ visualization? + ProgAction = InheritanceView; llvm::OwningPtr SourceMgr;