summaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile')
-rw-r--r--source/Plugins/SymbolFile/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.cpp55
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.h20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp733
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h62
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp42
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp555
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h90
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp80
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp75
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h18
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp11
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp75
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp22
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h13
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h16
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp15
-rw-r--r--source/Plugins/SymbolFile/DWARF/Makefile14
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp616
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h45
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp51
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h10
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h9
-rw-r--r--source/Plugins/SymbolFile/PDB/CMakeLists.txt7
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp237
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.h58
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp733
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h204
-rw-r--r--source/Plugins/SymbolFile/Symtab/Makefile14
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp3
38 files changed, 3152 insertions, 774 deletions
diff --git a/source/Plugins/SymbolFile/CMakeLists.txt b/source/Plugins/SymbolFile/CMakeLists.txt
index add6697389f97..98510704ce730 100644
--- a/source/Plugins/SymbolFile/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/CMakeLists.txt
@@ -1,2 +1,3 @@
add_subdirectory(DWARF)
add_subdirectory(Symtab)
+add_subdirectory(PDB)
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index b4658115dfeb8..ac69243b65c09 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -3,6 +3,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp
DWARFASTParserGo.cpp
+ DWARFASTParserJava.cpp
DWARFAttribute.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index c0754a1fdd542..5fe0cc4d416e1 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -10,26 +10,49 @@
#include "DIERef.h"
#include "DWARFCompileUnit.h"
#include "DWARFFormValue.h"
+#include "DWARFDebugInfo.h"
+#include "SymbolFileDWARF.h"
+#include "SymbolFileDWARFDebugMap.h"
DIERef::DIERef() :
cu_offset(DW_INVALID_OFFSET),
die_offset(DW_INVALID_OFFSET)
{}
-DIERef::DIERef(dw_offset_t d) :
- cu_offset(DW_INVALID_OFFSET),
- die_offset(d)
-{}
-
DIERef::DIERef(dw_offset_t c, dw_offset_t d) :
cu_offset(c),
die_offset(d)
{}
-DIERef::DIERef(lldb::user_id_t uid) :
- cu_offset(uid>>32),
+DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf) :
+ cu_offset(DW_INVALID_OFFSET),
die_offset(uid&0xffffffff)
-{}
+{
+ SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
+ if (debug_map)
+ {
+ const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
+ SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
+ if (actual_dwarf)
+ {
+ DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
+ if (debug_info)
+ {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIEOffset(die_offset);
+ if (dwarf_cu)
+ {
+ cu_offset = dwarf_cu->GetOffset();
+ return;
+ }
+ }
+ }
+ die_offset = DW_INVALID_OFFSET;
+ }
+ else
+ {
+ cu_offset = uid>>32;
+ }
+}
DIERef::DIERef(const DWARFFormValue& form_value) :
cu_offset(DW_INVALID_OFFSET),
@@ -50,7 +73,19 @@ DIERef::DIERef(const DWARFFormValue& form_value) :
}
lldb::user_id_t
-DIERef::GetUID() const
+DIERef::GetUID(SymbolFileDWARF *dwarf) const
{
- return ((lldb::user_id_t)cu_offset) << 32 | die_offset;
+ //----------------------------------------------------------------------
+ // Each SymbolFileDWARF will set its ID to what is expected.
+ //
+ // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
+ // ID set to the compile unit index.
+ //
+ // SymbolFileDWARFDwo sets the ID to the compile unit offset.
+ //----------------------------------------------------------------------
+ if (dwarf)
+ return dwarf->GetID() | die_offset;
+ else
+ return LLDB_INVALID_UID;
}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.h b/source/Plugins/SymbolFile/DWARF/DIERef.h
index 3df07d511749d..ad4ad45623a3d 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -14,24 +14,34 @@
#include "lldb/lldb-defines.h"
class DWARFFormValue;
+class SymbolFileDWARF;
struct DIERef
{
DIERef();
- explicit
- DIERef(dw_offset_t d);
-
DIERef(dw_offset_t c, dw_offset_t d);
+ //----------------------------------------------------------------------
+ // In order to properly decode a lldb::user_id_t back into a DIERef we
+ // need the DWARF file since it knows if DWARF in .o files is being used
+ // (MacOSX) or if DWO files are being used. The encoding of the user ID
+ // differs between the two types of DWARF.
+ //----------------------------------------------------------------------
explicit
- DIERef(lldb::user_id_t uid);
+ DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
explicit
DIERef(const DWARFFormValue& form_value);
+ //----------------------------------------------------------------------
+ // In order to properly encode a DIERef unto a lldb::user_id_t we need
+ // the DWARF file since it knows if DWARF in .o files is being used
+ // (MacOSX) or if DWO files are being used. The encoding of the user ID
+ // differs between the two types of DWARF.
+ //----------------------------------------------------------------------
lldb::user_id_t
- GetUID() const;
+ GetUID(SymbolFileDWARF *dwarf) const;
bool
operator< (const DIERef &ref) const
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index ab20844bfcfde..2fb360440f632 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -33,18 +33,6 @@ public:
const DWARFDIE &die) = 0;
virtual bool
- CanCompleteType (const lldb_private::CompilerType &compiler_type)
- {
- return false;
- }
-
- virtual bool
- CompleteType (const lldb_private::CompilerType &compiler_type)
- {
- return false;
- }
-
- virtual bool
CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) = 0;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 74b54d614aa25..23381df3297a8 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
@@ -18,14 +20,16 @@
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"
-#include "lldb/Interpreter/Args.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -33,7 +37,7 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/Language.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -97,9 +101,9 @@ struct BitfieldInfo
uint64_t bit_size;
uint64_t bit_offset;
- BitfieldInfo () :
- bit_size (LLDB_INVALID_ADDRESS),
- bit_offset (LLDB_INVALID_ADDRESS)
+ BitfieldInfo() :
+ bit_size(LLDB_INVALID_ADDRESS),
+ bit_offset(LLDB_INVALID_ADDRESS)
{
}
@@ -110,10 +114,28 @@ struct BitfieldInfo
bit_offset = LLDB_INVALID_ADDRESS;
}
- bool IsValid ()
+ bool
+ IsValid() const
{
return (bit_size != LLDB_INVALID_ADDRESS) &&
- (bit_offset != LLDB_INVALID_ADDRESS);
+ (bit_offset != LLDB_INVALID_ADDRESS);
+ }
+
+ bool
+ NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const
+ {
+ if (IsValid())
+ {
+ // This bitfield info is valid, so any subsequent bitfields
+ // must not overlap and must be at a higher bit offset than
+ // any previous bitfield + size.
+ return (bit_size + bit_offset) <= next_bit_offset;
+ }
+ else
+ {
+ // If the this BitfieldInfo is not valid, then any offset isOK
+ return true;
+ }
}
};
@@ -252,11 +274,11 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
switch (tag)
{
+ case DW_TAG_typedef:
case DW_TAG_base_type:
case DW_TAG_pointer_type:
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
- case DW_TAG_typedef:
case DW_TAG_const_type:
case DW_TAG_restrict_type:
case DW_TAG_volatile_type:
@@ -267,7 +289,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
const size_t num_attributes = die.GetAttributes (attributes);
uint32_t encoding = 0;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+ DWARFFormValue encoding_uid;
if (num_attributes > 0)
{
@@ -297,7 +319,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_encoding: encoding = form_value.Unsigned(); break;
- case DW_AT_type: encoding_uid = DIERef(form_value).GetUID(); break;
+ case DW_AT_type: encoding_uid = form_value; break;
default:
case DW_AT_sibling:
break;
@@ -306,7 +328,43 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
}
}
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
+ if (tag == DW_TAG_typedef && encoding_uid.IsValid())
+ {
+ // Try to parse a typedef from the DWO file first as modules
+ // can contain typedef'ed structures that have no names like:
+ //
+ // typedef struct { int a; } Foo;
+ //
+ // In this case we will have a structure with no name and a
+ // typedef named "Foo" that points to this unnamed structure.
+ // The name in the typedef is the only identifier for the struct,
+ // so always try to get typedefs from DWO files if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't exist
+ // in a DWO file, so it is cheap to call this function just to check.
+ //
+ // If we don't do this we end up creating a TypeSP that says this
+ // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
+ // in the DW_TAG_typedef), and this is the unnamed structure type.
+ // We will have a hard time tracking down an unnammed structure
+ // type in the module DWO file, so we make sure we don't get into
+ // this situation by always resolving typedefs from the DWO file.
+ const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
+
+ // First make sure that the die that this is typedef'ed to _is_
+ // just a declaration (DW_AT_declaration == 1), not a full definition
+ // since template types can't be represented in modules since only
+ // concrete instances of templates are ever emitted and modules
+ // won't contain those
+ if (encoding_die && encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
+ {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+ }
+ }
+
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid.Reference());
switch (tag)
{
@@ -322,6 +380,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
break;
}
// Fall through to base type below in case we can handle the type there...
+ LLVM_FALLTHROUGH;
case DW_TAG_base_type:
resolve_state = Type::eResolveStateFull;
@@ -341,6 +400,44 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
{
+ if (tag == DW_TAG_pointer_type)
+ {
+ DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
+
+ if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0))
+ {
+ // Blocks have a __FuncPtr inside them which is a pointer to a function of the proper type.
+
+ for (DWARFDIE child_die = target_die.GetFirstChild();
+ child_die.IsValid();
+ child_die = child_die.GetSibling())
+ {
+ if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr"))
+ {
+ DWARFDIE function_pointer_type = child_die.GetReferencedDIE(DW_AT_type);
+
+ if (function_pointer_type)
+ {
+ DWARFDIE function_type = function_pointer_type.GetReferencedDIE(DW_AT_type);
+
+ bool function_type_is_new_pointer;
+ TypeSP lldb_function_type_sp = ParseTypeFromDWARF(sc, function_type, log, &function_type_is_new_pointer);
+
+ if (lldb_function_type_sp)
+ {
+ clang_type = m_ast.CreateBlockPointerType(lldb_function_type_sp->GetForwardCompilerType());
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
if (translation_unit_is_objc)
@@ -361,7 +458,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
@@ -375,7 +472,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
else if (type_name_const_str == g_objc_type_name_selector)
@@ -388,15 +485,15 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
}
- else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
+ else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid.IsValid())
{
// Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
- const DWARFDIE encoding_die = die.GetDIE(encoding_uid);
+ const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type)
{
@@ -412,7 +509,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
}
@@ -426,7 +523,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_const_str,
byte_size,
NULL,
- encoding_uid,
+ DIERef(encoding_uid).GetUID(dwarf),
encoding_data_type,
&decl,
clang_type,
@@ -532,43 +629,32 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// and clang isn't good and sharing the stack space for variables in different blocks.
std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
+ ConstString unique_typename(type_name_const_str);
+ Declaration unique_decl(decl);
+
if (type_name_const_str)
{
LanguageType die_language = die.GetLanguage();
- bool handled = false;
if (Language::LanguageIsCPlusPlus(die_language))
{
+ // For C++, we rely solely upon the one definition rule that says only
+ // one thing can exist at a given decl context. We ignore the file and
+ // line that things are declared on.
std::string qualified_name;
if (die.GetQualifiedName(qualified_name))
- {
- handled = true;
- ConstString const_qualified_name(qualified_name);
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(const_qualified_name, die, Declaration(),
- byte_size_valid ? byte_size : -1,
- *unique_ast_entry_ap))
- {
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
}
- if (!handled)
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(unique_typename, die, unique_decl,
+ byte_size_valid ? byte_size : -1,
+ *unique_ast_entry_ap))
{
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
- byte_size_valid ? byte_size : -1,
- *unique_ast_entry_ap))
+ type_sp = unique_ast_entry_ap->m_type_sp;
+ if (type_sp)
{
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
}
}
}
@@ -716,7 +802,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// a complete type for this die
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
- dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));
+ dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
if (defn_decl_ctx)
LinkDeclContextToDIE(defn_decl_ctx, die);
return type_sp;
@@ -799,9 +885,9 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// and over in the ASTContext for our module
unique_ast_entry_ap->m_type_sp = type_sp;
unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = decl;
+ unique_ast_entry_ap->m_declaration = unique_decl;
unique_ast_entry_ap->m_byte_size = byte_size;
- dwarf->GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
+ dwarf->GetUniqueDWARFASTTypeMap().Insert (unique_typename,
*unique_ast_entry_ap);
if (is_forward_declaration && die.HasChildren())
@@ -842,15 +928,25 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (die.HasChildren() == false)
{
// No children for this struct/union/class, lets finish it
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
+ if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
+ }
+ else
+ {
+ dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
+ die.GetOffset(),
+ type_name_cstr);
+ }
if (tag == DW_TAG_structure_type) // this only applies in C
{
clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type);
if (record_decl)
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
+ {
+ GetClangASTImporter().InsertRecordDecl(record_decl, ClangASTImporter::LayoutInfo());
+ }
}
}
else if (clang_type_was_created)
@@ -872,12 +968,14 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// will automatically call the SymbolFile virtual function
// "SymbolFileDWARF::CompleteType(Type *)"
// When the definition needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
"Type already in the forward declaration map!");
- assert(((SymbolFileDWARF*)m_ast.GetSymbolFile())->UserIDMatches(die.GetDIERef().GetUID()) &&
- "Adding incorrect type to forward declaration map");
+ // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF, it can be a
+ // SymbolFileDWARFDebugMap for Apple binaries.
dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIERef();
+ dwarf->GetForwardDeclClangTypeToDie()[ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()] = die.GetDIERef();
m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
}
}
@@ -970,8 +1068,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// so lets use it and cache the fact that we found
// a complete type for this die
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
- dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));
+ clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
if (defn_decl_ctx)
LinkDeclContextToDIE(defn_decl_ctx, die);
return type_sp;
@@ -986,15 +1083,24 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
{
if (encoding_form.IsValid())
{
- Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form));
if (enumerator_type)
enumerator_clang_type = enumerator_type->GetFullCompilerType ();
}
if (!enumerator_clang_type)
- enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
- DW_ATE_signed,
- byte_size * 8);
+ {
+ if (byte_size > 0)
+ {
+ enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(NULL,
+ DW_ATE_signed,
+ byte_size * 8);
+ }
+ else
+ {
+ enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
+ }
+ }
clang_type = m_ast.CreateEnumerationType (type_name_cstr,
GetClangDeclContextContainingDIE (die, nullptr),
@@ -1013,21 +1119,29 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_const_str,
byte_size,
NULL,
- DIERef(encoding_form).GetUID(),
+ DIERef(encoding_form).GetUID(dwarf),
Type::eEncodingIsUID,
&decl,
clang_type,
Type::eResolveStateForward));
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- if (die.HasChildren())
+ if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
{
- SymbolContext cu_sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die);
+ if (die.HasChildren())
+ {
+ SymbolContext cu_sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ enumerator_clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
+ }
+ else
+ {
+ dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
+ die.GetOffset(),
+ type_name_cstr);
}
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
}
}
break;
@@ -1046,6 +1160,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
bool is_virtual = false;
bool is_explicit = false;
bool is_artificial = false;
+ bool has_template_params = false;
DWARFFormValue specification_die_form;
DWARFFormValue abstract_origin_die_form;
dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
@@ -1153,7 +1268,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
Type *func_type = NULL;
if (type_die_form.IsValid())
- func_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
+ func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
if (func_type)
return_clang_type = func_type->GetForwardCompilerType ();
@@ -1170,11 +1285,13 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die);
const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
- const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
+ bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
// Start off static. This will be set to false in ParseChildParameters(...)
// if we find a "this" parameters as the first parameter
if (is_cxx_method)
+ {
is_static = true;
+ }
if (die.HasChildren())
{
@@ -1185,11 +1302,26 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
skip_artificial,
is_static,
is_variadic,
+ has_template_params,
function_param_types,
function_param_decls,
type_quals);
}
+ bool ignore_containing_context = false;
+ // Check for templatized class member functions. If we had any DW_TAG_template_type_parameter
+ // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we can't let this become
+ // a method in a class. Why? Because templatized functions are only emitted if one of the
+ // templatized methods is used in the current compile unit and we will end up with classes
+ // that may or may not include these member functions and this means one class won't match another
+ // class definition and it affects our ability to use a class in the clang expression parser. So
+ // for the greater good, we currently must not allow any template member functions in a class definition.
+ if (is_cxx_method && has_template_params)
+ {
+ ignore_containing_context = true;
+ is_cxx_method = false;
+ }
+
// clang_type will get the function prototype clang type after this call
clang_type = m_ast.CreateFunctionType (return_clang_type,
function_param_types.data(),
@@ -1197,7 +1329,6 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
is_variadic,
type_quals);
- bool ignore_containing_context = false;
if (type_name_cstr)
{
@@ -1233,7 +1364,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_cstr,
clang_type,
accessibility,
- is_artificial);
+ is_artificial,
+ is_variadic);
type_handled = objc_method_decl != NULL;
if (type_handled)
{
@@ -1272,12 +1404,12 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (debug_map_symfile)
{
class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
- class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
+ class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf));
}
else
{
class_symfile = dwarf;
- class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
+ class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf));
}
if (class_type_die)
{
@@ -1378,7 +1510,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
clang::CXXMethodDecl *method_decl = *method_iter;
if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr))
{
- if (method_decl->getType() == ClangASTContext::GetQualType(clang_type))
+ if (method_decl->getType() ==
+ ClangUtil::GetQualType(clang_type))
{
add_method = false;
LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die);
@@ -1483,44 +1616,72 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (!type_handled)
{
- // We just have a function that isn't part of a class
- clang::FunctionDecl *function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx,
- type_name_cstr,
- clang_type,
- storage,
- is_inline);
-
- // if (template_param_infos.GetSize() > 0)
- // {
- // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx,
- // function_decl,
- // type_name_cstr,
- // template_param_infos);
- //
- // CreateFunctionTemplateSpecializationInfo (function_decl,
- // func_template_decl,
- // template_param_infos);
- // }
- // Add the decl to our DIE to decl context map
- assert (function_decl);
- LinkDeclContextToDIE(function_decl, die);
- if (!function_param_decls.empty())
- m_ast.SetFunctionParameters (function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ clang::FunctionDecl *function_decl = nullptr;
+
+ if (abstract_origin_die_form.IsValid())
+ {
+ DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form));
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
+ SymbolContext sc;
+
+ if (dwarf->ResolveType (abs_die))
+ {
+ function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(GetCachedClangDeclContextForDIE(abs_die));
+
+ if (function_decl)
+ {
+ LinkDeclContextToDIE(function_decl, die);
+ }
+ }
+ }
- if (!object_pointer_name.empty())
+ if (!function_decl)
{
- metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf ("Setting object pointer name: %s on function object %p.",
- object_pointer_name.c_str(),
- static_cast<void*>(function_decl));
+ // We just have a function that isn't part of a class
+ function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx,
+ type_name_cstr,
+ clang_type,
+ storage,
+ is_inline);
+
+ // if (template_param_infos.GetSize() > 0)
+ // {
+ // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx,
+ // function_decl,
+ // type_name_cstr,
+ // template_param_infos);
+ //
+ // CreateFunctionTemplateSpecializationInfo (function_decl,
+ // func_template_decl,
+ // template_param_infos);
+ // }
+ // Add the decl to our DIE to decl context map
+
+ lldbassert (function_decl);
+
+ if (function_decl)
+ {
+ LinkDeclContextToDIE(function_decl, die);
+
+ if (!function_param_decls.empty())
+ m_ast.SetFunctionParameters (function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ if (!object_pointer_name.empty())
+ {
+ metadata.SetObjectPtrName(object_pointer_name.c_str());
+ if (log)
+ log->Printf ("Setting object pointer name: %s on function object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void*>(function_decl));
+ }
+ m_ast.SetMetadata (function_decl, metadata);
+ }
}
- m_ast.SetMetadata (function_decl, metadata);
}
}
type_sp.reset( new Type (die.GetID(),
@@ -1591,7 +1752,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
- Type *element_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
+ DIERef type_die_ref(type_die_form);
+ Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
if (element_type)
{
@@ -1600,6 +1762,39 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (byte_stride == 0 && bit_stride == 0)
byte_stride = element_type->GetByteSize();
CompilerType array_element_type = element_type->GetForwardCompilerType ();
+
+ if (ClangASTContext::IsCXXClassType(array_element_type) && array_element_type.GetCompleteType() == false)
+ {
+ ModuleSP module_sp = die.GetModule();
+ if (module_sp)
+ {
+ if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
+ module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info or disable -gmodule",
+ die.GetOffset(),
+ type_die_ref.die_offset);
+ else
+ module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
+ die.GetOffset(),
+ type_die_ref.die_offset,
+ die.GetLLDBCompileUnit() ? die.GetLLDBCompileUnit()->GetPath().c_str() : "the source file");
+ }
+
+ // We have no choice other than to pretend that the element class type
+ // is complete. If we don't do this, clang will crash when trying
+ // to layout the class. Since we provide layout assistance, all
+ // ivars in this class and other classes will be fine, this is
+ // the best we can do short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(array_element_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(array_element_type);
+ }
+ else
+ {
+ module_sp->ReportError ("DWARF DIE at 0x%8.8x was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
+ type_die_ref.die_offset);
+ }
+ }
+
uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
if (element_orders.size() > 0)
{
@@ -1628,7 +1823,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
empty_name,
array_element_bit_stride / 8,
NULL,
- DIERef(type_die_form).GetUID(),
+ DIERef(type_die_form).GetUID(dwarf),
Type::eEncodingIsUID,
&decl,
clang_type,
@@ -1663,8 +1858,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
}
}
- Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
- Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form).GetUID());
+ Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+ Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType ();
CompilerType class_clang_type = class_type->GetLayoutCompilerType ();
@@ -1812,8 +2007,7 @@ DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
{
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes (attributes);
- const char *name = NULL;
- Type *lldb_type = NULL;
+ const char *name = nullptr;
CompilerType clang_type;
uint64_t uval64 = 0;
bool uval64_valid = false;
@@ -1834,7 +2028,7 @@ DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
case DW_AT_type:
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
- lldb_type = die.ResolveTypeUID(DIERef(form_value).GetUID());
+ Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
if (lldb_type)
clang_type = lldb_type->GetForwardCompilerType ();
}
@@ -1864,19 +2058,19 @@ DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
else
template_param_infos.names.push_back(NULL);
- if (tag == DW_TAG_template_value_parameter &&
- lldb_type != NULL &&
- clang_type.IsIntegerType (is_signed) &&
- uval64_valid)
+ // Get the signed value for any integer or enumeration if available
+ clang_type.IsIntegerOrEnumerationType (is_signed);
+
+ if (tag == DW_TAG_template_value_parameter && uval64_valid)
{
- llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
- template_param_infos.args.push_back (clang::TemplateArgument (*ast,
- llvm::APSInt(apint),
- ClangASTContext::GetQualType(clang_type)));
+ llvm::APInt apint (clang_type.GetBitSize(nullptr), uval64, is_signed);
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), ClangUtil::GetQualType(clang_type)));
}
else
{
- template_param_infos.args.push_back (clang::TemplateArgument (ClangASTContext::GetQualType(clang_type)));
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
}
}
else
@@ -1926,37 +2120,12 @@ DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die,
}
bool
-DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type)
+DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type)
{
- if (m_clang_ast_importer_ap)
- return ClangASTContext::CanImport(compiler_type, GetClangASTImporter());
- else
- return false;
-}
+ SymbolFileDWARF *dwarf = die.GetDWARF();
-bool
-DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type)
-{
- if (CanCompleteType(compiler_type))
- {
- if (ClangASTContext::Import(compiler_type, GetClangASTImporter()))
- {
- ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
- return true;
- }
- else
- {
- ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false);
- }
- }
- return false;
-}
+ std::lock_guard<std::recursive_mutex> guard(dwarf->GetObjectFile()->GetModule()->GetMutex());
-bool
-DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
- lldb_private::Type *type,
- CompilerType &clang_type)
-{
// Disable external storage for this type so we don't get anymore
// clang::ExternalASTSource queries for this type.
m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false);
@@ -1964,9 +2133,45 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
if (!die)
return false;
- const dw_tag_t tag = die.Tag();
+#if defined LLDB_CONFIGURATION_DEBUG
+ //----------------------------------------------------------------------
+ // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES
+ // environment variable can be set with one or more typenames separated
+ // by ';' characters. This will cause this function to not complete any
+ // types whose names match.
+ //
+ // Examples of setting this environment variable:
+ //
+ // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo
+ // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz
+ //----------------------------------------------------------------------
+ const char *dont_complete_typenames_cstr = getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES");
+ if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0])
+ {
+ const char *die_name = die.GetName();
+ if (die_name && die_name[0])
+ {
+ const char *match = strstr(dont_complete_typenames_cstr, die_name);
+ if (match)
+ {
+ size_t die_name_length = strlen(die_name);
+ while (match)
+ {
+ const char separator_char = ';';
+ const char next_char = match[die_name_length];
+ if (next_char == '\0' || next_char == separator_char)
+ {
+ if (match == dont_complete_typenames_cstr || match[-1] == separator_char)
+ return false;
+ }
+ match = strstr(match+1, die_name);
+ }
+ }
+ }
+ }
+#endif
- SymbolFileDWARF *dwarf = die.GetDWARF();
+ const dw_tag_t tag = die.Tag();
Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
if (log)
@@ -1983,7 +2188,7 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
case DW_TAG_union_type:
case DW_TAG_class_type:
{
- LayoutInfo layout_info;
+ ClangASTImporter::LayoutInfo layout_info;
{
if (die.HasChildren())
@@ -2080,7 +2285,7 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
if (class_language != eLanguageTypeObjC)
{
if (is_a_class && tag_decl_kind != clang::TTK_Class)
- m_ast.SetTagTypeKind (ClangASTContext::GetQualType(clang_type), clang::TTK_Class);
+ m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), clang::TTK_Class);
}
// Since DW_TAG_structure_type gets used for both classes
@@ -2130,8 +2335,10 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
// below. Since we provide layout assistance, all ivars in this
// class and other classes will be fine, this is the best we can do
// short of crashing.
- ClangASTContext::StartTagDeclarationDefinition (base_class_type);
- ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
+ if (ClangASTContext::StartTagDeclarationDefinition (base_class_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
+ }
}
}
}
@@ -2219,7 +2426,7 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
}
}
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
+ GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
}
}
}
@@ -2227,15 +2434,17 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
return (bool)clang_type;
case DW_TAG_enumeration_type:
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- if (die.HasChildren())
+ if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
{
- SymbolContext sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die);
+ if (die.HasChildren())
+ {
+ SymbolContext sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
}
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
return (bool)clang_type;
default:
@@ -2484,6 +2693,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
// never mangled.
bool is_static = false;
bool is_variadic = false;
+ bool has_template_params = false;
unsigned type_quals = 0;
std::vector<CompilerType> param_types;
std::vector<clang::ParmVarDecl*> param_decls;
@@ -2500,6 +2710,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
true,
is_static,
is_variadic,
+ has_template_params,
param_types,
param_decls,
type_quals);
@@ -2557,23 +2768,22 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
return NULL;
}
-
bool
-DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
- const DWARFDIE &parent_die,
- CompilerType &class_clang_type,
- const LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *>& base_classes,
- std::vector<int>& member_accessibilities,
- DWARFDIECollection& member_function_dies,
- DelayedPropertyList& delayed_properties,
- AccessType& default_accessibility,
- bool &is_a_class,
- LayoutInfo &layout_info)
+DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die,
+ CompilerType &class_clang_type, const LanguageType class_language,
+ std::vector<clang::CXXBaseSpecifier *> &base_classes,
+ std::vector<int> &member_accessibilities,
+ DWARFDIECollection &member_function_dies,
+ DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
+ bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info)
{
if (!parent_die)
return 0;
+ // Get the parent byte size so we can verify any members will fit
+ const uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8;
+ const uint64_t parent_bit_size = parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
+
uint32_t member_idx = 0;
BitfieldInfo last_field_info;
@@ -2607,9 +2817,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
bool is_artificial = false;
DWARFFormValue encoding_form;
AccessType accessibility = eAccessNone;
- uint32_t member_byte_offset = UINT32_MAX;
+ uint32_t member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
size_t byte_size = 0;
- size_t bit_offset = 0;
+ int64_t bit_offset = 0;
+ uint64_t data_bit_offset = UINT64_MAX;
size_t bit_size = 0;
bool is_external = false; // On DW_TAG_members, this means the member is static
uint32_t i;
@@ -2626,9 +2837,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(); break;
case DW_AT_type: encoding_form = form_value; break;
- case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
+ case DW_AT_bit_offset: bit_offset = form_value.Signed(); break;
case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
+ case DW_AT_data_bit_offset: data_bit_offset = form_value.Unsigned(); break;
case DW_AT_data_member_location:
if (form_value.BlockData())
{
@@ -2637,10 +2849,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
- NULL, // RegisterContext *
+ if (DWARFExpression::Evaluate(nullptr, // ExecutionContext *
+ nullptr, // ClangExpressionVariableList *
+ nullptr, // ClangExpressionDeclMap *
+ nullptr, // RegisterContext *
module_sp,
debug_info_data,
die.GetCU(),
@@ -2648,8 +2860,9 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
block_length,
eRegisterKindDWARF,
&initialValue,
+ nullptr,
memberOffset,
- NULL))
+ nullptr))
{
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
@@ -2739,7 +2952,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// type in an expression when clang becomes unhappy with its
// recycled debug info.
- if (bit_offset > 128)
+ if (byte_size == 0 && bit_offset < 0)
{
bit_size = 0;
bit_offset = 0;
@@ -2764,7 +2977,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// Handle static members
if (is_external && member_byte_offset == UINT32_MAX)
{
- Type *var_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
if (var_type)
{
@@ -2780,7 +2993,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
if (is_artificial == false)
{
- Type *member_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
clang::FieldDecl *field_decl = NULL;
if (tag == DW_TAG_member)
@@ -2815,17 +3028,38 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// AT_bit_size indicates the size of the field in bits.
/////////////////////////////////////////////////////////////
- if (byte_size == 0)
- byte_size = member_type->GetByteSize();
-
- if (die.GetDWARF()->GetObjectFile()->GetByteOrder() == eByteOrderLittle)
+ if (data_bit_offset != UINT64_MAX)
{
- this_field_info.bit_offset += byte_size * 8;
- this_field_info.bit_offset -= (bit_offset + bit_size);
+ this_field_info.bit_offset = data_bit_offset;
}
else
{
- this_field_info.bit_offset += bit_offset;
+ if (byte_size == 0)
+ byte_size = member_type->GetByteSize();
+
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ if (objfile->GetByteOrder() == eByteOrderLittle)
+ {
+ this_field_info.bit_offset += byte_size * 8;
+ this_field_info.bit_offset -= (bit_offset + bit_size);
+ }
+ else
+ {
+ this_field_info.bit_offset += bit_offset;
+ }
+ }
+
+ if ((this_field_info.bit_offset >= parent_bit_size) || !last_field_info.NextBitfieldOffsetIsValid(this_field_info.bit_offset))
+ {
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n",
+ die.GetID(),
+ DW_TAG_value_to_name(tag),
+ name,
+ this_field_info.bit_offset,
+ sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
+ this_field_info.Clear();
+ continue;
}
// Update the field bit offset we will report for layout
@@ -2962,8 +3196,18 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// to layout the class. Since we provide layout assistance, all
// ivars in this class and other classes will be fine, this is
// the best we can do short of crashing.
- ClangASTContext::StartTagDeclarationDefinition(member_clang_type);
- ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
+ if (ClangASTContext::StartTagDeclarationDefinition(member_clang_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
+ }
+ else
+ {
+ module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type claims to be a C++ class but we were not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
+ parent_die.GetOffset(),
+ parent_die.GetName(),
+ die.GetOffset(),
+ name);
+ }
}
field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
@@ -3063,10 +3307,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate (NULL,
- NULL,
- NULL,
- NULL,
+ if (DWARFExpression::Evaluate (nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
module_sp,
debug_info_data,
die.GetCU(),
@@ -3074,8 +3318,9 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
block_length,
eRegisterKindDWARF,
&initialValue,
+ nullptr,
memberOffset,
- NULL))
+ nullptr))
{
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
@@ -3106,7 +3351,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
}
}
- Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
if (base_class_type == NULL)
{
module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message",
@@ -3166,6 +3411,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
bool skip_artificial,
bool &is_static,
bool &is_variadic,
+ bool &has_template_params,
std::vector<CompilerType>& function_param_types,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals)
@@ -3251,7 +3497,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
// being in the formal parameter DIE...
if (name == NULL || ::strcmp(name, "this")==0)
{
- Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form).GetUID());
+ Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form));
if (this_type)
{
uint32_t encoding_mask = this_type->GetEncodingMask();
@@ -3294,7 +3540,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
if (!skip)
{
- Type *type = die.ResolveTypeUID(DIERef(param_type_die_form).GetUID());
+ Type *type = die.ResolveTypeUID(DIERef(param_type_die_form));
if (type)
{
function_param_types.push_back (type->GetForwardCompilerType ());
@@ -3324,6 +3570,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
// in SymbolFileDWARF::ParseType() so this was removed. If we ever need
// the template params back, we can add them back.
// ParseTemplateDIE (dwarf_cu, die, template_param_infos);
+ has_template_params = true;
break;
default:
@@ -3440,7 +3687,7 @@ DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die)
DWARFFormValue form_value;
if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
- return dwarf->ResolveTypeUID(DIERef(form_value).GetUID());
+ return dwarf->ResolveTypeUID(dwarf->GetDIE (DIERef(form_value)), true);
}
}
}
@@ -3477,6 +3724,14 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
m_decl_to_die[decl].insert(die.GetDIE());
return decl;
}
+
+ if (DWARFDIE abstract_origin_die = die.GetReferencedDIE(DW_AT_abstract_origin))
+ {
+ clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
+ m_die_to_decl[die.GetDIE()] = decl;
+ m_decl_to_die[decl].insert(die.GetDIE());
+ return decl;
+ }
clang::Decl *decl = nullptr;
switch (die.Tag())
@@ -3487,22 +3742,23 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
{
SymbolFileDWARF *dwarf = die.GetDWARF();
Type *type = GetTypeForDIE(die);
- const char *name = die.GetName();
- clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- decl = m_ast.CreateVariableDeclaration(
- decl_context,
- name,
- ClangASTContext::GetQualType(type->GetForwardCompilerType()));
+ if (dwarf && type)
+ {
+ const char *name = die.GetName();
+ clang::DeclContext *decl_context =
+ ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
+ decl = m_ast.CreateVariableDeclaration(decl_context, name,
+ ClangUtil::GetQualType(type->GetForwardCompilerType()));
+ }
break;
}
case DW_TAG_imported_declaration:
{
SymbolFileDWARF *dwarf = die.GetDWARF();
- lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
-
- if (dwarf->UserIDMatches(imported_uid))
+ DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
+ if (imported_uid)
{
- CompilerDecl imported_decl = dwarf->GetDeclForUID(imported_uid);
+ CompilerDecl imported_decl = imported_uid.GetDecl();
if (imported_decl)
{
clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
@@ -3515,15 +3771,15 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
case DW_TAG_imported_module:
{
SymbolFileDWARF *dwarf = die.GetDWARF();
- lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
+ DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
- if (dwarf->UserIDMatches(imported_uid))
+ if (imported_uid)
{
- CompilerDeclContext imported_decl = dwarf->GetDeclContextForUID(imported_uid);
- if (imported_decl)
+ CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext();
+ if (imported_decl_ctx)
{
clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl))
+ if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl_ctx))
decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
}
}
@@ -4001,34 +4257,3 @@ DWARFASTParserClang::CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die,
return (failures.Size() != 0);
}
-
-bool
-DWARFASTParserClang::LayoutRecordType(const clang::RecordDecl *record_decl,
- uint64_t &bit_size,
- uint64_t &alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
-{
- RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
- bool success = false;
- base_offsets.clear();
- vbase_offsets.clear();
- if (pos != m_record_decl_to_layout_map.end())
- {
- bit_size = pos->second.bit_size;
- alignment = pos->second.alignment;
- field_offsets.swap(pos->second.field_offsets);
- base_offsets.swap (pos->second.base_offsets);
- vbase_offsets.swap (pos->second.vbase_offsets);
- m_record_decl_to_layout_map.erase(pos);
- success = true;
- }
- else
- {
- bit_size = 0;
- alignment = 0;
- field_offsets.clear();
- }
- return success;
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 3814758fdd2cf..0826423b0359f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -19,11 +19,12 @@
#include "clang/AST/CharUnits.h"
// Project includes
+#include "DWARFASTParser.h"
+#include "DWARFDefines.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "DWARFDefines.h"
-#include "DWARFASTParser.h"
+#include "lldb/Symbol/ClangASTImporter.h"
class DWARFDebugInfoEntry;
class DWARFDIECollection;
@@ -35,6 +36,7 @@ public:
~DWARFASTParserClang() override;
+ // DWARFASTParser interface.
lldb::TypeSP
ParseTypeFromDWARF (const lldb_private::SymbolContext& sc,
const DWARFDIE &die,
@@ -47,12 +49,6 @@ public:
const DWARFDIE &die) override;
bool
- CanCompleteType (const lldb_private::CompilerType &compiler_type) override;
-
- bool
- CompleteType (const lldb_private::CompilerType &compiler_type) override;
-
- bool
CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) override;
@@ -69,43 +65,19 @@ public:
lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) override;
- bool
- LayoutRecordType(const clang::RecordDecl *record_decl,
- uint64_t &bit_size,
- uint64_t &alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets);
+ lldb_private::ClangASTImporter &
+ GetClangASTImporter();
protected:
class DelayedAddObjCClassProperty;
typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
- struct LayoutInfo
- {
- LayoutInfo () :
- bit_size(0),
- alignment(0),
- field_offsets(),
- base_offsets(),
- vbase_offsets()
- {
- }
- uint64_t bit_size;
- uint64_t alignment;
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
- };
-
clang::BlockDecl *
ResolveBlockDIE (const DWARFDIE &die);
clang::NamespaceDecl *
ResolveNamespaceDIE (const DWARFDIE &die);
- typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap;
-
bool
ParseTemplateDIE (const DWARFDIE &die,
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
@@ -114,17 +86,12 @@ protected:
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
bool
- ParseChildMembers (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- lldb_private::CompilerType &class_compiler_type,
- const lldb::LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *>& base_classes,
- std::vector<int>& member_accessibilities,
- DWARFDIECollection& member_function_dies,
- DelayedPropertyList& delayed_properties,
- lldb::AccessType &default_accessibility,
- bool &is_a_class,
- LayoutInfo &layout_info);
+ ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ lldb_private::CompilerType &class_compiler_type, const lldb::LanguageType class_language,
+ std::vector<clang::CXXBaseSpecifier *> &base_classes, std::vector<int> &member_accessibilities,
+ DWARFDIECollection &member_function_dies, DelayedPropertyList &delayed_properties,
+ lldb::AccessType &default_accessibility, bool &is_a_class,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
ParseChildParameters (const lldb_private::SymbolContext& sc,
@@ -133,6 +100,7 @@ protected:
bool skip_artificial,
bool &is_static,
bool &is_variadic,
+ bool &has_template_params,
std::vector<lldb_private::CompilerType>& function_args,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals);
@@ -181,9 +149,6 @@ protected:
void
LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
- lldb_private::ClangASTImporter &
- GetClangASTImporter();
-
lldb::TypeSP
ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);
@@ -206,7 +171,6 @@ protected:
DeclToDIEMap m_decl_to_die;
DIEToDeclContextMap m_die_to_decl_ctx;
DeclContextToDIEMap m_decl_ctx_to_die;
- RecordDeclToLayoutMap m_record_decl_to_layout_map;
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
};
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index bde2694461e2e..346e2d63b9082 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -144,7 +144,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
switch (tag)
@@ -183,7 +183,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
break;
}
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, byte_size,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
NULL, encoding_uid, encoding_data_type, &decl, compiler_type, resolve_state));
dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
@@ -254,7 +254,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr);
bool compiler_type_was_created = false;
@@ -265,7 +265,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
compiler_type = m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
}
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, byte_size,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
Type::eResolveStateForward));
@@ -347,7 +347,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr);
std::vector<CompilerType> function_param_types;
@@ -363,7 +363,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
compiler_type = m_ast.CreateFunctionType(type_name_const_str, function_param_types.data(),
function_param_types.size(), is_variadic);
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, 0, NULL,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
Type::eResolveStateFull));
assert(type_sp.get());
@@ -410,7 +410,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr);
Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
@@ -433,7 +433,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
{
compiler_type = m_ast.CreateArrayType(type_name_const_str, array_element_type, 0);
}
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
byte_stride, NULL, type_die_offset, Type::eEncodingIsUID, &decl,
compiler_type, Type::eResolveStateFull));
type_sp->SetEncodingType(element_type);
@@ -463,7 +463,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
else if (sc.function != NULL && sc_parent_die)
{
symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(dwarf->MakeUserID(sc_parent_die.GetOffset()));
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
if (symbol_context_scope == NULL)
symbol_context_scope = sc.function;
}
@@ -510,7 +510,7 @@ DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
if (num_attributes > 0)
{
Declaration decl;
- dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
+ DWARFFormValue param_type_die_offset;
uint32_t i;
for (i = 0; i < num_attributes; ++i)
@@ -525,7 +525,7 @@ DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
// = form_value.AsCString();
break;
case DW_AT_type:
- param_type_die_offset = form_value.Reference();
+ param_type_die_offset = form_value;
break;
case DW_AT_location:
// if (form_value.BlockData())
@@ -547,7 +547,7 @@ DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
}
}
- Type *type = parent_die.ResolveTypeUID(param_type_die_offset);
+ Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
if (type)
{
function_param_types.push_back(type->GetForwardCompilerType());
@@ -628,7 +628,7 @@ DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type
Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", dwarf->MakeUserID(die.GetOffset()),
+ log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", die.GetID(),
DW_TAG_value_to_name(tag), type->GetName().AsCString());
assert(compiler_type);
DWARFAttributes attributes;
@@ -683,7 +683,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
Declaration decl;
const char *name = NULL;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+ DWARFFormValue encoding_uid;
uint32_t member_byte_offset = UINT32_MAX;
uint32_t i;
for (i = 0; i < num_attributes; ++i)
@@ -698,7 +698,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
name = form_value.AsCString();
break;
case DW_AT_type:
- encoding_uid = form_value.Reference();
+ encoding_uid = form_value;
break;
case DW_AT_data_member_location:
if (form_value.BlockData())
@@ -715,7 +715,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
NULL, // RegisterContext *
module_sp, debug_info_data, die.GetCU(),
block_offset, block_length, eRegisterKindDWARF,
- &initialValue, memberOffset, NULL))
+ &initialValue, NULL, memberOffset, NULL))
{
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
@@ -735,7 +735,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
}
}
- Type *member_type = die.ResolveTypeUID(encoding_uid);
+ Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
if (member_type)
{
CompilerType member_go_type = member_type->GetFullCompilerType();
@@ -808,10 +808,12 @@ DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, const DWARFDIE
if (dwarf->FixupAddress(func_range.GetBaseAddress()))
{
- const user_id_t func_user_id = dwarf->MakeUserID(die.GetOffset());
+ const user_id_t func_user_id = die.GetID();
func_sp.reset(new Function(sc.comp_unit,
- dwarf->MakeUserID(func_user_id), // UserID is the DIE offset
- dwarf->MakeUserID(func_user_id), func_name, func_type,
+ func_user_id, // UserID is the DIE offset
+ func_user_id,
+ func_name,
+ func_type,
func_range)); // first address range
if (func_sp.get() != NULL)
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
new file mode 100644
index 0000000000000..b21bf2ded4899
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
@@ -0,0 +1,555 @@
+//===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFASTParserJava.h"
+#include "DWARFAttribute.h"
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFDeclContext.h"
+#include "SymbolFileDWARF.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+#include "lldb/Symbol/TypeList.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast)
+{
+}
+
+DWARFASTParserJava::~DWARFASTParserJava()
+{
+}
+
+TypeSP
+DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ ConstString type_name;
+ uint64_t byte_size = 0;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_name:
+ type_name.SetCString(form_value.AsCString());
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_encoding:
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_base_type");
+ }
+ }
+ }
+
+ Declaration decl;
+ CompilerType compiler_type = m_ast.CreateBaseType(type_name);
+ return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, compiler_type, Type::eResolveStateFull);
+}
+
+TypeSP
+DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ ConstString linkage_name;
+ DWARFFormValue type_attr_value;
+ lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
+ DWARFExpression length_expression(die.GetCU());
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_linkage_name:
+ linkage_name.SetCString(form_value.AsCString());
+ break;
+ case DW_AT_type:
+ type_attr_value = form_value;
+ break;
+ case DW_AT_data_member_location:
+ data_offset = form_value.Unsigned();
+ break;
+ case DW_AT_declaration:
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_array_type");
+ }
+ }
+ }
+
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling())
+ {
+ if (child_die.Tag() == DW_TAG_subrange_type)
+ {
+ DWARFAttributes attributes;
+ const size_t num_attributes = child_die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_count:
+ if (form_value.BlockData())
+ length_expression.CopyOpcodeData(form_value.BlockData(), form_value.Unsigned(),
+ child_die.GetCU()->GetByteOrder(),
+ child_die.GetCU()->GetAddressByteSize());
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_subrange_type");
+ }
+ }
+ }
+ }
+ else
+ {
+ assert(false && "Unsupported child for DW_TAG_array_type");
+ }
+ }
+
+ DIERef type_die_ref(type_attr_value);
+ Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
+ if (!element_type)
+ return nullptr;
+
+ CompilerType element_compiler_type = element_type->GetForwardCompilerType();
+ CompilerType array_compiler_type =
+ m_ast.CreateArrayType(linkage_name, element_compiler_type, length_expression, data_offset);
+
+ Declaration decl;
+ TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), -1, nullptr,
+ type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
+ array_compiler_type, Type::eResolveStateFull));
+ type_sp->SetEncodingType(element_type);
+ return type_sp;
+}
+
+TypeSP
+DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ Declaration decl;
+ DWARFFormValue type_attr_value;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_type:
+ type_attr_value = form_value;
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_array_type");
+ }
+ }
+ }
+
+ DIERef type_die_ref(type_attr_value);
+ Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
+ if (!pointee_type)
+ return nullptr;
+
+ CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
+ CompilerType reference_compiler_type = m_ast.CreateReferenceType(pointee_compiler_type);
+ TypeSP type_sp(new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1, nullptr,
+ type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
+ reference_compiler_type, Type::eResolveStateFull));
+ type_sp->SetEncodingType(pointee_type);
+ return type_sp;
+}
+
+lldb::TypeSP
+DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ Declaration decl;
+ ConstString name;
+ ConstString linkage_name;
+ bool is_forward_declaration = false;
+ uint32_t byte_size = 0;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_name:
+ name.SetCString(form_value.AsCString());
+ break;
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_linkage_name:
+ linkage_name.SetCString(form_value.AsCString());
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_class_type");
+ }
+ }
+ }
+
+ UniqueDWARFASTType unique_ast_entry;
+ if (name)
+ {
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ {
+ name.SetCString(qualified_name.c_str());
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1, unique_ast_entry))
+ {
+ if (unique_ast_entry.m_type_sp)
+ {
+ dwarf->GetDIEToType()[die.GetDIE()] = unique_ast_entry.m_type_sp.get();
+ is_new_type = false;
+ return unique_ast_entry.m_type_sp;
+ }
+ }
+ }
+ }
+
+ if (is_forward_declaration)
+ {
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+ if (type_sp)
+ {
+ // We found a real definition for this type elsewhere so lets use it
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ is_new_type = false;
+ return type_sp;
+ }
+ }
+
+ CompilerType compiler_type(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!compiler_type)
+ compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
+
+ is_new_type = true;
+ TypeSP type_sp(new Type(die.GetID(), dwarf, name,
+ -1, // byte size isn't specified
+ nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
+ Type::eResolveStateForward));
+
+ // Add our type to the unique type map
+ unique_ast_entry.m_type_sp = type_sp;
+ unique_ast_entry.m_die = die;
+ unique_ast_entry.m_declaration = decl;
+ unique_ast_entry.m_byte_size = -1;
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
+
+ if (!is_forward_declaration)
+ {
+ // Leave this as a forward declaration until we need to know the details of the type
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = compiler_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
+ }
+ return type_sp;
+}
+
+lldb::TypeSP
+DWARFASTParserJava::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ lldb_private::Log *log, bool *type_is_new_ptr)
+{
+ if (type_is_new_ptr)
+ *type_is_new_ptr = false;
+
+ if (!die)
+ return nullptr;
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+
+ Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
+ if (type_ptr == DIE_IS_BEING_PARSED)
+ return nullptr;
+ if (type_ptr != nullptr)
+ return type_ptr->shared_from_this();
+
+ TypeSP type_sp;
+ if (type_is_new_ptr)
+ *type_is_new_ptr = true;
+
+ switch (die.Tag())
+ {
+ case DW_TAG_base_type:
+ {
+ type_sp = ParseBaseTypeFromDIE(die);
+ break;
+ }
+ case DW_TAG_array_type:
+ {
+ type_sp = ParseArrayTypeFromDIE(die);
+ break;
+ }
+ case DW_TAG_class_type:
+ {
+ bool is_new_type = false;
+ type_sp = ParseClassTypeFromDIE(die, is_new_type);
+ if (!is_new_type)
+ return type_sp;
+ break;
+ }
+ case DW_TAG_reference_type:
+ {
+ type_sp = ParseReferenceTypeFromDIE(die);
+ break;
+ }
+ }
+
+ if (!type_sp)
+ return nullptr;
+
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = nullptr;
+ if (sc_parent_tag == DW_TAG_compile_unit)
+ {
+ symbol_context_scope = sc.comp_unit;
+ }
+ else if (sc.function != nullptr && sc_parent_die)
+ {
+ symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == nullptr)
+ symbol_context_scope = sc.function;
+ }
+
+ if (symbol_context_scope != nullptr)
+ type_sp->SetSymbolContextScope(symbol_context_scope);
+
+ dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+
+ return type_sp;
+}
+
+lldb_private::Function *
+DWARFASTParserJava::ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die)
+{
+ assert(die.Tag() == DW_TAG_subprogram);
+
+ const char *name = nullptr;
+ const char *mangled = nullptr;
+ int decl_file = 0;
+ int decl_line = 0;
+ int decl_column = 0;
+ int call_file = 0;
+ int call_line = 0;
+ int call_column = 0;
+ DWARFRangeList func_ranges;
+ DWARFExpression frame_base(die.GetCU());
+
+ if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
+ call_column, &frame_base))
+ {
+ // Union of all ranges in the function DIE (if the function is discontiguous)
+ AddressRange func_range;
+ lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
+ lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
+ if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
+ {
+ ModuleSP module_sp(die.GetModule());
+ func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
+ if (func_range.GetBaseAddress().IsValid())
+ func_range.SetByteSize(highest_func_addr - lowest_func_addr);
+ }
+
+ if (func_range.GetBaseAddress().IsValid())
+ {
+ std::unique_ptr<Declaration> decl_ap;
+ if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+ decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
+ decl_column));
+
+ if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress()))
+ {
+ FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
+ Mangled(ConstString(name), false),
+ nullptr, // No function types in java
+ func_range));
+ if (frame_base.IsValid())
+ func_sp->GetFrameBaseExpression() = frame_base;
+ sc.comp_unit->AddFunction(func_sp);
+
+ return func_sp.get();
+ }
+ }
+ }
+ return nullptr;
+}
+
+bool
+DWARFASTParserJava::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ lldb_private::CompilerType &java_type)
+{
+ switch (die.Tag())
+ {
+ case DW_TAG_class_type:
+ {
+ if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0)
+ {
+ if (die.HasChildren())
+ ParseChildMembers(die, java_type);
+ m_ast.CompleteObjectType(java_type);
+ return java_type.IsValid();
+ }
+ }
+ break;
+ default:
+ assert(false && "Not a forward java type declaration!");
+ break;
+ }
+ return false;
+}
+
+void
+DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type)
+{
+ DWARFCompileUnit *dwarf_cu = parent_die.GetCU();
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
+ {
+ switch (die.Tag())
+ {
+ case DW_TAG_member:
+ {
+ const char *name = nullptr;
+ DWARFFormValue encoding_uid;
+ uint32_t member_byte_offset = UINT32_MAX;
+ DWARFExpression member_location_expression(dwarf_cu);
+
+ DWARFAttributes attributes;
+ size_t num_attributes = die.GetAttributes(attributes);
+ for (size_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attributes.AttributeAtIndex(i))
+ {
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData())
+ member_location_expression.CopyOpcodeData(
+ form_value.BlockData(), form_value.Unsigned(), dwarf_cu->GetByteOrder(),
+ dwarf_cu->GetAddressByteSize());
+ else
+ member_byte_offset = form_value.Unsigned();
+ break;
+ case DW_AT_artificial:
+ static_cast<void>(form_value.Boolean());
+ break;
+ case DW_AT_accessibility:
+ // TODO: Handle when needed
+ break;
+ default:
+ assert(false && "Unhandled attribute for DW_TAG_member");
+ break;
+ }
+ }
+ }
+
+ if (strcmp(name, ".dynamic_type") == 0)
+ m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
+ else
+ {
+ if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
+ m_ast.AddMemberToObject(compiler_type, ConstString(name), member_type->GetFullCompilerType(),
+ member_byte_offset);
+ }
+ break;
+ }
+ case DW_TAG_inheritance:
+ {
+ DWARFFormValue encoding_uid;
+ uint32_t member_byte_offset = UINT32_MAX;
+
+ DWARFAttributes attributes;
+ size_t num_attributes = die.GetAttributes(attributes);
+ for (size_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attributes.AttributeAtIndex(i))
+ {
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ case DW_AT_data_member_location:
+ member_byte_offset = form_value.Unsigned();
+ break;
+ case DW_AT_accessibility:
+ // In java all base class is public so we can ignore this attribute
+ break;
+ default:
+ assert(false && "Unhandled attribute for DW_TAG_member");
+ break;
+ }
+ }
+ }
+ if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
+ m_ast.AddBaseClassToObject(compiler_type, base_type->GetFullCompilerType(), member_byte_offset);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
new file mode 100644
index 0000000000000..6a7eee75e6f7b
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
@@ -0,0 +1,90 @@
+//===-- DWARFASTParserJava.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFASTParserJava_h_
+#define SymbolFileDWARF_DWARFASTParserJava_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+// Project includes
+#include "DWARFASTParser.h"
+#include "DWARFDIE.h"
+#include "DWARFDefines.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/JavaASTContext.h"
+
+class DWARFDebugInfoEntry;
+class DWARFDIECollection;
+
+class DWARFASTParserJava : public DWARFASTParser
+{
+public:
+ DWARFASTParserJava(lldb_private::JavaASTContext &ast);
+ ~DWARFASTParserJava() override;
+
+ lldb::TypeSP
+ ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
+ bool *type_is_new_ptr) override;
+
+ lldb_private::Function *
+ ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die) override;
+
+ bool
+ CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ lldb_private::CompilerType &java_type) override;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override
+ {
+ return lldb_private::CompilerDeclContext();
+ }
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override
+ {
+ return lldb_private::CompilerDeclContext();
+ }
+
+ lldb_private::CompilerDecl
+ GetDeclForUIDFromDWARF(const DWARFDIE &die) override
+ {
+ return lldb_private::CompilerDecl();
+ }
+
+ std::vector<DWARFDIE>
+ GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override
+ {
+ return std::vector<DWARFDIE>();
+ }
+
+ void
+ ParseChildMembers(const DWARFDIE &parent_die, lldb_private::CompilerType &class_compiler_type);
+
+private:
+ lldb_private::JavaASTContext &m_ast;
+
+ lldb::TypeSP
+ ParseBaseTypeFromDIE(const DWARFDIE &die);
+
+ lldb::TypeSP
+ ParseArrayTypeFromDIE(const DWARFDIE &die);
+
+ lldb::TypeSP
+ ParseReferenceTypeFromDIE(const DWARFDIE &die);
+
+ lldb::TypeSP
+ ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type);
+};
+
+#endif // SymbolFileDWARF_DWARFASTParserJava_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index e7cb2b413ad7a..c5d7568b52729 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -311,46 +311,12 @@ DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die)
{
assert (m_die_array.empty() && "Compile unit DIE already added");
AddDIE(die);
-
- DWARFDebugInfoEntry& cu_die = m_die_array.front();
-
- const char* dwo_name = cu_die.GetAttributeValueAsString(m_dwarf2Data,
- this,
- DW_AT_GNU_dwo_name,
- nullptr);
- if (!dwo_name)
- return;
-
- FileSpec dwo_file(dwo_name, true);
- if (dwo_file.IsRelative())
- {
- const char* comp_dir = cu_die.GetAttributeValueAsString(m_dwarf2Data,
- this,
- DW_AT_comp_dir,
- nullptr);
- if (!comp_dir)
- return;
-
- dwo_file.SetFile(comp_dir, true);
- dwo_file.AppendPathComponent(dwo_name);
- }
-
- if (!dwo_file.Exists())
- return;
- DataBufferSP dwo_file_data_sp;
- lldb::offset_t dwo_file_data_offset = 0;
- ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(m_dwarf2Data->GetObjectFile()->GetModule(),
- &dwo_file,
- 0 /* file_offset */,
- dwo_file.GetByteSize(),
- dwo_file_data_sp,
- dwo_file_data_offset);
- if (dwo_obj_file == nullptr)
+ const DWARFDebugInfoEntry &cu_die = m_die_array.front();
+ std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die);
+ if (!dwo_symbol_file)
return;
- std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file(new SymbolFileDWARFDwo(dwo_obj_file, this));
-
DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
if (!dwo_cu)
return; // Can't fetch the compile unit from the dwo file.
@@ -467,7 +433,7 @@ DWARFCompileUnit::GetID () const
{
dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
if (m_dwarf2Data)
- return m_dwarf2Data->MakeUserID(local_id);
+ return DIERef(local_id, local_id).GetUID(m_dwarf2Data);
else
return local_id;
}
@@ -665,7 +631,7 @@ DWARFCompileUnit::GetDIE (dw_offset_t die_offset)
{
// Don't specify the compile unit offset as we don't know it because the DIE belongs to
// a different compile unit in the same symbol file.
- return m_dwarf2Data->DebugInfo()->GetDIE (DIERef(die_offset));
+ return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
}
}
return DWARFDIE(); // Not found
@@ -789,20 +755,21 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
switch (tag)
{
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
+ case DW_TAG_array_type:
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_constant:
case DW_TAG_enumeration_type:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_namespace:
case DW_TAG_string_type:
- case DW_TAG_subroutine_type:
case DW_TAG_structure_type:
- case DW_TAG_union_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
case DW_TAG_typedef:
- case DW_TAG_namespace:
- case DW_TAG_variable:
+ case DW_TAG_union_type:
case DW_TAG_unspecified_type:
+ case DW_TAG_variable:
break;
default:
@@ -977,7 +944,7 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
// as our name. If it starts with '_', then it is ok, else compare
// the string to make sure it isn't the same and we don't end up
// with duplicate entries
- if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0)))
+ if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
{
Mangled mangled (ConstString(mangled_cstr), true);
func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
@@ -1000,7 +967,7 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
// as our name. If it starts with '_', then it is ok, else compare
// the string to make sure it isn't the same and we don't end up
// with duplicate entries
- if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
+ if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
{
Mangled mangled (ConstString(mangled_cstr), true);
func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
@@ -1014,20 +981,21 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
}
break;
+ case DW_TAG_array_type:
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_constant:
case DW_TAG_enumeration_type:
case DW_TAG_string_type:
- case DW_TAG_subroutine_type:
case DW_TAG_structure_type:
- case DW_TAG_union_type:
+ case DW_TAG_subroutine_type:
case DW_TAG_typedef:
+ case DW_TAG_union_type:
case DW_TAG_unspecified_type:
- if (name && is_declaration == false)
- {
+ if (name && !is_declaration)
types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- }
+ if (mangled_cstr && !is_declaration)
+ types.Insert (ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset()));
break;
case DW_TAG_namespace:
@@ -1180,7 +1148,7 @@ DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val)
{
case DW_LANG_Mips_Assembler:
return eLanguageTypeMipsAssembler;
- case 0x8e57: // FIXME: needs to be added to llvm
+ case DW_LANG_GOOGLE_RenderScript:
return eLanguageTypeExtRenderScript;
default:
return static_cast<LanguageType>(val);
@@ -1259,3 +1227,9 @@ DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset)
m_addr_base = addr_base;
m_base_obj_offset = base_obj_offset;
}
+
+lldb::ByteOrder
+DWARFCompileUnit::GetByteOrder() const
+{
+ return m_dwarf2Data->GetObjectFile()->GetByteOrder();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 0fcaaca09ed8c..8d96e3698ab26 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -59,6 +59,8 @@ public:
void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
DWARFDebugAranges* debug_aranges);
+ lldb::ByteOrder
+ GetByteOrder() const;
lldb_private::TypeSystem *
GetTypeSystem();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 0564de9e5dd1f..0f02c74fd2ebd 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -9,6 +9,7 @@
#include "DWARFDIE.h"
+#include "DWARFASTParser.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
@@ -127,6 +128,21 @@ DWARFDIE::GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) c
return fail_value;
}
+DWARFDIE
+DWARFDIE::GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const
+{
+ if (IsValid())
+ {
+ DWARFCompileUnit *cu = GetCU();
+ SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
+ const bool check_specification_or_abstract_origin = true;
+ DWARFFormValue form_value;
+ if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
+ return dwarf->GetDIE(DIERef(form_value));
+ }
+ return DWARFDIE();
+}
+
uint64_t
DWARFDIE::GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const
{
@@ -166,7 +182,7 @@ DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const
if (cu->ContainsDIEOffset(block_die->GetOffset()))
return DWARFDIE(cu, block_die);
else
- return DWARFDIE(dwarf->DebugInfo()->GetCompileUnitContainingDIE(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die);
+ return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die);
}
}
}
@@ -176,27 +192,7 @@ DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const
lldb::user_id_t
DWARFDIE::GetID () const
{
- const dw_offset_t die_offset = GetOffset();
- if (die_offset != DW_INVALID_OFFSET)
- {
- lldb::user_id_t id = 0;
- SymbolFileDWARF *dwarf = GetDWARF();
- if (dwarf)
- id = dwarf->MakeUserID(die_offset);
- else
- id = die_offset;
-
- if (m_cu)
- {
- lldb::user_id_t cu_id = m_cu->GetID()&0xffffffff00000000ull;
- assert ((id&0xffffffff00000000ull) == 0 ||
- (cu_id&0xffffffff00000000ll) == 0 ||
- (id&0xffffffff00000000ull) == (cu_id&0xffffffff00000000ll));
- id |= cu_id;
- }
- return id;
- }
- return LLDB_INVALID_UID;
+ return GetDIERef().GetUID(GetDWARF());
}
const char *
@@ -274,11 +270,11 @@ DWARFDIE::ResolveType () const
}
lldb_private::Type *
-DWARFDIE::ResolveTypeUID (lldb::user_id_t uid) const
+DWARFDIE::ResolveTypeUID (const DIERef &die_ref) const
{
SymbolFileDWARF *dwarf = GetDWARF();
if (dwarf)
- return dwarf->ResolveTypeUID(uid);
+ return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true);
else
return nullptr;
}
@@ -302,6 +298,7 @@ DWARFDIE::GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const
{
if (IsValid())
{
+ dwarf_decl_ctx.SetLanguage(GetLanguage());
m_die->GetDWARFDeclContext (GetDWARF(), GetCU(), dwarf_decl_ctx);
}
else
@@ -530,6 +527,36 @@ DWARFDIE::Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const
}
+CompilerDecl
+DWARFDIE::GetDecl () const
+{
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclForUIDFromDWARF(*this);
+ else
+ return CompilerDecl();
+}
+
+CompilerDeclContext
+DWARFDIE::GetDeclContext () const
+{
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextForUIDFromDWARF(*this);
+ else
+ return CompilerDeclContext();
+}
+
+CompilerDeclContext
+DWARFDIE::GetContainingDeclContext () const
+{
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this);
+ else
+ return CompilerDeclContext();
+}
+
bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs)
{
return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index db37a45ad01a8..2dcd1d7dc43e1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -58,7 +58,7 @@ public:
//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------
- operator bool () const
+ explicit operator bool () const
{
return IsValid();
}
@@ -180,9 +180,11 @@ public:
lldb_private::Type *
ResolveType () const;
+ //----------------------------------------------------------------------
// Resolve a type by UID using this DIE's DWARF file
+ //----------------------------------------------------------------------
lldb_private::Type *
- ResolveTypeUID (lldb::user_id_t uid) const;
+ ResolveTypeUID (const DIERef &die_ref) const;
//----------------------------------------------------------------------
// Functions for obtaining DIE relations and references
@@ -245,6 +247,9 @@ public:
uint64_t
GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const;
+ DWARFDIE
+ GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const;
+
uint64_t
GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const;
@@ -270,6 +275,15 @@ public:
void
Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const;
+ lldb_private::CompilerDecl
+ GetDecl () const;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContext() const;
+
+ lldb_private::CompilerDeclContext
+ GetContainingDeclContext() const;
+
protected:
DWARFCompileUnit *m_cu;
DWARFDebugInfoEntry *m_die;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
index 9e021c7185bd6..e9f09fd8776ce 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
@@ -16,17 +16,6 @@
using namespace lldb_private;
using namespace std;
-bool
-DWARFDIECollection::Insert(const DWARFDIE &die)
-{
- iterator end_pos = m_dies.end();
- iterator insert_pos = upper_bound(m_dies.begin(), end_pos, die);
- if (insert_pos != end_pos && (*insert_pos == die))
- return false;
- m_dies.insert(insert_pos, die);
- return true;
-}
-
void
DWARFDIECollection::Append (const DWARFDIE &die)
{
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
index e39e1aa4ccda3..83d58ec49300f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
@@ -33,9 +33,6 @@ public:
DWARFDIE
GetDIEAtIndex (uint32_t idx) const;
- bool
- Insert(const DWARFDIE &die);
-
size_t
Size() const;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index a1b00d1892e91..417f2cd79bdac 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -209,48 +209,51 @@ DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr)
}
DWARFCompileUnit *
-DWARFDebugInfo::GetCompileUnitContainingDIE (const DIERef& die_ref)
+DWARFDebugInfo::GetCompileUnit (const DIERef& die_ref)
{
- dw_offset_t search_offset = die_ref.die_offset;
- bool is_cu_offset = false;
- if (m_dwarf2Data->GetID() == 0 && die_ref.cu_offset != DW_INVALID_OFFSET)
- {
- is_cu_offset = true;
- search_offset = die_ref.cu_offset;
- }
+ if (die_ref.cu_offset == DW_INVALID_OFFSET)
+ return GetCompileUnitContainingDIEOffset(die_ref.die_offset);
+ else
+ return GetCompileUnit(die_ref.cu_offset);
+}
+
+DWARFCompileUnit*
+DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset)
+{
+ ParseCompileUnitHeadersIfNeeded();
DWARFCompileUnitSP cu_sp;
- if (search_offset != DW_INVALID_OFFSET)
- {
- ParseCompileUnitHeadersIfNeeded();
- // Watch out for single compile unit executable as they are pretty common
- const size_t num_cus = m_compile_units.size();
- if (num_cus == 1)
- {
- if ((is_cu_offset && m_compile_units[0]->GetOffset() == search_offset) ||
- (!is_cu_offset && m_compile_units[0]->ContainsDIEOffset(search_offset)))
- {
- cu_sp = m_compile_units[0];
- }
- }
- else if (num_cus)
+ // Watch out for single compile unit executable as they are pretty common
+ const size_t num_cus = m_compile_units.size();
+ if (num_cus == 1)
+ {
+ if (m_compile_units[0]->ContainsDIEOffset(die_offset))
+ return m_compile_units[0].get();
+ }
+ else if (num_cus)
+ {
+ CompileUnitColl::const_iterator end_pos = m_compile_units.end();
+ CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
+ CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset);
+ if (pos != begin_pos)
{
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
- CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, search_offset, OffsetLessThanCompileUnitOffset);
- if (pos != begin_pos)
- {
- --pos;
- if ((is_cu_offset && (*pos)->GetOffset() == search_offset) ||
- (!is_cu_offset && (*pos)->ContainsDIEOffset(search_offset)))
- {
- cu_sp = *pos;
- }
- }
+ --pos;
+ if ((*pos)->ContainsDIEOffset(die_offset))
+ return (*pos).get();
}
}
- return cu_sp.get();
+
+ return nullptr;
+}
+
+DWARFDIE
+DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset)
+{
+ DWARFCompileUnit* cu = GetCompileUnitContainingDIEOffset(die_offset);
+ if (cu)
+ return cu->GetDIE(die_offset);
+ return DWARFDIE();
}
//----------------------------------------------------------------------
@@ -261,7 +264,7 @@ DWARFDebugInfo::GetCompileUnitContainingDIE (const DIERef& die_ref)
DWARFDIE
DWARFDebugInfo::GetDIE(const DIERef& die_ref)
{
- DWARFCompileUnit *cu = GetCompileUnitContainingDIE(die_ref);
+ DWARFCompileUnit *cu = GetCompileUnit(die_ref);
if (cu)
return cu->GetDIE (die_ref.die_offset);
return DWARFDIE(); // Not found
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index ea2e204db7029..7783135bdb95b 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -39,9 +39,10 @@ public:
size_t GetNumCompileUnits();
bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
DWARFCompileUnit* GetCompileUnitAtIndex (uint32_t idx);
- DWARFCompileUnit* GetCompileUnit (dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
- DWARFCompileUnit* GetCompileUnitContainingDIE (const DIERef& die_ref);
-
+ DWARFCompileUnit* GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
+ DWARFCompileUnit* GetCompileUnitContainingDIEOffset (dw_offset_t die_offset);
+ DWARFCompileUnit* GetCompileUnit(const DIERef& die_ref);
+ DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
DWARFDIE GetDIE (const DIERef& die_ref);
void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index b9d825489aef9..f48d8fc9eeb29 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -482,11 +482,19 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
case DW_AT_ranges:
{
const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(form_value.Unsigned(), ranges);
- // All DW_AT_ranges are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
- ranges.Slide(cu->GetBaseAddress());
+ if (debug_ranges)
+ {
+ debug_ranges->FindRanges(form_value.Unsigned(), ranges);
+ // All DW_AT_ranges are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ ranges.Slide(cu->GetBaseAddress());
+ }
+ else
+ {
+ cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute yet DWARF has no .debug_ranges, please file a bug and attach the file at the start of this error message",
+ m_offset, form_value.Unsigned());
+ }
}
break;
@@ -602,7 +610,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
{
if (die_ref.die_offset != DW_INVALID_OFFSET)
{
- DWARFDIE die = dwarf2Data->DebugInfo()->GetDIE(die_ref);
+ DWARFDIE die = dwarf2Data->GetDIE(die_ref);
if (die)
die.GetDIE()->GetDIENamesAndRanges(die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
}
@@ -934,7 +942,7 @@ DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu,
// referencing this DIE because curr_depth is not zero
break;
}
- // Fall through...
+ LLVM_FALLTHROUGH;
default:
attributes.Append(cu, offset, attr, form);
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 02bbff8defc0a..27b4fe93bc332 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -115,6 +115,13 @@ public:
DWARFAttributes& attrs,
uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
+ dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
+ const DWARFCompileUnit* cu,
+ const dw_attr_t attr,
+ DWARFFormValue& formValue,
+ dw_offset_t* end_attr_offset_ptr = nullptr,
+ bool check_specification_or_abstract_origin = false) const;
+
const char* GetAttributeValueAsString(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
@@ -382,12 +389,6 @@ public:
DWARFDebugInfoEntry::collection &die_collection);
protected:
- dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- DWARFFormValue& formValue,
- dw_offset_t* end_attr_offset_ptr = nullptr,
- bool check_specification_or_abstract_origin = false) const;
dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry
uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 4c29447b47bb8..2452274a293be 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -64,7 +64,8 @@ public:
};
DWARFDeclContext () :
- m_entries()
+ m_entries(),
+ m_language(lldb::eLanguageTypeUnknown)
{
}
@@ -115,10 +116,23 @@ public:
m_qualified_name.clear();
}
+ lldb::LanguageType
+ GetLanguage() const
+ {
+ return m_language;
+ }
+
+ void
+ SetLanguage(lldb::LanguageType language)
+ {
+ m_language = language;
+ }
+
protected:
typedef std::vector<Entry> collection;
collection m_entries;
mutable std::string m_qualified_name;
+ lldb::LanguageType m_language;
};
#endif // SymbolFileDWARF_DWARFDeclContext_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index a0ed9731a565d..addc14858461f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -167,6 +167,14 @@ DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) :
{
}
+void
+DWARFFormValue::Clear()
+{
+ m_cu = nullptr;
+ m_form = 0;
+ memset(&m_value, 0, sizeof(m_value));
+}
+
bool
DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr)
{
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index b10f4d3a0ac97..07bd038d94865 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -101,6 +101,7 @@ public:
static FixedFormSizes GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64);
static int Compare (const DWARFFormValue& a,
const DWARFFormValue& b);
+ void Clear();
protected:
const DWARFCompileUnit* m_cu; // Compile unit for this form
dw_form_t m_form; // Form for this value
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 0db416054ae8e..12e1e89c36bdb 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -220,7 +220,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
hash_data_has_fixed_byte_size = false;
- // Fall through to the cases below...
+ LLVM_FALLTHROUGH;
case DW_FORM_flag:
case DW_FORM_data1:
case DW_FORM_ref1:
@@ -230,7 +230,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_block2:
hash_data_has_fixed_byte_size = false;
- // Fall through to the cases below...
+ LLVM_FALLTHROUGH;
case DW_FORM_data2:
case DW_FORM_ref2:
min_hash_data_byte_size += 2;
@@ -238,7 +238,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_block4:
hash_data_has_fixed_byte_size = false;
- // Fall through to the cases below...
+ LLVM_FALLTHROUGH;
case DW_FORM_data4:
case DW_FORM_ref4:
case DW_FORM_addr:
@@ -346,7 +346,8 @@ DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data,
case eAtomTypeTag: // DW_TAG value for the DIE
hash_data.tag = (dw_tag_t)form_value.Unsigned ();
-
+ break;
+
case eAtomTypeTypeFlags: // Flags from enum TypeFlags
hash_data.type_flags = (uint32_t)form_value.Unsigned ();
break;
@@ -671,6 +672,9 @@ DWARFMappedHash::MemoryTable::AppendAllDIEsInRange (const uint32_t die_offset_st
size_t
DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEArray &die_offsets)
{
+ if (!name || !name[0])
+ return 0;
+
DIEInfoArray die_info_array;
if (FindByName(name, die_info_array))
DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
@@ -736,6 +740,9 @@ DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName (const char *name,
size_t
DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEInfoArray &die_info_array)
{
+ if (!name || !name[0])
+ return 0;
+
Pair kv_pair;
size_t old_size = die_info_array.size();
if (Find (name, kv_pair))
diff --git a/source/Plugins/SymbolFile/DWARF/Makefile b/source/Plugins/SymbolFile/DWARF/Makefile
deleted file mode 100644
index 509065650ab9e..0000000000000
--- a/source/Plugins/SymbolFile/DWARF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SymbolFile/DWARF/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSymbolFileDWARF
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 2088864bf6b19..942a5d62d9b45 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -35,16 +35,17 @@
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/DebugMacros.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
-#include "lldb/Symbol/TypeMap.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
@@ -54,7 +55,9 @@
#include "lldb/Utility/TaskPool.h"
#include "DWARFASTParser.h"
+#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
@@ -63,11 +66,10 @@
#include "DWARFDebugPubnames.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
-#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
#include "LogChannelDWARF.h"
-#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDebugMap.h"
+#include "SymbolFileDWARFDwo.h"
#include <map>
@@ -277,9 +279,11 @@ SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
TypeList *
SymbolFileDWARF::GetTypeList ()
{
- if (GetDebugMapSymfile ())
- return m_debug_map_symfile->GetTypeList();
- return m_obj_file->GetModule()->GetTypeList();
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetTypeList();
+ else
+ return m_obj_file->GetModule()->GetTypeList();
}
void
@@ -483,15 +487,17 @@ GetDWARFMachOSegmentName ()
UniqueDWARFASTTypeMap &
SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
{
- if (GetDebugMapSymfile ())
- return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
- return m_unique_ast_type_map;
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetUniqueDWARFASTTypeMap ();
+ else
+ return m_unique_ast_type_map;
}
TypeSystem *
SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
{
- SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
TypeSystem *type_system;
if (debug_map_symfile)
{
@@ -823,30 +829,13 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
DWARFDebugInfo* info = DebugInfo();
if (info)
{
- if (GetDebugMapSymfile ())
- {
- // The debug map symbol file made the compile units for this DWARF
- // file which is .o file with DWARF in it, and we should have
- // only 1 compile unit which is at offset zero in the DWARF.
- // TODO: modify to support LTO .o files where each .o file might
- // have multiple DW_TAG_compile_unit tags.
-
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
- }
- else
- {
- // Just a normal DWARF file whose user ID for the compile unit is
- // the DWARF offset itself
+ // Just a normal DWARF file whose user ID for the compile unit is
+ // the DWARF offset itself
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
-
- }
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
}
return NULL;
}
@@ -893,7 +882,7 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
{
return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
}
- else if (GetDebugMapSymfile ())
+ else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile ())
{
// Let the debug map create the compile unit
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
@@ -926,12 +915,8 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
bool is_optimized = dwarf_cu->GetIsOptimized ();
- cu_sp.reset(new CompileUnit (module_sp,
- dwarf_cu,
- cu_file_spec,
- dwarf_cu->GetID(),
- cu_language,
- is_optimized));
+ cu_sp.reset(new CompileUnit(module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), cu_language,
+ is_optimized ? eLazyBoolYes : eLazyBoolNo));
if (cu_sp)
{
// If we just created a compile unit with an invalid file spec, try and get the
@@ -1007,7 +992,7 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFD
bool
SymbolFileDWARF::FixupAddress (Address &addr)
{
- SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile)
{
return debug_map_symfile->LinkOSOAddress(addr);
@@ -1063,7 +1048,6 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec
if (cu_die)
{
const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
-
const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
if (stmt_list != DW_INVALID_OFFSET)
{
@@ -1082,7 +1066,17 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec
}
bool
-SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
+SymbolFileDWARF::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
+{
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
+ return dwarf_cu->GetIsOptimized();
+ return false;
+}
+
+bool
+SymbolFileDWARF::ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules)
{
assert (sc.comp_unit);
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
@@ -1091,9 +1085,40 @@ SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, st
if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
{
UpdateExternalModuleListIfNeeded();
- for (const auto &pair : m_external_type_modules)
+
+ if (sc.comp_unit)
{
- imported_modules.push_back(pair.first);
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+
+ if (die)
+ {
+ for (DWARFDIE child_die = die.GetFirstChild();
+ child_die;
+ child_die = child_die.GetSibling())
+ {
+ if (child_die.Tag() == DW_TAG_imported_declaration)
+ {
+ if (DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import))
+ {
+ if (module_die.Tag() == DW_TAG_module)
+ {
+ if (const char *name = module_die.GetAttributeValueAsString(DW_AT_name, nullptr))
+ {
+ ConstString const_name(name);
+ imported_modules.push_back(const_name);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (const auto &pair : m_external_type_modules)
+ {
+ imported_modules.push_back(pair.first);
+ }
}
}
}
@@ -1198,13 +1223,14 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- if (m_debug_map_symfile)
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
{
// We have an object file that has a line table with addresses
// that are not linked. We need to link the line table and convert
// the addresses that are relative to the .o file into addresses
// for the main executable.
- sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
+ sc.comp_unit->SetLineTable (debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
}
else
{
@@ -1439,63 +1465,71 @@ SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
ast_parser->GetDeclForUIDFromDWARF(decl);
}
+SymbolFileDWARF *
+SymbolFileDWARF::GetDWARFForUID (lldb::user_id_t uid)
+{
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
+ if (debug_map)
+ return debug_map->GetSymbolFileByOSOIndex(debug_map->GetOSOIndexFromUserID(uid));
+ return this;
+}
+
+DWARFDIE
+SymbolFileDWARF::GetDIEFromUID (lldb::user_id_t uid)
+{
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
+ if (dwarf)
+ return dwarf->GetDIE(DIERef(uid, dwarf));
+ return DWARFDIE();
+}
+
CompilerDecl
SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclForUIDFromDWARF(die);
- }
- }
- }
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDecl();
return CompilerDecl();
}
CompilerDeclContext
SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
- }
- }
- }
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDeclContext();
return CompilerDeclContext();
}
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
- }
- }
- }
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetContainingDeclContext();
return CompilerDeclContext();
}
@@ -1503,20 +1537,20 @@ SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
Type*
SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
- if (type_die)
- {
- const bool assert_not_being_parsed = true;
- return ResolveTypeUID (type_die, assert_not_being_parsed);
- }
- }
- }
- return NULL;
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE type_die = GetDIEFromUID(type_uid);
+ if (type_die)
+ return type_die.ResolveType();
+ else
+ return nullptr;
+}
+
+Type*
+SymbolFileDWARF::ResolveTypeUID (const DIERef &die_ref)
+{
+ return ResolveType (GetDIE(die_ref), true);
}
Type*
@@ -1573,35 +1607,36 @@ SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_pars
bool
SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
{
- CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+ CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
{
return true;
}
TypeSystem *type_system = compiler_type.GetTypeSystem();
- if (type_system)
- {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->CanCompleteType(compiler_type);
- }
- return false;
+
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return false;
+ DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ return ast_parser->GetClangASTImporter().CanImport(compiler_type);
}
bool
SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
{
- TypeSystem *type_system = compiler_type.GetTypeSystem();
- if (type_system)
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFile()->GetModule()->GetMutex());
+
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+ if (clang_type_system)
{
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))
- return dwarf_ast->CompleteType(compiler_type);
+ DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type))
+ return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
}
// We have a struct/union/class/enum that needs to be fully resolved.
- CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+ CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
if (die_it == GetForwardDeclClangTypeToDie().end())
{
@@ -1609,30 +1644,29 @@ SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
return true;
}
- DWARFDebugInfo* debug_info = DebugInfo();
- DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
-
- assert(UserIDMatches(die_it->getSecond().GetUID()) && "CompleteType called on the wrong SymbolFile");
-
- // Once we start resolving this type, remove it from the forward declaration
- // map in case anyone child members or other types require this type to get resolved.
- // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
- // are done.
- GetForwardDeclClangTypeToDie().erase (die_it);
+ DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
+ if (dwarf_die)
+ {
+ // Once we start resolving this type, remove it from the forward declaration
+ // map in case anyone child members or other types require this type to get resolved.
+ // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
+ // are done.
+ GetForwardDeclClangTypeToDie().erase (die_it);
- Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
+ Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
- if (log)
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
- "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
- dwarf_die.GetID(),
- dwarf_die.GetTagAsCString(),
- type->GetName().AsCString());
- assert (compiler_type);
- DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
+ if (log)
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
+ "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
+ dwarf_die.GetID(),
+ dwarf_die.GetTagAsCString(),
+ type->GetName().AsCString());
+ assert (compiler_type);
+ DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
+ }
return false;
}
@@ -1641,10 +1675,7 @@ SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed,
{
if (die)
{
- Type *type = GetDIEToType().lookup (die.GetDIE());
-
- if (type == NULL)
- type = GetTypeForDIE (die, resolve_function_context).get();
+ Type *type = GetTypeForDIE (die, resolve_function_context).get();
if (assert_not_being_parsed)
{
@@ -1730,6 +1761,55 @@ SymbolFileDWARF::GetDWOModule (ConstString name)
return lldb::ModuleSP();
}
+DWARFDIE
+SymbolFileDWARF::GetDIE (const DIERef &die_ref)
+{
+ DWARFDebugInfo * debug_info = DebugInfo();
+ if (debug_info)
+ return debug_info->GetDIE(die_ref);
+ else
+ return DWARFDIE();
+}
+
+
+std::unique_ptr<SymbolFileDWARFDwo>
+SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
+{
+ // If we are using a dSYM file, we never want the standard DWO files since
+ // the -gmodule support uses the same DWO machanism to specify full debug
+ // info files for modules.
+ if (GetDebugMapSymfile())
+ return nullptr;
+
+ const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
+ if (!dwo_name)
+ return nullptr;
+
+ FileSpec dwo_file(dwo_name, true);
+ if (dwo_file.IsRelative())
+ {
+ const char *comp_dir = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_comp_dir, nullptr);
+ if (!comp_dir)
+ return nullptr;
+
+ dwo_file.SetFile(comp_dir, true);
+ dwo_file.AppendPathComponent(dwo_name);
+ }
+
+ if (!dwo_file.Exists())
+ return nullptr;
+
+ const lldb::offset_t file_offset = 0;
+ DataBufferSP dwo_file_data_sp;
+ lldb::offset_t dwo_file_data_offset = 0;
+ ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(GetObjectFile()->GetModule(), &dwo_file, file_offset,
+ dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset);
+ if (dwo_obj_file == nullptr)
+ return nullptr;
+
+ return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
+}
+
void
SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
{
@@ -1760,9 +1840,25 @@ SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
{
ModuleSpec dwo_module_spec;
dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+ if (dwo_module_spec.GetFileSpec().IsRelative())
+ {
+ const char *comp_dir = die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
+ if (comp_dir)
+ {
+ dwo_module_spec.GetFileSpec().SetFile(comp_dir, true);
+ dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
+ }
+ }
dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
//printf ("Loading dwo = '%s'\n", dwo_path);
Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
+ if (!module_sp)
+ {
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: unable to locate module needed for external types: %s\nerror: %s\nDebugging will be degraded due to missing types. Rebuilding your project will regenerate the needed module files.",
+ die.GetOffset(),
+ dwo_module_spec.GetFileSpec().GetPath().c_str(),
+ error.AsCString("unknown error"));
+ }
}
m_external_type_modules[const_name] = module_sp;
}
@@ -1799,7 +1895,7 @@ SymbolFileDWARF::GetGlobalAranges()
const DWARFExpression &location = var_sp->LocationExpression();
Value location_result;
Error error;
- if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
+ if (location.Evaluate(nullptr, nullptr, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error))
{
if (location_result.GetValueType() == Value::eValueTypeFileAddress)
{
@@ -2094,6 +2190,9 @@ SymbolFileDWARF::Index ()
if (debug_info)
{
const uint32_t num_compile_units = GetNumCompileUnits();
+ if (num_compile_units == 0)
+ return;
+
std::vector<NameToDIE> function_basename_index(num_compile_units);
std::vector<NameToDIE> function_fullname_index(num_compile_units);
std::vector<NameToDIE> function_method_index(num_compile_units);
@@ -2102,7 +2201,8 @@ SymbolFileDWARF::Index ()
std::vector<NameToDIE> global_index(num_compile_units);
std::vector<NameToDIE> type_index(num_compile_units);
std::vector<NameToDIE> namespace_index(num_compile_units);
-
+
+ std::vector<bool> clear_cu_dies(num_compile_units, false);
auto parser_fn = [this,
debug_info,
&function_basename_index,
@@ -2115,25 +2215,62 @@ SymbolFileDWARF::Index ()
&namespace_index](uint32_t cu_idx)
{
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
-
- dwarf_cu->Index(function_basename_index[cu_idx],
- function_fullname_index[cu_idx],
- function_method_index[cu_idx],
- function_selector_index[cu_idx],
- objc_class_selectors_index[cu_idx],
- global_index[cu_idx],
- type_index[cu_idx],
- namespace_index[cu_idx]);
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- dwarf_cu->ClearDIEs(true);
-
+ if (dwarf_cu)
+ {
+ dwarf_cu->Index(function_basename_index[cu_idx],
+ function_fullname_index[cu_idx],
+ function_method_index[cu_idx],
+ function_selector_index[cu_idx],
+ objc_class_selectors_index[cu_idx],
+ global_index[cu_idx],
+ type_index[cu_idx],
+ namespace_index[cu_idx]);
+ }
return cu_idx;
};
+ auto extract_fn = [this,
+ debug_info,
+ num_compile_units](uint32_t cu_idx)
+ {
+ DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu)
+ {
+ // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
+ // DIEs for a compile unit have already been parsed.
+ return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
+ }
+ return std::make_pair(cu_idx, false);
+ };
+
+ // Create a task runner that extracts dies for each DWARF compile unit in a separate thread
+ TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner_extract.AddTask(extract_fn, cu_idx);
+
+ //----------------------------------------------------------------------
+ // First figure out which compile units didn't have their DIEs already
+ // parsed and remember this. If no DIEs were parsed prior to this index
+ // function call, we are going to want to clear the CU dies after we
+ // are done indexing to make sure we don't pull in all DWARF dies, but
+ // we need to wait until all compile units have been indexed in case
+ // a DIE in one compile unit refers to another and the indexes accesses
+ // those DIEs.
+ //----------------------------------------------------------------------
+ while (true)
+ {
+ auto f = task_runner_extract.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ unsigned cu_idx;
+ bool clear;
+ std::tie(cu_idx, clear) = f.get();
+ clear_cu_dies[cu_idx] = clear;
+ }
+
+ // Now create a task runner that can index each DWARF compile unit in a separate
+ // thread so we can index quickly.
+
TaskRunner<uint32_t> task_runner;
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
task_runner.AddTask(parser_fn, cu_idx);
@@ -2165,6 +2302,16 @@ SymbolFileDWARF::Index ()
[&]() { m_type_index.Finalize(); },
[&]() { m_namespace_index.Finalize(); });
+ //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any compile units if indexing
+ // caused us to load the compile unit's DIEs.
+ //----------------------------------------------------------------------
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ {
+ if (clear_cu_dies[cu_idx])
+ debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
+ }
+
#if defined (ENABLE_DEBUG_PRINTF)
StreamFile s(stdout, false);
s.Printf ("DWARF index for '%s':",
@@ -2265,12 +2412,11 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDec
sc.module_sp = m_obj_file->GetModule();
assert (sc.module_sp);
- DWARFDebugInfo* debug_info = DebugInfo();
bool done = false;
for (size_t i=0; i<num_die_matches && !done; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -2383,11 +2529,10 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -2971,9 +3116,20 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
const ConstString &name,
const CompilerDeclContext *parent_decl_ctx,
bool append,
- uint32_t max_matches,
+ uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap& types)
{
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ types.Clear();
+
+ // Make sure we haven't already searched this SymbolFile before...
+ if (searched_symbol_files.count(this))
+ return 0;
+ else
+ searched_symbol_files.insert(this);
+
DWARFDebugInfo* info = DebugInfo();
if (info == NULL)
return 0;
@@ -2996,10 +3152,6 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
max_matches);
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- types.Clear();
-
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
@@ -3026,11 +3178,10 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
if (num_die_matches)
{
const uint32_t initial_types_size = types.GetSize();
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_die_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -3097,6 +3248,7 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
parent_decl_ctx,
append,
max_matches,
+ searched_symbol_files,
types);
if (num_external_matches)
return num_external_matches;
@@ -3124,6 +3276,9 @@ SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
ConstString name = context.back().name;
+ if (!name)
+ return 0;
+
if (m_using_apple_tables)
{
if (m_apple_types_ap.get())
@@ -3145,11 +3300,10 @@ SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
if (num_die_matches)
{
size_t num_matches = 0;
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_die_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -3228,11 +3382,10 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -3447,11 +3600,10 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = debug_info->GetDIE (die_ref);
+ DWARFDIE type_die = GetDIE (die_ref);
if (type_die)
{
@@ -3667,18 +3819,26 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
}
const size_t num_matches = die_offsets.size();
-
-
+
+ // Get the type system that we are looking to find a type for. We will use this
+ // to ensure any matches we find are in a language that this type system supports
+ const LanguageType language = dwarf_decl_ctx.GetLanguage();
+ TypeSystem *type_system = (language == eLanguageTypeUnknown) ? nullptr : GetTypeSystemForLanguage(language);
+
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = debug_info->GetDIE (die_ref);
+ DWARFDIE type_die = GetDIE (die_ref);
if (type_die)
{
+ // Make sure type_die's langauge matches the type system we are looking for.
+ // We don't want to find a "Foo" type from Java if we are looking for a "Foo"
+ // type for C, C++, ObjC, or ObjC++.
+ if (type_system && !type_system->SupportsLanguage(type_die.GetLanguage()))
+ continue;
bool try_resolving_type = false;
// Don't try and resolve the DIE we are looking for with the DIE itself!
@@ -3919,7 +4079,7 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
if (sc.function)
{
- DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
+ DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
if (func_lo_pc != LLDB_INVALID_ADDRESS)
@@ -3974,11 +4134,10 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
@@ -4047,6 +4206,7 @@ SymbolFileDWARF::ParseVariableDIE
bool location_is_const_value_data = false;
bool has_explicit_location = false;
DWARFFormValue const_value;
+ Variable::RangeList scope_ranges;
//AccessType accessibility = eAccessNone;
for (i=0; i<num_attributes; ++i)
@@ -4156,19 +4316,47 @@ SymbolFileDWARF::ParseVariableDIE
}
break;
case DW_AT_specification:
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- spec_die = debug_info->GetDIE(DIERef(form_value));
+ spec_die = GetDIE(DIERef(form_value));
+ break;
+ case DW_AT_start_scope:
+ {
+ if (form_value.Form() == DW_FORM_sec_offset)
+ {
+ DWARFRangeList dwarf_scope_ranges;
+ const DWARFDebugRanges* debug_ranges = DebugRanges();
+ debug_ranges->FindRanges(form_value.Unsigned(), dwarf_scope_ranges);
+
+ // All DW_AT_start_scope are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ for (size_t i = 0, count = dwarf_scope_ranges.GetSize(); i < count; ++i)
+ {
+ const DWARFRangeList::Entry& range = dwarf_scope_ranges.GetEntryRef(i);
+ scope_ranges.Append(range.GetRangeBase() + die.GetCU()->GetBaseAddress(),
+ range.GetByteSize());
+ }
+ }
+ else
+ {
+ // TODO: Handle the case when DW_AT_start_scope have form constant. The
+ // dwarf spec is a bit ambiguous about what is the expected behavior in
+ // case the enclosing block have a non coninious address range and the
+ // DW_AT_start_scope entry have a form constant.
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_start_scope has unsupported form type (0x%x)\n",
+ die.GetID(),
+ form_value.Form());
+ }
+
+ scope_ranges.Sort();
+ scope_ranges.CombineConsecutiveRanges();
+ }
break;
- }
case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration:
case DW_AT_description:
case DW_AT_endianity:
case DW_AT_segment:
- case DW_AT_start_scope:
case DW_AT_visibility:
default:
case DW_AT_abstract_origin:
@@ -4232,6 +4420,7 @@ SymbolFileDWARF::ParseVariableDIE
GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
}
}
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
{
@@ -4240,9 +4429,6 @@ SymbolFileDWARF::ParseVariableDIE
else
scope = eValueTypeVariableStatic;
-
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
-
if (debug_map_symfile)
{
// When leaving the DWARF in the .o files on darwin,
@@ -4320,7 +4506,22 @@ SymbolFileDWARF::ParseVariableDIE
if (location_is_const_value_data)
scope = eValueTypeVariableStatic;
else
+ {
scope = eValueTypeVariableLocal;
+ if (debug_map_symfile)
+ {
+ // We need to check for TLS addresses that we need to fixup
+ if (location.ContainsThreadLocalStorage())
+ {
+ location.LinkThreadLocalStorage(
+ debug_map_symfile->GetObjectFile()->GetModule(),
+ [this, debug_map_symfile](lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
+ return debug_map_symfile->LinkOSOFileAddress(this, unlinked_file_addr);
+ });
+ scope = eValueTypeVariableThreadLocal;
+ }
+ }
+ }
}
}
@@ -4347,20 +4548,21 @@ SymbolFileDWARF::ParseVariableDIE
if (symbol_context_scope)
{
- SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID()));
-
+ SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
+
if (const_value.Form() && type_sp && type_sp->GetType())
location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
-
+
var_sp.reset (new Variable (die.GetID(),
- name,
+ name,
mangled,
type_sp,
- scope,
- symbol_context_scope,
- &decl,
- location,
- is_external,
+ scope,
+ symbol_context_scope,
+ scope_ranges,
+ &decl,
+ location,
+ is_external,
is_artificial,
is_static_member));
@@ -4505,7 +4707,7 @@ SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
// a concrete block counterpart in the current function. We need
// to find the concrete block so we can correctly add the
// variable to it
- const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
+ const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID(), this),
sc_parent_die.GetOffset());
if (concrete_block_die)
block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
@@ -4596,7 +4798,7 @@ SymbolFileDWARF::DumpIndexes ()
SymbolFileDWARFDebugMap *
-SymbolFileDWARF::GetDebugMapSymfile ()
+SymbolFileDWARF::GetDebugMapSymfile()
{
if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
{
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index be097595346ec..865e589627003 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -58,6 +58,7 @@ class DWARFDeclContext;
class DWARFDIECollection;
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
+class SymbolFileDWARFDwo;
#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
@@ -67,9 +68,12 @@ public:
friend class SymbolFileDWARFDebugMap;
friend class SymbolFileDWARFDwo;
friend class DebugMapModule;
+ friend struct DIERef;
friend class DWARFCompileUnit;
+ friend class DWARFDIE;
friend class DWARFASTParserClang;
friend class DWARFASTParserGo;
+ friend class DWARFASTParserJava;
//------------------------------------------------------------------
// Static Functions
@@ -133,8 +137,11 @@ public:
lldb_private::FileSpecList& support_files) override;
bool
- ParseImportedModules (const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
size_t
ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
@@ -156,6 +163,12 @@ public:
bool assert_not_being_parsed = true,
bool resolve_function_context = false);
+ SymbolFileDWARF *
+ GetDWARFForUID (lldb::user_id_t uid);
+
+ DWARFDIE
+ GetDIEFromUID (lldb::user_id_t uid);
+
lldb_private::CompilerDecl
GetDeclForUID (lldb::user_id_t uid) override;
@@ -218,6 +231,7 @@ public:
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append,
uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap& types) override;
size_t
@@ -299,12 +313,6 @@ public:
GetCompUnitForDWARFCompUnit(DWARFCompileUnit* dwarf_cu,
uint32_t cu_idx = UINT32_MAX);
- lldb::user_id_t
- MakeUserID (dw_offset_t die_offset) const
- {
- return GetID() | die_offset;
- }
-
size_t
GetObjCMethodDIEOffsets (lldb_private::ConstString class_name,
DIEArray &method_die_offsets);
@@ -327,6 +335,12 @@ public:
lldb::ModuleSP
GetDWOModule (lldb_private::ConstString name);
+ virtual DWARFDIE
+ GetDIE(const DIERef &die_ref);
+
+ virtual std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die);
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
@@ -387,8 +401,10 @@ protected:
bool *type_is_new);
lldb_private::Type *
- ResolveTypeUID (const DWARFDIE &die,
- bool assert_not_being_parsed);
+ ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed);
+
+ lldb_private::Type *
+ ResolveTypeUID(const DIERef &die_ref);
lldb::VariableSP
ParseVariableDIE(const lldb_private::SymbolContext& sc,
@@ -483,15 +499,6 @@ protected:
GetUniqueDWARFASTTypeMap ();
bool
- UserIDMatches (lldb::user_id_t uid) const
- {
- const lldb::user_id_t high_uid = uid & 0xffffffff00000000ull;
- if (high_uid != 0 && GetID() != 0)
- return high_uid == GetID();
- return true;
- }
-
- bool
DIEDeclContextsMatch (const DWARFDIE &die1,
const DWARFDIE &die2);
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index be25dfc99deea..ca819624c715d 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -123,8 +123,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
// Add the inverse OSO file address to debug map entry mapping
exe_symfile->AddOSOFileRange (this,
exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
oso_fun_symbol->GetAddressRef().GetFileAddress(),
- std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
+ oso_fun_symbol->GetByteSize());
}
}
@@ -157,8 +158,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
// Add the inverse OSO file address to debug map entry mapping
exe_symfile->AddOSOFileRange (this,
exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
oso_gsym_symbol->GetAddressRef().GetFileAddress(),
- std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
+ oso_gsym_symbol->GetByteSize());
}
}
break;
@@ -206,7 +208,7 @@ public:
ObjectFile *oso_objfile = GetObjectFile ();
if (oso_objfile)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
if (symbol_vendor)
{
@@ -635,13 +637,9 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
// zero in each .o file since each .o file can only have
// one compile unit for now.
lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
- NULL,
- so_file_spec,
- cu_id,
- eLanguageTypeUnknown,
- false));
-
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
+ m_obj_file->GetModule(), NULL, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate));
+
if (m_compile_unit_infos[cu_idx].compile_unit_sp)
{
// Let our symbol vendor know about this compile unit
@@ -725,7 +723,16 @@ SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc,
}
bool
-SymbolFileDWARFDebugMap::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
+SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
+{
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitIsOptimized(sc);
+ return false;
+}
+
+bool
+SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
{
SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
if (oso_dwarf)
@@ -1276,7 +1283,8 @@ SymbolFileDWARFDebugMap::FindTypes
const ConstString &name,
const CompilerDeclContext *parent_decl_ctx,
bool append,
- uint32_t max_matches,
+ uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap& types
)
{
@@ -1290,13 +1298,16 @@ SymbolFileDWARFDebugMap::FindTypes
{
oso_dwarf = GetSymbolFile (sc);
if (oso_dwarf)
- return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types);
+ return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
}
else
{
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types);
- return false;
+ oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
+ if (types.GetSize() >= max_matches)
+ return true;
+ else
+ return false;
});
}
@@ -1452,6 +1463,7 @@ SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext
bool
SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size,
lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size)
{
@@ -1460,7 +1472,14 @@ SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
{
DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
- cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
+ addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0)
+ {
+ range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0)
+ range_size = 1;
+ }
+ cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
return true;
}
return false;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 1eb33c927bdfb..fcf02975a58fb 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -65,6 +65,8 @@ public:
bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override;
bool ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override;
bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files) override;
+ bool
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
bool ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override;
size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
size_t ParseTypes (const lldb_private::SymbolContext& sc) override;
@@ -82,7 +84,7 @@ public:
uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
uint32_t FindFunctions (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override;
uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override;
- uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::TypeMap& types) override;
+ uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap& types) override;
lldb_private::CompilerDeclContext
FindNamespace (const lldb_private::SymbolContext& sc,
const lldb_private::ConstString &name,
@@ -107,10 +109,11 @@ protected:
kNumFlags
};
- friend class DWARFCompileUnit;
- friend class SymbolFileDWARF;
friend class DebugMapModule;
+ friend struct DIERef;
friend class DWARFASTParserClang;
+ friend class DWARFCompileUnit;
+ friend class SymbolFileDWARF;
struct OSOInfo
{
lldb::ModuleSP module_sp;
@@ -348,6 +351,7 @@ protected:
bool
AddOSOFileRange (CompileUnitInfo *cu_info,
lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size,
lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size);
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 326c397c83d56..14603aa460c9e 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
@@ -129,3 +130,10 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language)
{
return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
}
+
+DWARFDIE
+SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref)
+{
+ lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
+ return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 39ed6502229b5..9391a28249482 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -38,6 +38,15 @@ public:
lldb_private::TypeSystem*
GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ DWARFDIE
+ GetDIE(const DIERef &die_ref) override;
+
+ std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) override
+ {
+ return nullptr;
+ }
+
protected:
void
LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data) override;
diff --git a/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
new file mode 100644
index 0000000000000..79d8a25d6979d
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LLVM_PRIVATE_LINK_COMPONENTS
+ DebugInfoPDB)
+
+add_lldb_library(lldbPluginSymbolFilePDB
+ PDBASTParser.cpp
+ SymbolFilePDB.cpp
+ )
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
new file mode 100644
index 0000000000000..1e8e040fd47c9
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -0,0 +1,237 @@
+//===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PDBASTParser.h"
+
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/Declaration.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeSystem.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+using namespace llvm::pdb;
+
+namespace
+{
+int
+TranslateUdtKind(PDB_UdtType pdb_kind)
+{
+ switch (pdb_kind)
+ {
+ case PDB_UdtType::Class:
+ return clang::TTK_Class;
+ case PDB_UdtType::Struct:
+ return clang::TTK_Struct;
+ case PDB_UdtType::Union:
+ return clang::TTK_Union;
+ case PDB_UdtType::Interface:
+ return clang::TTK_Interface;
+ }
+ return clang::TTK_Class;
+}
+
+lldb::Encoding
+TranslateBuiltinEncoding(PDB_BuiltinType type)
+{
+ switch (type)
+ {
+ case PDB_BuiltinType::Float:
+ return lldb::eEncodingIEEE754;
+ case PDB_BuiltinType::Int:
+ case PDB_BuiltinType::Long:
+ case PDB_BuiltinType::Char:
+ return lldb::eEncodingSint;
+ case PDB_BuiltinType::Bool:
+ case PDB_BuiltinType::UInt:
+ case PDB_BuiltinType::ULong:
+ case PDB_BuiltinType::HResult:
+ return lldb::eEncodingUint;
+ default:
+ return lldb::eEncodingInvalid;
+ }
+}
+}
+
+PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast)
+{
+}
+
+PDBASTParser::~PDBASTParser()
+{
+}
+
+// DebugInfoASTParser interface
+
+lldb::TypeSP
+PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type)
+{
+ // PDB doesn't maintain enough information to robustly rebuild the entire
+ // tree, and this is most problematic when it comes to figure out the
+ // right DeclContext to put a type in. So for now, everything goes in
+ // the translation unit decl as a fully qualified type.
+ clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
+ Declaration decl;
+
+ if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type))
+ {
+ AccessType access = lldb::eAccessPublic;
+ PDB_UdtType udt_kind = udt->getUdtKind();
+
+ if (udt_kind == PDB_UdtType::Class)
+ access = lldb::eAccessPrivate;
+
+ CompilerType clang_type =
+ m_ast.CreateRecordType(tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(udt->getName()),
+ udt->getLength(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ clang_type, Type::eResolveStateForward);
+ }
+ else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type))
+ {
+ std::string name = enum_type->getName();
+ lldb::Encoding encoding = TranslateBuiltinEncoding(enum_type->getBuiltinType());
+ uint64_t bytes = enum_type->getLength();
+ CompilerType builtin_type = m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
+
+ CompilerType ast_enum = m_ast.CreateEnumerationType(name.c_str(), tu_decl_ctx, decl, builtin_type);
+ auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
+ while (auto enum_value = enum_values->getNext())
+ {
+ if (enum_value->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ AddEnumValue(ast_enum, *enum_value);
+ }
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ast_enum, Type::eResolveStateFull);
+ }
+ else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type))
+ {
+ Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+ std::string name = type_def->getName();
+ uint64_t bytes = type_def->getLength();
+ if (!target_type)
+ return nullptr;
+ CompilerType target_ast_type = target_type->GetFullCompilerType();
+ CompilerDeclContext target_decl_ctx = m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
+ CompilerType ast_typedef = m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
+ return std::make_shared<Type>(type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
+ nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl, ast_typedef,
+ Type::eResolveStateFull);
+ }
+ else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type))
+ {
+ auto arg_enum = func_sig->getArguments();
+ uint32_t num_args = arg_enum->getChildCount();
+ std::vector<CompilerType> arg_list(num_args);
+ while (auto arg = arg_enum->getNext())
+ {
+ Type *arg_type = m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this function signature, bail.
+ if (!arg_type)
+ return nullptr;
+ CompilerType arg_ast_type = arg_type->GetFullCompilerType();
+ arg_list.push_back(arg_ast_type);
+ }
+ auto pdb_return_type = func_sig->getReturnType();
+ Type *return_type = m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this function signature, bail.
+ if (!return_type)
+ return nullptr;
+ CompilerType return_ast_type = return_type->GetFullCompilerType();
+ uint32_t type_quals = 0;
+ if (func_sig->isConstType())
+ type_quals |= clang::Qualifiers::Const;
+ if (func_sig->isVolatileType())
+ type_quals |= clang::Qualifiers::Volatile;
+ CompilerType func_sig_ast_type =
+ m_ast.CreateFunctionType(return_ast_type, &arg_list[0], num_args, false, type_quals);
+
+ return std::make_shared<Type>(func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_sig_ast_type,
+ Type::eResolveStateFull);
+ }
+ else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type))
+ {
+ uint32_t num_elements = array_type->getCount();
+ uint32_t element_uid = array_type->getElementType()->getSymIndexId();
+ uint32_t bytes = array_type->getLength();
+
+ Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+ CompilerType element_ast_type = element_type->GetFullCompilerType();
+ CompilerType array_ast_type = m_ast.CreateArrayType(element_ast_type, num_elements, false);
+ return std::make_shared<Type>(array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), bytes, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, array_ast_type,
+ Type::eResolveStateFull);
+ }
+ return nullptr;
+}
+
+bool
+PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) const
+{
+ Declaration decl;
+ Variant v = enum_value.getValue();
+ std::string name = enum_value.getName();
+ int64_t raw_value;
+ switch (v.Type)
+ {
+ case PDB_VariantType::Int8:
+ raw_value = v.Value.Int8;
+ break;
+ case PDB_VariantType::Int16:
+ raw_value = v.Value.Int16;
+ break;
+ case PDB_VariantType::Int32:
+ raw_value = v.Value.Int32;
+ break;
+ case PDB_VariantType::Int64:
+ raw_value = v.Value.Int64;
+ break;
+ case PDB_VariantType::UInt8:
+ raw_value = v.Value.UInt8;
+ break;
+ case PDB_VariantType::UInt16:
+ raw_value = v.Value.UInt16;
+ break;
+ case PDB_VariantType::UInt32:
+ raw_value = v.Value.UInt32;
+ break;
+ case PDB_VariantType::UInt64:
+ raw_value = v.Value.UInt64;
+ break;
+ default:
+ return false;
+ }
+ CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+ uint32_t byte_size = m_ast.getASTContext()->getTypeSize(ClangUtil::GetQualType(underlying_type));
+ return m_ast.AddEnumerationValueToEnumerationType(enum_type.GetOpaqueQualType(), underlying_type, decl,
+ name.c_str(), raw_value, byte_size * 8);
+}
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
new file mode 100644
index 0000000000000..ca425c17c4515
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -0,0 +1,58 @@
+//===-- PDBASTParser.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+#define LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+
+#include "lldb/lldb-forward.h"
+
+#include "lldb/Symbol/ClangASTImporter.h"
+
+namespace clang
+{
+class CharUnits;
+class CXXRecordDecl;
+class FieldDecl;
+class RecordDecl;
+}
+
+namespace lldb_private
+{
+class ClangASTContext;
+class CompilerType;
+}
+
+namespace llvm
+{
+namespace pdb
+{
+class PDBSymbol;
+class PDBSymbolData;
+class PDBSymbolTypeBuiltin;
+}
+}
+
+class PDBASTParser
+{
+public:
+ PDBASTParser(lldb_private::ClangASTContext &ast);
+ ~PDBASTParser();
+
+ lldb::TypeSP
+ CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
+
+private:
+ bool
+ AddEnumValue(lldb_private::CompilerType enum_type, const llvm::pdb::PDBSymbolData &data) const;
+
+ lldb_private::ClangASTContext &m_ast;
+ lldb_private::ClangASTImporter m_ast_importer;
+};
+
+#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
new file mode 100644
index 0000000000000..d8092c011acb6
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -0,0 +1,733 @@
+//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFilePDB.h"
+
+#include "clang/Lex/Lexer.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/TypeMap.h"
+
+#include "llvm/DebugInfo/PDB/GenericError.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
+
+#include <regex>
+
+using namespace lldb_private;
+using namespace llvm::pdb;
+
+namespace
+{
+lldb::LanguageType
+TranslateLanguage(PDB_Lang lang)
+{
+ switch (lang)
+ {
+ case PDB_Lang::Cpp:
+ return lldb::LanguageType::eLanguageTypeC_plus_plus;
+ case PDB_Lang::C:
+ return lldb::LanguageType::eLanguageTypeC;
+ default:
+ return lldb::LanguageType::eLanguageTypeUnknown;
+ }
+ }
+
+ bool
+ ShouldAddLine(uint32_t requested_line, uint32_t actual_line, uint32_t addr_length)
+ {
+ return ((requested_line == 0 || actual_line == requested_line) && addr_length > 0);
+ }
+}
+
+void
+SymbolFilePDB::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+}
+
+void
+SymbolFilePDB::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+void
+SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger)
+{
+}
+
+lldb_private::ConstString
+SymbolFilePDB::GetPluginNameStatic()
+{
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+const char *
+SymbolFilePDB::GetPluginDescriptionStatic()
+{
+ return "Microsoft PDB debug symbol file reader.";
+}
+
+lldb_private::SymbolFile *
+SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file)
+{
+ return new SymbolFilePDB(obj_file);
+}
+
+SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
+ : SymbolFile(object_file), m_cached_compile_unit_count(0)
+{
+}
+
+SymbolFilePDB::~SymbolFilePDB()
+{
+}
+
+uint32_t
+SymbolFilePDB::CalculateAbilities()
+{
+ if (!m_session_up)
+ {
+ // Lazily load and match the PDB file, but only do this once.
+ std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), m_session_up);
+ if (error)
+ {
+ llvm::consumeError(std::move(error));
+ return 0;
+ }
+ }
+ return CompileUnits | LineTables;
+}
+
+void
+SymbolFilePDB::InitializeObject()
+{
+ lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
+ m_session_up->setLoadAddress(obj_load_address);
+
+ TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(type_system, clang_type_system->GetTranslationUnitDecl());
+}
+
+uint32_t
+SymbolFilePDB::GetNumCompileUnits()
+{
+ if (m_cached_compile_unit_count == 0)
+ {
+ auto global = m_session_up->getGlobalScope();
+ auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ m_cached_compile_unit_count = compilands->getChildCount();
+
+ // The linker can inject an additional "dummy" compilation unit into the PDB.
+ // Ignore this special compile unit for our purposes, if it is there. It is
+ // always the last one.
+ auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
+ std::string name = last_cu->getName();
+ if (name == "* Linker *")
+ --m_cached_compile_unit_count;
+ }
+ return m_cached_compile_unit_count;
+}
+
+lldb::CompUnitSP
+SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index)
+{
+ auto global = m_session_up->getGlobalScope();
+ auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ auto cu = compilands->getChildAtIndex(index);
+
+ uint32_t id = cu->getSymIndexId();
+
+ return ParseCompileUnitForSymIndex(id);
+}
+
+lldb::LanguageType
+SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc)
+{
+ // What fields should I expect to be filled out on the SymbolContext? Is it
+ // safe to assume that `sc.comp_unit` is valid?
+ if (!sc.comp_unit)
+ return lldb::eLanguageTypeUnknown;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
+ if (!cu)
+ return lldb::eLanguageTypeUnknown;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ return lldb::eLanguageTypeUnknown;
+ return TranslateLanguage(details->getLanguage());
+}
+
+size_t
+SymbolFilePDB::ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc)
+{
+ return ParseCompileUnitLineTable(sc, 0);
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc)
+{
+ // PDB doesn't contain information about macros
+ return false;
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files)
+{
+ if (!sc.comp_unit)
+ return false;
+
+ // In theory this is unnecessary work for us, because all of this information is easily
+ // (and quickly) accessible from DebugInfoPDB, so caching it a second time seems like a waste.
+ // Unfortunately, there's no good way around this short of a moderate refactor, since SymbolVendor
+ // depends on being able to cache this list.
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
+ if (!cu)
+ return false;
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+ if (!files || files->getChildCount() == 0)
+ return false;
+
+ while (auto file = files->getNext())
+ {
+ FileSpec spec(file->getFileName(), false);
+ support_files.Append(spec);
+ }
+ return true;
+}
+
+bool
+SymbolFilePDB::ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules)
+{
+ // PDB does not yet support module debug info
+ return false;
+}
+
+size_t
+SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+size_t
+SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+size_t
+SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+lldb_private::Type *
+SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid)
+{
+ auto find_result = m_types.find(type_uid);
+ if (find_result != m_types.end())
+ return find_result->second.get();
+
+ TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return nullptr;
+ PDBASTParser *pdb = llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
+ if (!pdb)
+ return nullptr;
+
+ auto pdb_type = m_session_up->getSymbolById(type_uid);
+ if (pdb_type == nullptr)
+ return nullptr;
+
+ lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
+ m_types.insert(std::make_pair(type_uid, result));
+ return result.get();
+}
+
+bool
+SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type)
+{
+ // TODO: Implement this
+ return false;
+}
+
+lldb_private::CompilerDecl
+SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid)
+{
+ return lldb_private::CompilerDecl();
+}
+
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid)
+{
+ // PDB always uses the translation unit decl context for everything. We can improve this later
+ // but it's not easy because PDB doesn't provide a high enough level of type fidelity in this area.
+ return *m_tu_decl_ctx_up;
+}
+
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid)
+{
+ return *m_tu_decl_ctx_up;
+}
+
+void
+SymbolFilePDB::ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)
+{
+}
+
+uint32_t
+SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list)
+{
+ if (resolve_scope & lldb::eSymbolContextCompUnit)
+ {
+ // Locate all compilation units with line numbers referencing the specified file. For example, if
+ // `file_spec` is <vector>, then this should return all source files and header files that reference
+ // <vector>, either directly or indirectly.
+ auto compilands =
+ m_session_up->findCompilandsForSourceFile(file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
+
+ // For each one, either find get its previously parsed data, or parse it afresh and add it to
+ // the symbol context list.
+ while (auto compiland = compilands->getNext())
+ {
+ // If we're not checking inlines, then don't add line information for this file unless the FileSpec
+ // matches.
+ if (!check_inlines)
+ {
+ // `getSourceFileName` returns the basename of the original source file used to generate this compiland.
+ // It does not return the full path. Currently the only way to get that is to do a basename lookup to
+ // get the IPDBSourceFile, but this is ambiguous in the case of two source files with the same name
+ // contributing to the same compiland. This is a moderately extreme edge case, so we consider this ok
+ // for now, although we need to find a long term solution.
+ std::string source_file = compiland->getSourceFileName();
+ auto pdb_file = m_session_up->findOneSourceFile(compiland.get(), source_file,
+ PDB_NameSearchFlags::NS_CaseInsensitive);
+ source_file = pdb_file->getFileName();
+ FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
+ if (!file_spec.FileEquals(this_spec))
+ continue;
+ }
+
+ SymbolContext sc;
+ auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
+ sc.comp_unit = cu.get();
+ sc.module_sp = cu->GetModule();
+ sc_list.Append(sc);
+
+ // If we were asked to resolve line entries, add all entries to the line table that match the requested
+ // line (or all lines if `line` == 0)
+ if (resolve_scope & lldb::eSymbolContextLineEntry)
+ ParseCompileUnitLineTable(sc, line);
+ }
+ }
+ return sc_list.GetSize();
+}
+
+uint32_t
+SymbolFilePDB::FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches, lldb_private::VariableList &variables)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex, bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::FindFunctions(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+ bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list)
+{
+ return uint32_t();
+}
+
+void
+SymbolFilePDB::GetMangledNamesForFunction(const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names)
+{
+}
+
+uint32_t
+SymbolFilePDB::FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types)
+{
+ if (!append)
+ types.Clear();
+ if (!name)
+ return 0;
+
+ searched_symbol_files.clear();
+ searched_symbol_files.insert(this);
+
+ std::string name_str = name.AsCString();
+
+ // If this might be a regex, we have to return EVERY symbol and process them one by one, which is going
+ // to destroy performance on large PDB files. So try really hard not to use a regex match.
+ if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
+ FindTypesByRegex(name_str, max_matches, types);
+ else
+ FindTypesByName(name_str, max_matches, types);
+ return types.GetSize();
+}
+
+void
+SymbolFilePDB::FindTypesByRegex(const std::string &regex, uint32_t max_matches, lldb_private::TypeMap &types)
+{
+ // When searching by regex, we need to go out of our way to limit the search space as much as possible, since
+ // the way this is implemented is by searching EVERYTHING in the PDB and manually doing a regex compare. PDB
+ // library isn't optimized for regex searches or searches across multiple symbol types at the same time, so the
+ // best we can do is to search enums, then typedefs, then classes one by one, and do a regex compare against all
+ // of them.
+ PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, PDB_SymType::UDT};
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+
+ std::regex re(regex);
+
+ uint32_t matches = 0;
+
+ for (auto tag : tags_to_search)
+ {
+ results = global->findAllChildren(tag);
+ while (auto result = results->getNext())
+ {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+
+ std::string type_name;
+ if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
+ type_name = enum_type->getName();
+ else if (auto typedef_type = llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
+ type_name = typedef_type->getName();
+ else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
+ type_name = class_type->getName();
+ else
+ {
+ // We're only looking for types that have names. Skip symbols, as well as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
+
+ if (!std::regex_match(type_name, re))
+ continue;
+
+ // This should cause the type to get cached and stored in the `m_types` lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
+ }
+}
+
+void
+SymbolFilePDB::FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types)
+{
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+ results = global->findChildren(PDB_SymType::None, name.c_str(), PDB_NameSearchFlags::NS_Default);
+
+ uint32_t matches = 0;
+
+ while (auto result = results->getNext())
+ {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+ switch (result->getSymTag())
+ {
+ case PDB_SymType::Enum:
+ case PDB_SymType::UDT:
+ case PDB_SymType::Typedef:
+ break;
+ default:
+ // We're only looking for types that have names. Skip symbols, as well as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
+
+ // This should cause the type to get cached and stored in the `m_types` lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
+}
+
+size_t
+SymbolFilePDB::FindTypes(const std::vector<lldb_private::CompilerContext> &contexts, bool append,
+ lldb_private::TypeMap &types)
+{
+ return 0;
+}
+
+lldb_private::TypeList *
+SymbolFilePDB::GetTypeList()
+{
+ return nullptr;
+}
+
+size_t
+SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
+ lldb_private::TypeList &type_list)
+{
+ return size_t();
+}
+
+lldb_private::TypeSystem *
+SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language)
+{
+ auto type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ return type_system;
+}
+
+lldb_private::CompilerDeclContext
+SymbolFilePDB::FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx)
+{
+ return lldb_private::CompilerDeclContext();
+}
+
+lldb_private::ConstString
+SymbolFilePDB::GetPluginName()
+{
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+uint32_t
+SymbolFilePDB::GetPluginVersion()
+{
+ return 1;
+}
+
+IPDBSession &
+SymbolFilePDB::GetPDBSession()
+{
+ return *m_session_up;
+}
+
+const IPDBSession &
+SymbolFilePDB::GetPDBSession() const
+{
+ return *m_session_up;
+}
+
+lldb::CompUnitSP
+SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id)
+{
+ auto found_cu = m_comp_units.find(id);
+ if (found_cu != m_comp_units.end())
+ return found_cu->second;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
+
+ // `getSourceFileName` returns the basename of the original source file used to generate this compiland. It does
+ // not return the full path. Currently the only way to get that is to do a basename lookup to get the
+ // IPDBSourceFile, but this is ambiguous in the case of two source files with the same name contributing to the
+ // same compiland. This is a moderately extreme edge case, so we consider this ok for now, although we need to find
+ // a long term solution.
+ auto file =
+ m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), PDB_NameSearchFlags::NS_CaseInsensitive);
+ std::string path = file->getFileName();
+
+ lldb::LanguageType lang;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ lang = lldb::eLanguageTypeC_plus_plus;
+ else
+ lang = TranslateLanguage(details->getLanguage());
+
+ // Don't support optimized code for now, DebugInfoPDB does not return this information.
+ LazyBool optimized = eLazyBoolNo;
+ auto result = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
+ m_comp_units.insert(std::make_pair(id, result));
+ return result;
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line)
+{
+ auto global = m_session_up->getGlobalScope();
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
+
+ // LineEntry needs the *index* of the file into the list of support files returned by
+ // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally unique
+ // idenfitifier in the namespace of the PDB. So, we have to do a mapping so that we
+ // can hand out indices.
+ llvm::DenseMap<uint32_t, uint32_t> index_map;
+ BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
+ auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
+
+ // Find contributions to `cu` from all source and header files.
+ std::string path = sc.comp_unit->GetPath();
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+
+ // For each source and header file, create a LineSequence for contributions to the cu
+ // from that file, and add the sequence.
+ while (auto file = files->getNext())
+ {
+ std::unique_ptr<LineSequence> sequence(line_table->CreateLineSequenceContainer());
+ auto lines = m_session_up->findLineNumbers(*cu, *file);
+ int entry_count = lines->getChildCount();
+
+ uint64_t prev_addr;
+ uint32_t prev_length;
+ uint32_t prev_line;
+ uint32_t prev_source_idx;
+
+ for (int i = 0; i < entry_count; ++i)
+ {
+ auto line = lines->getChildAtIndex(i);
+
+ uint64_t lno = line->getLineNumber();
+ uint64_t addr = line->getVirtualAddress();
+ uint32_t length = line->getLength();
+ uint32_t source_id = line->getSourceFileId();
+ uint32_t col = line->getColumnNumber();
+ uint32_t source_idx = index_map[source_id];
+
+ // There was a gap between the current entry and the previous entry if the addresses don't perfectly line
+ // up.
+ bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
+
+ // Before inserting the current entry, insert a terminal entry at the end of the previous entry's address
+ // range if the current entry resulted in a gap from the previous entry.
+ if (is_gap && ShouldAddLine(match_line, prev_line, prev_length))
+ {
+ line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ if (ShouldAddLine(match_line, lno, length))
+ {
+ bool is_statement = line->isStatement();
+ bool is_prologue = false;
+ bool is_epilogue = false;
+ auto func = m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
+ if (func)
+ {
+ auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
+ is_prologue = (addr == prologue->getVirtualAddress());
+
+ auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
+ is_epilogue = (addr == epilogue->getVirtualAddress());
+ }
+
+ line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, source_idx, is_statement, false,
+ is_prologue, is_epilogue, false);
+ }
+
+ prev_addr = addr;
+ prev_length = length;
+ prev_line = lno;
+ prev_source_idx = source_idx;
+ }
+
+ if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length))
+ {
+ // The end is always a terminal entry, so insert it regardless.
+ line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ line_table->InsertSequence(sequence.release());
+ }
+
+ sc.comp_unit->SetLineTable(line_table.release());
+ return true;
+}
+
+void
+SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(const PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const
+{
+ // This is a hack, but we need to convert the source id into an index into the support
+ // files array. We don't want to do path comparisons to avoid basename / full path
+ // issues that may or may not even be a problem, so we use the globally unique source
+ // file identifiers. Ideally we could use the global identifiers everywhere, but LineEntry
+ // currently assumes indices.
+ auto source_files = m_session_up->getSourceFilesForCompiland(cu);
+ int index = 0;
+
+ while (auto file = source_files->getNext())
+ {
+ uint32_t source_id = file->getUniqueId();
+ index_map[source_id] = index++;
+ }
+}
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
new file mode 100644
index 0000000000000..cf75de8ac78e3
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -0,0 +1,204 @@
+//===-- SymbolFilePDB.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/SymbolFile.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
+
+class SymbolFilePDB : public lldb_private::SymbolFile
+{
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static void
+ DebuggerInitialize(lldb_private::Debugger &debugger);
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFilePDB(lldb_private::ObjectFile *ofile);
+
+ ~SymbolFilePDB() override;
+
+ uint32_t
+ CalculateAbilities() override;
+
+ void
+ InitializeObject() override;
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+
+ uint32_t
+ GetNumCompileUnits() override;
+
+ lldb::CompUnitSP
+ ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
+
+ bool
+ ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
+
+ size_t
+ ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
+
+ size_t
+ ParseTypes(const lldb_private::SymbolContext &sc) override;
+
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+
+ lldb_private::Type *
+ ResolveTypeUID(lldb::user_id_t type_uid) override;
+
+ bool
+ CompleteType(lldb_private::CompilerType &compiler_type) override;
+
+ lldb_private::CompilerDecl
+ GetDeclForUID(lldb::user_id_t uid) override;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
+
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+
+ uint32_t
+ ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
+
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) override;
+
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches, lldb_private::VariableList &variables) override;
+
+ uint32_t
+ FindGlobalVariables(const lldb_private::RegularExpression &regex, bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+
+ uint32_t
+ FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
+
+ uint32_t
+ FindFunctions(const lldb_private::RegularExpression &regex, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
+
+ void
+ GetMangledNamesForFunction(const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) override;
+
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override;
+
+ size_t
+ FindTypes(const std::vector<lldb_private::CompilerContext> &context, bool append,
+ lldb_private::TypeMap &types) override;
+
+ lldb_private::TypeList *
+ GetTypeList() override;
+
+ size_t
+ GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
+
+ lldb_private::TypeSystem *
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
+
+ lldb_private::CompilerDeclContext
+ FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ llvm::pdb::IPDBSession &
+ GetPDBSession();
+
+ const llvm::pdb::IPDBSession &
+ GetPDBSession() const;
+
+private:
+ lldb::CompUnitSP
+ ParseCompileUnitForSymIndex(uint32_t id);
+
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line);
+
+ void
+ BuildSupportFileIdToSupportFileIndexMap(const llvm::pdb::PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
+
+ void
+ FindTypesByRegex(const std::string &regex, uint32_t max_matches, lldb_private::TypeMap &types);
+
+ void
+ FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types);
+
+ llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
+ llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
+
+ std::vector<lldb::TypeSP> m_builtin_types;
+ std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
+ uint32_t m_cached_compile_unit_count;
+ std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
+};
+
+#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
diff --git a/source/Plugins/SymbolFile/Symtab/Makefile b/source/Plugins/SymbolFile/Symtab/Makefile
deleted file mode 100644
index 2c3dbb6d86ab7..0000000000000
--- a/source/Plugins/SymbolFile/Symtab/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SymbolFile/Symtab/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSymbolFileSymtab
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index d3dd1ae923e02..24175079c95f2 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -153,7 +153,8 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
{
const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
- cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown, false));
+ cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0,
+ eLanguageTypeUnknown, eLazyBoolNo));
}
return cu_sp;
}