[Lldb-commits] [lldb] r374570 - [lldb-test] Modify lldb-test to print out ASTs from symbol file

Shafik Yaghmour via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 11 09:36:20 PDT 2019


Author: shafik
Date: Fri Oct 11 09:36:20 2019
New Revision: 374570

URL: http://llvm.org/viewvc/llvm-project?rev=374570&view=rev
Log:
[lldb-test] Modify lldb-test to print out ASTs from symbol file

Summary:
Currently when invoking lldb-test symbols -dump-ast it parses all the debug symbols and calls print(...) on the TranslationUnitDecl.
While useful the TranslationUnitDecl::print(...) method gives us a higher level view then the dump from ASTDumper which is what we get when we invoke dump() on a specific AST node.
The main motivation for this change is allow us to verify that the AST nodes we create when we parse DWARF. For example in order to verify we are correctly using DIFlagExportSymbols added by D66667

Differential Revision: https://reviews.llvm.org/D67994

Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/tools/lldb-test/lldb-test.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=374570&r1=374569&r2=374570&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Oct 11 09:36:20 2019
@@ -886,6 +886,14 @@ public:
 
   void Dump(Stream &s);
 
+  /// Dump clang AST types from the symbol file.
+  ///
+  /// \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 DumpFromSymbolFile(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,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=374570&r1=374569&r2=374570&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Oct 11 09:36:20 2019
@@ -3024,12 +3024,21 @@ size_t SymbolFileDWARF::ParseTypes(const
                                    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);
+
+    // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
+    // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
+    // not.
+    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) {

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=374570&r1=374569&r2=374570&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Oct 11 09:36:20 2019
@@ -8973,6 +8973,39 @@ void ClangASTContext::Dump(Stream &s) {
   tu->dump(s.AsRawOstream());
 }
 
+void ClangASTContext::DumpFromSymbolFile(Stream &s,
+                                         llvm::StringRef symbol_name) {
+  SymbolFile *symfile = GetSymbolFile();
+
+  if (!symfile)
+    return;
+
+  lldb_private::TypeList type_list;
+  symfile->GetTypes(nullptr, eTypeClassAny, type_list);
+  size_t ntypes = type_list.GetSize();
+
+  for (size_t i = 0; i < ntypes; ++i) {
+    TypeSP type = type_list.GetTypeAtIndex(i);
+
+    if (!symbol_name.empty())
+      if (symbol_name.compare(type->GetName().GetStringRef()) != 0)
+        continue;
+
+    s << type->GetName().AsCString() << "\n";
+
+    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 {
+      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,

Modified: lldb/trunk/tools/lldb-test/lldb-test.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/lldb-test.cpp?rev=374570&r1=374569&r2=374570&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/lldb-test.cpp (original)
+++ lldb/trunk/tools/lldb-test/lldb-test.cpp Fri Oct 11 09:36:20 2019
@@ -42,6 +42,7 @@
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/WithColor.h"
+
 #include <cstdio>
 #include <thread>
 
@@ -168,6 +169,10 @@ static FunctionNameType getFunctionNameF
 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<bool> Verify("verify", cl::desc("Verify symbol information."),
                             cl::sub(SymbolsSubcommand));
@@ -187,6 +192,7 @@ static Error findTypes(lldb_private::Mod
 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();
@@ -580,11 +586,11 @@ Error opts::symbols::dumpModule(lldb_pri
 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");
@@ -598,7 +604,7 @@ Error opts::symbols::dumpAST(lldb_privat
   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.");
 
@@ -607,6 +613,30 @@ Error opts::symbols::dumpAST(lldb_privat
   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->DumpFromSymbolFile(Stream, Name);
+  outs() << Stream.GetData() << "\n";
+
+  return Error::success();
+}
+
 Error opts::symbols::verify(lldb_private::Module &Module) {
   SymbolFile *symfile = Module.GetSymbolFile();
   if (!symfile)
@@ -685,6 +715,16 @@ Expected<Error (*)(lldb_private::Module
     return dumpAST;
   }
 
+  if (DumpClangAST) {
+    if (Find != FindType::None)
+      return make_string_error("Cannot both search and dump clang AST.");
+    if (Regex || !Context.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.");




More information about the lldb-commits mailing list