Add an option, -ast-dump-no-include, to clang and clang-check. Usage example:

clang++ -Xclang -ast-dump -Xclang -ast-dump-no-include -fsyntax-only test.cpp

clang-check -ast-print -ast-dump-no-include test.cpp

This option work with -ast-dump, -ast-dump-lookups or -ast-print to not show decls from included headers. This can be useful if you don't want decls from headers mess up ast-dump outputs.

>From 45664657b1bcfedea3db1a3b187829c4028b1f00 Mon Sep 17 00:00:00 2001
From: Li Jinpei <leekingp1...@gmail.com>
Date: Sun, 13 Aug 2017 18:51:57 +0800
Subject: [PATCH] add -ast-dump-no-include option
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.14.1"

This is a multi-part message in MIME format.
--------------2.14.1
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit

---
 include/clang/Driver/CC1Options.td            |  3 ++
 include/clang/Frontend/ASTConsumers.h         |  6 ++-
 include/clang/Frontend/FrontendOptions.h      |  2 +
 lib/Frontend/ASTConsumers.cpp                 | 63 +++++++++++++++++----------
 lib/Frontend/CompilerInvocation.cpp           |  1 +
 lib/Frontend/FrontendActions.cpp              |  6 ++-
 tools/clang-check/ClangCheck.cpp              |  9 +++-
 tools/clang-import-test/clang-import-test.cpp |  2 +-
 8 files changed, 62 insertions(+), 30 deletions(-)


--------------2.14.1
Content-Type: text/x-patch; name="0001-add-ast-dump-no-include-option.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-add-ast-dump-no-include-option.patch"

diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 912abd9d48..275698d806 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -432,6 +432,9 @@ def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
   HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
            " nodes having a certain substring in a qualified name. Use"
            " -ast-list to list all filterable declaration node names.">;
+def ast_dump_no_include : Flag<["-"], "ast-dump-no-include">,
+  HelpText<"Use with -ast-dump, -ast-dump-lookups or -ast-print,"
+    " not show decls included from headers when dumping ASTs">;
 def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
   HelpText<"Do not automatically generate or update the global module index">;
 def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">,
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 53975a07ea..0f39f1a8a1 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -32,13 +32,15 @@ class TargetOptions;
 // clang could re-parse the output back into the same AST, but the
 // implementation is still incomplete.
 std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS,
-                                              StringRef FilterString);
+                                              StringRef FilterString,
+                                              bool NoInclude = false);
 
 // AST dumper: dumps the raw AST in human-readable form to stderr; this is
 // intended for debugging.
 std::unique_ptr<ASTConsumer> CreateASTDumper(StringRef FilterString,
                                              bool DumpDecls, bool Deserialize,
-                                             bool DumpLookups);
+                                             bool DumpLookups,
+                                             bool NoInclude = false);
 
 // AST Decl node lister: prints qualified names of all filterable AST Decl
 // nodes.
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index e757a7e397..f31f4d842f 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -196,6 +196,8 @@ public:
                                            ///< when forming AST dumps.
   unsigned ASTDumpLookups : 1;             ///< Whether we include lookup table
                                            ///< dumps in AST dumps.
+  unsigned ASTDumpNoInclude : 1;           ///< Whether not to include decls
+                                           ///< from included headers in AST dumps.
   unsigned BuildingImplicitModule : 1;     ///< Whether we are performing an
                                            ///< implicit module build.
   unsigned ModulesEmbedAllFiles : 1;       ///< Whether we should embed all used
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 7dc475e26f..8dfd53913b 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -35,19 +35,25 @@ namespace {
 
   public:
     enum Kind { DumpFull, Dump, Print, None };
-    ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, StringRef FilterString,
-               bool DumpLookups = false)
-        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
-          OutputKind(K), FilterString(FilterString), DumpLookups(DumpLookups) {}
-
-    void HandleTranslationUnit(ASTContext &Context) override {
-      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
-
-      if (FilterString.empty())
-        return print(D);
-
-      TraverseDecl(D);
+  ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, StringRef FilterString,
+             bool DumpLookups = false, bool NoInclude = false)
+      : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), OutputKind(K),
+        FilterString(FilterString), DumpLookups(DumpLookups),
+        NoInclude(NoInclude) {}
+
+  void HandleTranslationUnit(ASTContext &Context) override {
+    TranslationUnitDecl *D = Context.getTranslationUnitDecl();
+    if (!NoInclude)
+      printTopLevelDecl(D);
+    else {
+      const SourceManager &SM = Context.getSourceManager();
+      for (auto db = D->decls_begin(), de = D->decls_end(); db != de; ++db) {
+        if (SM.isWrittenInMainFile(db->getLocation())) {
+          printTopLevelDecl(*db);
+        }
+      }
     }
+  }
 
     bool shouldWalkTypesOfTypeLocs() const { return false; }
 
@@ -77,6 +83,12 @@ namespace {
     bool filterMatches(Decl *D) {
       return getName(D).find(FilterString) != std::string::npos;
     }
+    void printTopLevelDecl(Decl *D) {
+      if (FilterString.empty())
+        return print(D);
+
+      TraverseDecl(D);
+    }
     void print(Decl *D) {
       if (DumpLookups) {
         if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
@@ -106,6 +118,12 @@ namespace {
     /// results will be output with a format determined by OutputKind. This is
     /// incompatible with OutputKind == Print.
     bool DumpLookups;
+
+    /// Whether not to show decls from included header files. At the top level,
+    /// TranslationUnitDecl contains decls decls whose lexical source locations
+    /// are at the file you give at command line, or included from header files.
+    /// This options can filter out decls based on source location.
+    bool NoInclude;
   };
 
   class ASTDeclNodeLister : public ASTConsumer,
@@ -133,21 +151,20 @@ namespace {
 
 std::unique_ptr<ASTConsumer>
 clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
-                        StringRef FilterString) {
+                        StringRef FilterString, bool NoInclude) {
   return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
-                                       FilterString);
+                                       FilterString, false, NoInclude);
 }
 
-std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,
-                                                    bool DumpDecls,
-                                                    bool Deserialize,
-                                                    bool DumpLookups) {
+std::unique_ptr<ASTConsumer>
+clang::CreateASTDumper(StringRef FilterString, bool DumpDecls, bool Deserialize,
+                       bool DumpLookups, bool NoInclude) {
   assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
-  return llvm::make_unique<ASTPrinter>(nullptr,
-                                       Deserialize ? ASTPrinter::DumpFull :
-                                       DumpDecls ? ASTPrinter::Dump :
-                                       ASTPrinter::None,
-                                       FilterString, DumpLookups);
+  return llvm::make_unique<ASTPrinter>(
+      nullptr,
+      Deserialize ? ASTPrinter::DumpFull
+                  : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,
+      FilterString, DumpLookups, NoInclude);
 }
 
 std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index a3473e4f22..622b34a3c4 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1305,6 +1305,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
   Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all);
   Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter);
   Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups);
+  Opts.ASTDumpNoInclude = Args.hasArg(OPT_ast_dump_no_include);
   Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
   Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
   Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index d42400183a..5e79c97d64 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -49,7 +49,8 @@ std::unique_ptr<ASTConsumer>
 ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   if (std::unique_ptr<raw_ostream> OS =
           CI.createDefaultOutputFile(false, InFile))
-    return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
+    return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter,
+                            CI.getFrontendOpts().ASTDumpNoInclude);
   return nullptr;
 }
 
@@ -58,7 +59,8 @@ ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter,
                          CI.getFrontendOpts().ASTDumpDecls,
                          CI.getFrontendOpts().ASTDumpAll,
-                         CI.getFrontendOpts().ASTDumpLookups);
+                         CI.getFrontendOpts().ASTDumpLookups,
+                         CI.getFrontendOpts().ASTDumpNoInclude);
 }
 
 std::unique_ptr<ASTConsumer>
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index e190c0721a..bd0d2dff92 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -68,6 +68,10 @@ static cl::opt<std::string> ASTDumpFilter(
     "ast-dump-filter",
     cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)),
     cl::cat(ClangCheckCategory));
+static cl::opt<bool> ASTDumpNoInclude(
+    "ast-dump-no-include",
+    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_no_include)),
+    cl::cat(ClangCheckCategory));
 static cl::opt<bool>
 Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)),
         cl::cat(ClangCheckCategory));
@@ -140,9 +144,10 @@ public:
     if (ASTDump)
       return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
                                     /*Deserialize=*/false,
-                                    /*DumpLookups=*/false);
+                                    /*DumpLookups=*/false,
+                                    /*NoInclude=*/ASTDumpNoInclude);
     if (ASTPrint)
-      return clang::CreateASTPrinter(nullptr, ASTDumpFilter);
+      return clang::CreateASTPrinter(nullptr, ASTDumpFilter, ASTDumpNoInclude);
     return llvm::make_unique<clang::ASTConsumer>();
   }
 };
diff --git a/tools/clang-import-test/clang-import-test.cpp b/tools/clang-import-test/clang-import-test.cpp
index 186a7c82dc..32583dd94d 100644
--- a/tools/clang-import-test/clang-import-test.cpp
+++ b/tools/clang-import-test/clang-import-test.cpp
@@ -287,7 +287,7 @@ Parse(const std::string &Path,
   auto &CG = *static_cast<CodeGenerator*>(ASTConsumers.back().get());
 
   if (ShouldDumpAST)
-    ASTConsumers.push_back(CreateASTDumper("", true, false, false));
+    ASTConsumers.push_back(CreateASTDumper("", true, false, false, false));
 
   CI->getDiagnosticClient().BeginSourceFile(CI->getLangOpts(),
                                             &CI->getPreprocessor());

--------------2.14.1--


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to