shafik updated this revision to Diff 222861.
shafik retitled this revision from "[WIP] Modify lldb-test to print out ASTs 
from symbol file" to "Modify lldb-test to print out ASTs from symbol file".
shafik added a comment.

- Updated approach based on comment
- Pushed clang ast manipulation into `ClangASTContext.cpp`
- Created a new option in lldb-test to keep the new functionality separate from 
the old use called `dumpClangAST`
- Cleaned up checking DWARF type by using `isType()`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67994/new/

https://reviews.llvm.org/D67994

Files:
  include/lldb/Symbol/ClangASTContext.h
  source/Core/Module.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Symbol/ClangASTContext.cpp
  tools/lldb-test/lldb-test.cpp

Index: tools/lldb-test/lldb-test.cpp
===================================================================
--- tools/lldb-test/lldb-test.cpp
+++ tools/lldb-test/lldb-test.cpp
@@ -42,6 +42,7 @@
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/WithColor.h"
+
 #include <cstdio>
 #include <thread>
 
@@ -159,6 +160,13 @@
 static cl::opt<bool> DumpAST("dump-ast",
                              cl::desc("Dump AST restored from symbols."),
                              cl::sub(SymbolsSubcommand));
+static cl::opt<bool>
+    DumpClangAST("dump-clang-ast",
+                 cl::desc("Dump clang AST restored from symbols."),
+                 cl::sub(SymbolsSubcommand));
+static cl::opt<std::string>
+    SymbolName("symbol-name", cl::desc("Symbol to dump complete AST for"),
+               cl::sub(SymbolsSubcommand));
 
 static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
                             cl::sub(SymbolsSubcommand));
@@ -178,6 +186,7 @@
 static Error findVariables(lldb_private::Module &Module);
 static Error dumpModule(lldb_private::Module &Module);
 static Error dumpAST(lldb_private::Module &Module);
+static Error dumpClangAST(lldb_private::Module &Module);
 static Error verify(lldb_private::Module &Module);
 
 static Expected<Error (*)(lldb_private::Module &)> getAction();
@@ -524,11 +533,11 @@
 Error opts::symbols::dumpAST(lldb_private::Module &Module) {
   Module.ParseAllDebugSymbols();
 
-  auto symfile = Module.GetSymbolFile();
+  SymbolFile *symfile = Module.GetSymbolFile();
   if (!symfile)
     return make_string_error("Module has no symbol file.");
 
-  auto type_system_or_err =
+  llvm::Expected<TypeSystem &> type_system_or_err =
       symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
   if (!type_system_or_err)
     return make_string_error("Can't retrieve ClangASTContext");
@@ -542,7 +551,7 @@
   if (!ast_ctx)
     return make_string_error("Can't retrieve AST context.");
 
-  auto tu = ast_ctx->getTranslationUnitDecl();
+  clang::TranslationUnitDecl *tu = ast_ctx->getTranslationUnitDecl();
   if (!tu)
     return make_string_error("Can't retrieve translation unit declaration.");
 
@@ -551,6 +560,30 @@
   return Error::success();
 }
 
+Error opts::symbols::dumpClangAST(lldb_private::Module &Module) {
+  Module.ParseAllDebugSymbols();
+
+  SymbolFile *symfile = Module.GetSymbolFile();
+  if (!symfile)
+    return make_string_error("Module has no symbol file.");
+
+  llvm::Expected<TypeSystem &> type_system_or_err =
+      symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+  if (!type_system_or_err)
+    return make_string_error("Can't retrieve ClangASTContext");
+
+  auto *clang_ast_ctx =
+      llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+  if (!clang_ast_ctx)
+    return make_string_error("Retrieved TypeSystem was not a ClangASTContext");
+
+  StreamString Stream;
+  clang_ast_ctx->DumpFromSymbols(Stream, SymbolName);
+  outs() << Stream.GetData() << "\n";
+
+  return Error::success();
+}
+
 Error opts::symbols::verify(lldb_private::Module &Module) {
   SymbolFile *symfile = Module.GetSymbolFile();
   if (!symfile)
@@ -629,6 +662,17 @@
     return dumpAST;
   }
 
+  if (DumpClangAST) {
+    if (Find != FindType::None)
+      return make_string_error("Cannot both search and dump clang AST.");
+    if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
+        Line != 0)
+      return make_string_error(
+          "-regex, -context, -name, -file and -line options are not "
+          "applicable for dumping clang AST.");
+    return dumpClangAST;
+  }
+
   if (Regex && !Context.empty())
     return make_string_error(
         "Cannot search using both regular expressions and context.");
Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -9163,6 +9163,43 @@
   tu->dump(s.AsRawOstream());
 }
 
+void ClangASTContext::DumpFromSymbols(Stream &s, llvm::StringRef symbol_name) {
+  SymbolFile *symfile = GetSymbolFile();
+
+  if (!symfile)
+    return;
+
+  lldb_private::TypeList type_list;
+  size_t ntypes = symfile->GetTypes(nullptr, eTypeClassAny, type_list);
+
+  for (size_t i = 0; i < ntypes; ++i) {
+    auto type = type_list.GetTypeAtIndex(i);
+
+    if (!symbol_name.empty())
+      if (symbol_name.compare(type->GetName().AsCString()) != 0)
+        continue;
+
+    s << type->GetName().AsCString() << "\n";
+
+    if (clang::CXXRecordDecl *record_decl =
+            GetAsCXXRecordDecl(type->GetFullCompilerType().GetOpaqueQualType()))
+      record_decl->dump(s.AsRawOstream());
+    else if (clang::TagDecl *tag_decl =
+                 GetAsTagDecl(type->GetFullCompilerType()))
+      tag_decl->dump(s.AsRawOstream());
+    else if (clang::TypedefNameDecl *typedef_decl =
+                 GetAsTypedefDecl(type->GetFullCompilerType()))
+      typedef_decl->dump(s.AsRawOstream());
+    else if (clang::EnumDecl *enum_decl =
+                 GetAsEnumDecl(type->GetFullCompilerType()))
+      enum_decl->dump(s.AsRawOstream());
+    else {
+      GetCanonicalQualType(type->GetFullCompilerType().GetOpaqueQualType())
+          .dump(s.AsRawOstream());
+    }
+  }
+}
+
 void ClangASTContext::DumpValue(
     lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
     lldb::Format format, const DataExtractor &data,
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3049,12 +3049,18 @@
                                    bool parse_siblings, bool parse_children) {
   size_t types_added = 0;
   DWARFDIE die = orig_die;
+
   while (die) {
+    const dw_tag_t tag = die.Tag();
     bool type_is_new = false;
-    if (ParseType(sc, die, &type_is_new).get()) {
-      if (type_is_new)
-        ++types_added;
-    }
+
+    Tag dwarf_tag = static_cast<Tag>(tag);
+
+    if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
+      ParseType(sc, die, &type_is_new);
+
+    if (type_is_new)
+      ++types_added;
 
     if (parse_children && die.HasChildren()) {
       if (die.Tag() == DW_TAG_subprogram) {
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp
+++ source/Core/Module.cpp
@@ -374,7 +374,6 @@
       continue;
 
     symbols->ParseVariablesForContext(sc);
-
     symbols->ParseFunctions(*sc.comp_unit);
 
     sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {
Index: include/lldb/Symbol/ClangASTContext.h
===================================================================
--- include/lldb/Symbol/ClangASTContext.h
+++ include/lldb/Symbol/ClangASTContext.h
@@ -892,6 +892,14 @@
 
   void Dump(Stream &s);
 
+  /// Dump clang AST types from the symbol table
+  ///
+  /// \param[in] s
+  ///       A stream to send the dumped AST node(s) to
+  /// \param[in] symbol_name
+  ///       The name of the symbol to dump, if it is empty dump all the symbols
+  void DumpFromSymbols(Stream &s, llvm::StringRef symbol_name);
+
   void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
                  Stream *s, lldb::Format format, const DataExtractor &data,
                  lldb::offset_t data_offset, size_t data_byte_size,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to