From e34a052d642ba7830174b1a51787251d7f704f80 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Thu, 26 Jul 2012 16:01:23 +0000 Subject: [PATCH] Added -ast-dump-filter option to clang -cc1. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160784 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclBase.h | 5 +- include/clang/Driver/CC1Options.td | 4 ++ include/clang/Frontend/ASTConsumers.h | 4 +- include/clang/Frontend/FrontendOptions.h | 3 + lib/AST/DeclPrinter.cpp | 6 +- lib/AST/DumpXML.cpp | 5 -- lib/Frontend/ASTConsumers.cpp | 76 ++++++++++++++++++------ lib/Frontend/CompilerInvocation.cpp | 3 + lib/Frontend/FrontendActions.cpp | 4 +- 9 files changed, 79 insertions(+), 31 deletions(-) diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index b1f9180e05..b304f1ff3e 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -857,9 +857,8 @@ public: static void printGroup(Decl** Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); - LLVM_ATTRIBUTE_USED void dump() const; - LLVM_ATTRIBUTE_USED void dumpXML() const; - void dumpXML(raw_ostream &OS) const; + LLVM_ATTRIBUTE_USED void dump(raw_ostream &Out = llvm::errs()) const; + LLVM_ATTRIBUTE_USED void dumpXML(raw_ostream &OS = llvm::errs()) const; private: void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 8fd3166ebe..48d143d2e1 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -286,6 +286,10 @@ def resource_dir : Separate<"-resource-dir">, HelpText<"The directory which holds the compiler resource files">; def version : Flag<"-version">, HelpText<"Print the compiler version">; +def ast_dump_filter : Separate<"-ast-dump-filter">, + MetaVarName<"">, + HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration" + " nodes having a certain substring in a qualified name.">; let Group = Action_Group in { diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h index cef9509a97..eebdfb8dc2 100644 --- a/include/clang/Frontend/ASTConsumers.h +++ b/include/clang/Frontend/ASTConsumers.h @@ -33,11 +33,11 @@ class TargetOptions; // original C code. The output is intended to be in a format such that // clang could re-parse the output back into the same AST, but the // implementation is still incomplete. -ASTConsumer *CreateASTPrinter(raw_ostream *OS); +ASTConsumer *CreateASTPrinter(raw_ostream *OS, StringRef FilterString); // AST dumper: dumps the raw AST in human-readable form to stderr; this is // intended for debugging. -ASTConsumer *CreateASTDumper(); +ASTConsumer *CreateASTDumper(StringRef FilterString); // AST XML-dumper: dumps out the AST to stderr in a very detailed XML // format; this is intended for particularly intense debugging. diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 22cce9cc37..5d674caca5 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -141,6 +141,9 @@ public: /// If given, the new suffix for fix-it rewritten files. std::string FixItSuffix; + /// If given, filter dumped AST Decl nodes by this substring. + std::string ASTDumpFilter; + /// If given, enable code completion at the provided location. ParsedSourceLocation CodeCompletionAt; diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 10f38942a5..fe8f8298be 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -173,8 +173,10 @@ void DeclContext::dumpDeclContext() const { Printer.VisitDeclContext(const_cast(this), /*Indent=*/false); } -void Decl::dump() const { - print(llvm::errs()); +void Decl::dump(raw_ostream &Out) const { + PrintingPolicy Policy = getASTContext().getPrintingPolicy(); + Policy.Dump = true; + print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ true); } raw_ostream& DeclPrinter::Indent(unsigned Indentation) { diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp index c5b3c6875b..ad551ccf0a 100644 --- a/lib/AST/DumpXML.cpp +++ b/lib/AST/DumpXML.cpp @@ -1022,17 +1022,12 @@ struct XMLDumper : public XMLDeclVisitor, }; } -void Decl::dumpXML() const { - dumpXML(llvm::errs()); -} - void Decl::dumpXML(raw_ostream &out) const { XMLDumper(out, getASTContext()).dispatch(const_cast(this)); } #else /* ifndef NDEBUG */ -void Decl::dumpXML() const {} void Decl::dumpXML(raw_ostream &out) const {} #endif diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp index 390ae09497..80f94397aa 100644 --- a/lib/Frontend/ASTConsumers.cpp +++ b/lib/Frontend/ASTConsumers.cpp @@ -12,47 +12,89 @@ //===----------------------------------------------------------------------===// #include "clang/Frontend/ASTConsumers.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" -#include "clang/Basic/FileManager.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/RecordLayout.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "llvm/Module.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Timer.h" using namespace clang; //===----------------------------------------------------------------------===// /// ASTPrinter - Pretty-printer and dumper of ASTs namespace { - class ASTPrinter : public ASTConsumer { - raw_ostream &Out; - bool Dump; + class ASTPrinter : public ASTConsumer, + public RecursiveASTVisitor { + typedef RecursiveASTVisitor base; public: - ASTPrinter(raw_ostream* o = NULL, bool Dump = false) - : Out(o? *o : llvm::outs()), Dump(Dump) { } + ASTPrinter(raw_ostream *Out = NULL, bool Dump = false, + StringRef FilterString = "") + : Out(Out ? *Out : llvm::outs()), Dump(Dump), + FilterString(FilterString) {} virtual void HandleTranslationUnit(ASTContext &Context) { - PrintingPolicy Policy = Context.getPrintingPolicy(); - Policy.Dump = Dump; - Context.getTranslationUnitDecl()->print(Out, Policy, /*Indentation=*/0, - /*PrintInstantiation=*/true); + TranslationUnitDecl *D = Context.getTranslationUnitDecl(); + + if (FilterString.empty()) { + if (Dump) + D->dump(Out); + else + D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true); + return; + } + + TraverseDecl(D); + } + + bool shouldWalkTypesOfTypeLocs() const { return false; } + + bool TraverseDecl(Decl *D) { + if (filterMatches(D)) { + Out.changeColor(llvm::raw_ostream::BLUE) << + (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n"; + Out.resetColor(); + if (Dump) + D->dump(Out); + else + D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true); + // Don't traverse child nodes to avoid output duplication. + return true; + } + return base::TraverseDecl(D); + } + + private: + std::string getName(Decl *D) { + if (isa(D)) + return cast(D)->getQualifiedNameAsString(); + return ""; + } + bool filterMatches(Decl *D) { + return getName(D).find(FilterString) != std::string::npos; } + + raw_ostream &Out; + bool Dump; + std::string FilterString; }; } // end anonymous namespace -ASTConsumer *clang::CreateASTPrinter(raw_ostream* out) { - return new ASTPrinter(out); +ASTConsumer *clang::CreateASTPrinter(raw_ostream *Out, + StringRef FilterString) { + return new ASTPrinter(Out, /*Dump=*/ false, FilterString); } -ASTConsumer *clang::CreateASTDumper() { - return new ASTPrinter(0, true); +ASTConsumer *clang::CreateASTDumper(StringRef FilterString) { + return new ASTPrinter(0, /*Dump=*/ true, FilterString); } //===----------------------------------------------------------------------===// diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 5fa01d3719..ea735ed122 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -558,6 +558,8 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts, ToArgsList &Res) { for(unsigned i = 0, e = Opts.PluginArgs.size(); i != e; ++i) Res.push_back("-plugin-arg-" + Opts.ActionName, Opts.PluginArgs[i]); } + if (!Opts.ASTDumpFilter.empty()) + Res.push_back("-ast-dump-filter", Opts.ASTDumpFilter); for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i) Res.push_back("-load", Opts.Plugins[i]); for (unsigned i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) { @@ -1542,6 +1544,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings); Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile); Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp); + Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter); Opts.CodeCompleteOpts.IncludeMacros = Args.hasArg(OPT_code_completion_macros); diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index b699ae8279..ffd3d90729 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -47,13 +47,13 @@ void InitOnlyAction::ExecuteAction() { ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) - return CreateASTPrinter(OS); + return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter); return 0; } ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - return CreateASTDumper(); + return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter); } ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI, -- 2.40.0