summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/ClangASTContext.h8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp17
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp33
-rw-r--r--lldb/tools/lldb-test/lldb-test.cpp46
4 files changed, 97 insertions, 7 deletions
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h
index 92d8985f446..c5d840973ae 100644
--- a/lldb/include/lldb/Symbol/ClangASTContext.h
+++ b/lldb/include/lldb/Symbol/ClangASTContext.h
@@ -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,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 863cf2c1f0d..7d96e324ff9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3024,12 +3024,21 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
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) {
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index a1637ca7baa..b37346814bf 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -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,
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index 426b12acd40..5c5d793466e 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/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>
@@ -168,6 +169,10 @@ static FunctionNameType getFunctionNameFlags() {
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::Module &Module);
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_private::Module &Module) {
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_private::Module &Module) {
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_private::Module &Module) {
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 &)> opts::symbols::getAction() {
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.");
OpenPOWER on IntegriCloud