Added a new class called lldb_private::SymbolFileType which is designed to
take a SymbolFile reference and a lldb::user_id_t and be used in objects
which represent things in debug symbols that have types where we don't need
to know the true type yet, such as in lldb_private::Variable objects. This
allows us to defer resolving the type until something is used. More specifically
this allows us to get 1000 local variables from the current function, and if
the user types "frame variable argc", we end up _only_ resolving the type for
"argc" and not for the 999 other local variables. We can expand the use of this
as needed in the future.
Modified the DWARFMappedHash class to be able to read the HashData that has
more than just the DIE offset. It currently will read the atoms in the header
definition and read the data correctly. Currently only the DIE offset and
type flags are supported. This is needed for adding type flags to the
.apple_types hash accelerator tables.
Fixed a assertion crash that would happen if we have a variable that had a
DW_AT_const_value instead of a location where "location.LocationContains_DW_OP_addr()"
would end up asserting when it tried to parse the variable location as a
DWARF opcode list.
Decreased the amount of memory that LLDB would use when evaluating an expression
by 3x - 4x for clang. There was a place in the namespace lookup code that was
parsing all namespaces with a certain name in a DWARF file instead of stopping
when it found the first match. This was causing all of the compile units with
a matching namespace to get parsed into memory and causing unnecessary memory
bloat.
Improved "Target::EvaluateExpression(...)" to not try and find a variable
when the expression contains characters that would certainly cause an expression
to need to be evaluated by the debugger.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@146130 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Core/MappedHash.h b/include/lldb/Core/MappedHash.h
index 32beb80..1198a2d 100644
--- a/include/lldb/Core/MappedHash.h
+++ b/include/lldb/Core/MappedHash.h
@@ -508,6 +508,12 @@
uint32_t* hash_data_offset_ptr,
Pair &pair) const = 0;
+ const HeaderType &
+ GetHeader()
+ {
+ return m_header;
+ }
+
protected:
// Implementation agnostic information
HeaderType m_header;
diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
index 9c11ae4..6c78ffb 100644
--- a/include/lldb/Symbol/Type.h
+++ b/include/lldb/Symbol/Type.h
@@ -19,6 +19,35 @@
#include <set>
namespace lldb_private {
+
+class SymbolFileType :
+ public ReferenceCountedBaseVirtual<SymbolFileType>,
+ public UserID
+ {
+ public:
+ SymbolFileType (SymbolFile &symbol_file, lldb::user_id_t uid) :
+ UserID (uid),
+ m_symbol_file (symbol_file)
+ {
+ }
+
+ ~SymbolFileType ()
+ {
+ }
+
+ Type *
+ operator->()
+ {
+ return GetType ();
+ }
+
+ Type *
+ GetType ();
+
+ protected:
+ SymbolFile &m_symbol_file;
+ lldb::TypeSP m_type_sp;
+ };
class Type :
public ReferenceCountedBaseVirtual<Type>,
diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h
index 85412af..3459494 100644
--- a/include/lldb/Symbol/Variable.h
+++ b/include/lldb/Symbol/Variable.h
@@ -30,7 +30,7 @@
Variable (lldb::user_id_t uid,
const char *name,
const char *mangled, // The mangled variable name for variables in namespaces
- Type *type,
+ const lldb::SymbolFileTypeSP &symfile_type_sp,
lldb::ValueType scope,
SymbolContextScope *owner_scope,
Declaration* decl,
@@ -81,16 +81,7 @@
NameMatches (const RegularExpression& regex) const;
Type *
- GetType()
- {
- return m_type;
- }
-
- const Type *
- GetType() const
- {
- return m_type;
- }
+ GetType();
lldb::ValueType
GetScope() const
@@ -169,7 +160,7 @@
protected:
ConstString m_name; // The basename of the variable (no namespaces)
Mangled m_mangled; // The mangled name of hte variable
- Type *m_type; // The type pointer of the variable (int, struct, class, etc)
+ lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable (int, struct, class, etc)
lldb::ValueType m_scope; // global, parameter, local
SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in
Declaration m_declaration; // Declaration location for this item.
diff --git a/include/lldb/lldb-forward-rtti.h b/include/lldb/lldb-forward-rtti.h
index 63b1d6f..c9f7b53 100644
--- a/include/lldb/lldb-forward-rtti.h
+++ b/include/lldb/lldb-forward-rtti.h
@@ -70,6 +70,7 @@
typedef SharedPtr<lldb_private::StringSummaryFormat>::Type StringSummaryFormatSP;
typedef SharedPtr<lldb_private::SummaryFormat>::Type SummaryFormatSP;
typedef SharedPtr<lldb_private::SymbolFile>::Type SymbolFileSP;
+ typedef IntrusiveSharedPtr<lldb_private::SymbolFileType>::Type SymbolFileTypeSP;
typedef SharedPtr<lldb_private::SymbolContextSpecifier>::Type SymbolContextSpecifierSP;
typedef SharedPtr<lldb_private::SyntheticChildren>::Type SyntheticChildrenSP;
typedef SharedPtr<lldb_private::SyntheticChildrenFrontEnd>::Type SyntheticChildrenFrontEndSP;
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index 94cd4e2..e877c6e 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -158,6 +158,7 @@
class SymbolContextScope;
class SymbolContextSpecifier;
class SymbolFile;
+class SymbolFileType;
class SymbolVendor;
class Symtab;
class SyntheticChildren;
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 014f980..44bab7b 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -1524,47 +1524,35 @@
{
if (module && name_cstr && name_cstr[0])
{
- /*SymbolContextList sc_list;
-
- SymbolVendor *symbol_vendor = module->GetSymbolVendor();
- if (symbol_vendor)
- {*/
- TypeList type_list;
- uint32_t num_matches = 0;
- SymbolContext sc;
- // if (name_is_regex)
- // {
- // RegularExpression name_regex (name_cstr);
- // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
- // }
- // else
- // {
- ConstString name(name_cstr);
- num_matches = module->FindTypes(sc, name, NULL, true, UINT32_MAX, type_list);
- // }
+ TypeList type_list;
+ const uint32_t max_num_matches = 1;
+ uint32_t num_matches = 0;
+ SymbolContext sc;
+
+ ConstString name(name_cstr);
+ num_matches = module->FindTypes(sc, name, NULL, true, max_num_matches, type_list);
- if (num_matches)
+ if (num_matches)
+ {
+ strm.Indent ();
+ strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
+ DumpFullpath (strm, &module->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+ const uint32_t num_types = type_list.GetSize();
+ for (uint32_t i=0; i<num_types; ++i)
{
- strm.Indent ();
- strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
- DumpFullpath (strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- const uint32_t num_types = type_list.GetSize();
- for (uint32_t i=0; i<num_types; ++i)
+ TypeSP type_sp (type_list.GetTypeAtIndex(i));
+ if (type_sp)
{
- TypeSP type_sp (type_list.GetTypeAtIndex(i));
- if (type_sp)
- {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
- type_sp->GetClangFullType ();
- type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
- }
- strm.EOL();
+ // Resolve the clang type so that any forward references
+ // to types that haven't yet been parsed will get parsed.
+ type_sp->GetClangFullType ();
+ type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
}
+ strm.EOL();
}
- return num_matches;
- //}
+ }
+ return num_matches;
}
return 0;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index ac417e5..507dea2 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -472,6 +472,27 @@
return die_offset;
}
+uint64_t
+DWARFFormValue::Reference (dw_offset_t base_offset) const
+{
+ uint64_t die_offset = m_value.value.uval;
+ switch (m_form)
+ {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ die_offset += base_offset;
+ break;
+
+ default:
+ break;
+ }
+
+ return die_offset;
+}
+
//----------------------------------------------------------------------
// Resolve any compile unit specific references so that we don't need
// the compile unit at a later time in order to work with the form
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 4194e1c..5051a51 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -10,9 +10,10 @@
#ifndef SymbolFileDWARF_DWARFFormValue_h_
#define SymbolFileDWARF_DWARFFormValue_h_
-#include "SymbolFileDWARF.h"
#include <stddef.h> // for NULL
+class DWARFCompileUnit;
+
class DWARFFormValue
{
public:
@@ -52,6 +53,7 @@
bool IsInlinedCStr() const { return (m_value.data != NULL) && m_value.data == (uint8_t*)m_value.value.cstr; }
const uint8_t* BlockData() const;
uint64_t Reference(const DWARFCompileUnit* cu) const;
+ uint64_t Reference (dw_offset_t offset) const;
bool ResolveCompileUnitReferences(const DWARFCompileUnit* cu);
uint64_t Unsigned() const { return m_value.value.uval; }
void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index 43b3830..690072d 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -11,17 +11,55 @@
#define SymbolFileDWARF_HashedNameToDIE_h_
#include <vector>
+
+#include "DWARFFormValue.h"
+
#include "lldb/lldb-defines.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/MappedHash.h"
+
class SymbolFileDWARF;
+class DWARFCompileUnit;
+class DWARFDebugInfoEntry;
struct DWARFMappedHash
{
+ struct DIEInfo
+ {
+ dw_offset_t offset; // The DIE offset
+ uint32_t type_flags; // Any flags for this DIEInfo
+
+ DIEInfo (dw_offset_t _offset = DW_INVALID_OFFSET,
+ uint32_t _type_flags = 0) :
+ offset(_offset),
+ type_flags (_type_flags)
+ {
+ }
+
+ void
+ Clear()
+ {
+ offset = DW_INVALID_OFFSET;
+ type_flags = 0;
+ }
+ };
+
+ typedef std::vector<DIEInfo> DIEInfoArray;
typedef std::vector<uint32_t> DIEArray;
+ static void
+ ExtractDIEArray (const DIEInfoArray &die_info_array,
+ DIEArray &die_offsets)
+ {
+ const size_t count = die_info_array.size();
+ for (size_t i=0; i<count; ++i)
+ {
+ die_offsets.push_back (die_info_array[i].offset);
+ }
+ }
+
enum AtomType
{
eAtomTypeNULL = 0u,
@@ -31,6 +69,37 @@
eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
eAtomTypeTypeFlags = 5u // Flags from enum TypeFlags
};
+
+ // Held in bits[3:0] of the eAtomTypeTypeFlags value to help us know what kind of type
+ // the name is describing
+ enum TypeFlagsTypeClass
+ {
+ eTypeClassInvalid = 0u, // An invalid type class, this might happend when type flags were not correctly set
+ eTypeClassOther = 1u, // A type other than any listed below
+ eTypeClassBuiltIn = 2u, // Language built in type
+ eTypeClassClassOrStruct = 3u, // A class or structure, just not an objective C class
+ eTypeClassClassOBJC = 4u,
+ eTypeClassEnum = 5u,
+ eTypeClassTypedef = 7u,
+ eTypeClassUnion = 8u
+ };
+
+ // Other type bits for the eAtomTypeTypeFlags flags
+
+ enum TypeFlags
+ {
+ // Make bits [3:0] of the eAtomTypeTypeFlags value and see TypeFlagsTypeClass
+ eTypeFlagClassMask = 0x0000000fu,
+
+ // If the name contains the namespace and class scope or the type
+ // exists in the global namespace, then this bits should be set
+ eTypeFlagNameIsFullyQualified = ( 1u << 4 ),
+
+ // Always set for C++, only set for ObjC if this is the
+ // @implementation for class
+ eTypeFlagClassIsImplementation = ( 1u << 5 ),
+
+ };
struct Atom
{
@@ -46,7 +115,12 @@
typedef std::vector<Atom> AtomArray;
+ static uint32_t
+ GetTypeFlags (SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit* cu,
+ const DWARFDebugInfoEntry* die);
+
static const char *
GetAtomTypeName (uint16_t atom)
{
@@ -66,14 +140,18 @@
// DIE offset base so die offsets in hash_data can be CU relative
dw_offset_t die_base_offset;
AtomArray atoms;
+ size_t min_hash_data_byte_size;
Prologue (dw_offset_t _die_base_offset = 0) :
- die_base_offset (_die_base_offset)
+ die_base_offset (_die_base_offset),
+ atoms(),
+ min_hash_data_byte_size(0)
{
// Define an array of DIE offsets by first defining an array,
// and then define the atom type for the array, in this case
// we have an array of DIE offsets
- atoms.push_back (Atom(eAtomTypeDIEOffset, DW_FORM_data4));
+ AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
+ min_hash_data_byte_size = 4;
}
virtual ~Prologue()
@@ -87,12 +165,60 @@
atoms.clear();
}
+ void
+ AppendAtom (AtomType type, dw_form_t form)
+ {
+ atoms.push_back (Atom(type, form));
+ switch (form)
+ {
+ case DW_FORM_indirect:
+ case DW_FORM_exprloc:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ assert (!"Unhandled atom form");
+ break;
+
+ case DW_FORM_string:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_sec_offset:
+ case DW_FORM_ref_udata:
+ min_hash_data_byte_size += 1;
+ break;
+ case DW_FORM_block2:
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ min_hash_data_byte_size += 2;
+ break;
+ case DW_FORM_block4:
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ case DW_FORM_strp:
+ min_hash_data_byte_size += 4;
+ break;
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ min_hash_data_byte_size += 8;
+ break;
+
+ }
+ }
+
// void
// Dump (std::ostream* ostrm_ptr);
uint32_t
Read (const lldb_private::DataExtractor &data, uint32_t offset)
{
+ atoms.clear();
+
die_base_offset = data.GetU32 (&offset);
const uint32_t atom_count = data.GetU32 (&offset);
@@ -103,16 +229,15 @@
/* do nothing */;
// Hardcode to the only know value for now.
- atoms.push_back (Atom(eAtomTypeDIEOffset, DW_FORM_data4));
+ AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
}
else
{
- Atom atom;
for (uint32_t i=0; i<atom_count; ++i)
{
- atom.type = data.GetU16 (&offset);
- atom.form = data.GetU16 (&offset);
- atoms.push_back(atom);
+ AtomType type = (AtomType)data.GetU16 (&offset);
+ dw_form_t form = (dw_form_t)data.GetU16 (&offset);
+ AppendAtom (type, form);
}
}
return offset;
@@ -128,6 +253,13 @@
// written to disk
return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom);
}
+
+ size_t
+ GetHashDataByteSize () const
+ {
+ return min_hash_data_byte_size;
+ }
+
};
struct Header : public MappedHash::Header<Prologue>
@@ -147,6 +279,11 @@
return header_data.GetByteSize();
}
+ size_t
+ GetHashDataByteSize ()
+ {
+ return header_data.GetHashDataByteSize();
+ }
// virtual void
// Dump (std::ostream* ostrm_ptr);
@@ -161,9 +298,89 @@
}
return offset;
}
- //
- // virtual void
- // Write (BinaryStreamBuf &s);
+
+ bool
+ Read (const lldb_private::DataExtractor &data,
+ uint32_t *offset_ptr,
+ DIEInfo &hash_data) const
+ {
+ const size_t num_atoms = header_data.atoms.size();
+ if (num_atoms == 0)
+ return false;
+
+ for (size_t i=0; i<num_atoms; ++i)
+ {
+ DWARFFormValue form_value (header_data.atoms[i].form);
+
+ if (!form_value.ExtractValue(data, offset_ptr, NULL))
+ return false;
+
+ switch (header_data.atoms[i].type)
+ {
+ case eAtomTypeDIEOffset: // DIE offset, check form for encoding
+ hash_data.offset = form_value.Reference (header_data.die_base_offset);
+ break;
+ case eAtomTypeTypeFlags: // Flags from enum TypeFlags
+ hash_data.type_flags = form_value.Unsigned ();
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+ return true;
+ }
+
+ void
+ Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const
+ {
+ const size_t num_atoms = header_data.atoms.size();
+ for (size_t i=0; i<num_atoms; ++i)
+ {
+ if (i > 0)
+ strm.PutCString (", ");
+
+ DWARFFormValue form_value (header_data.atoms[i].form);
+ switch (header_data.atoms[i].type)
+ {
+ case eAtomTypeDIEOffset: // DIE offset, check form for encoding
+ strm.Printf ("0x%8.8x", hash_data.offset);
+ break;
+
+ case eAtomTypeTypeFlags: // Flags from enum TypeFlags
+ strm.Printf ("0x%2.2x ( type = ", hash_data.type_flags);
+ switch (hash_data.type_flags & eTypeFlagClassMask)
+ {
+ case eTypeClassInvalid: strm.PutCString ("invalid"); break;
+ case eTypeClassOther: strm.PutCString ("other"); break;
+ case eTypeClassBuiltIn: strm.PutCString ("built-in"); break;
+ case eTypeClassClassOrStruct: strm.PutCString ("class-struct"); break;
+ case eTypeClassClassOBJC: strm.PutCString ("class-objc"); break;
+ case eTypeClassEnum: strm.PutCString ("enum"); break;
+ case eTypeClassTypedef: strm.PutCString ("typedef"); break;
+ case eTypeClassUnion: strm.PutCString ("union"); break;
+ default: strm.PutCString ("???"); break;
+ }
+
+ if (hash_data.type_flags & ~eTypeFlagClassMask)
+ {
+ strm.PutCString (", flags =");
+ if (hash_data.type_flags & eTypeFlagNameIsFullyQualified)
+ strm.PutCString (" qualified");
+
+ if (hash_data.type_flags & eTypeFlagClassIsImplementation)
+ strm.PutCString (" implementation");
+ }
+ strm.PutCString (" )");
+ break;
+
+ default:
+ strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
+ break;
+ }
+ }
+ }
+
};
// class ExportTable
@@ -210,7 +427,7 @@
// };
//
// // Map uniqued .debug_str offset to the corresponding DIE offsets
-// typedef std::map<uint32_t, DIEArray> NameInfo;
+// typedef std::map<uint32_t, DIEInfoArray> NameInfo;
// // Map a name hash to one or more name infos
// typedef std::map<uint32_t, NameInfo> BucketEntry;
//
@@ -226,14 +443,14 @@
// A class for reading and using a saved hash table from a block of data
// in memory
- class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEArray>
+ class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEInfoArray>
{
public:
MemoryTable (lldb_private::DataExtractor &table_data,
const lldb_private::DataExtractor &string_table,
const char *name) :
- MappedHash::MemoryTable<uint32_t, Header, DIEArray> (table_data),
+ MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray> (table_data),
m_data (table_data),
m_string_table (string_table),
m_name (name)
@@ -270,14 +487,18 @@
return eResultError;
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const uint32_t data_size = count * sizeof(uint32_t);
+ const uint32_t data_size = count * m_header.header_data.GetHashDataByteSize();
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, data_size))
{
if (strcmp (name, strp_cstr) == 0)
{
pair.value.clear();
for (uint32_t i=0; i<count; ++i)
- pair.value.push_back (m_data.GetU32 (hash_data_offset_ptr));
+ {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
+ pair.value.push_back (die_info);
+ }
return eResultKeyMatch;
}
else
@@ -314,13 +535,17 @@
return eResultError;
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const uint32_t data_size = count * sizeof(uint32_t);
+ const uint32_t data_size = count * m_header.header_data.GetHashDataByteSize();
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, data_size))
{
if (regex.Execute(strp_cstr))
{
for (uint32_t i=0; i<count; ++i)
- pair.value.push_back (m_data.GetU32 (hash_data_offset_ptr));
+ {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
+ pair.value.push_back (die_info);
+ }
return eResultKeyMatch;
}
else
@@ -341,7 +566,7 @@
size_t
AppendAllDIEsThatMatchingRegex (const lldb_private::RegularExpression& regex,
- DIEArray &die_offsets) const
+ DIEInfoArray &die_info_array) const
{
const uint32_t hash_count = m_header.hashes_count;
Pair pair;
@@ -371,14 +596,14 @@
}
}
}
- die_offsets.swap (pair.value);
- return die_offsets.size();
+ die_info_array.swap (pair.value);
+ return die_info_array.size();
}
size_t
AppendAllDIEsInRange (const uint32_t die_offset_start,
const uint32_t die_offset_end,
- DIEArray &die_offsets) const
+ DIEInfoArray &die_info_array) const
{
const uint32_t hash_count = m_header.hashes_count;
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
@@ -396,26 +621,38 @@
const uint32_t count = m_data.GetU32 (&hash_data_offset);
for (uint32_t i=0; i<count; ++i)
{
- uint32_t die_offset = m_data.GetU32 (&hash_data_offset);
- if (die_offset == 0)
- done = true;
- if (die_offset_start <= die_offset && die_offset < die_offset_end)
- die_offsets.push_back(die_offset);
+ DIEInfo die_info;
+ if (m_header.Read(m_data, &hash_data_offset, die_info))
+ {
+ if (die_info.offset == 0)
+ done = true;
+ if (die_offset_start <= die_info.offset && die_info.offset < die_offset_end)
+ die_info_array.push_back(die_info);
+ }
}
}
}
- return die_offsets.size();
+ return die_info_array.size();
+ }
+
+ size_t
+ FindByName (const char *name, DIEArray &die_offsets)
+ {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
+ return die_info_array.size();
}
size_t
- FindByName (const char *name, DIEArray &die_offsets)
+ FindByName (const char *name, DIEInfoArray &die_info_array)
{
Pair kv_pair;
- size_t old_size = die_offsets.size();
+ size_t old_size = die_info_array.size();
if (Find (name, kv_pair))
{
- die_offsets.swap(kv_pair.value);
- return die_offsets.size() - old_size;
+ die_info_array.swap(kv_pair.value);
+ return die_info_array.size() - old_size;
}
return 0;
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 7004e8d..87806a0 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2398,7 +2398,11 @@
if (m_using_apple_tables)
{
if (m_apple_names_ap.get())
- m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets);
+ {
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
+ DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
+ }
}
else
{
@@ -2556,8 +2560,10 @@
SymbolContextList& sc_list)
{
DIEArray die_offsets;
- if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets))
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
{
+ DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
ParseFunctions (die_offsets, sc_list);
}
}
@@ -2965,7 +2971,12 @@
}
uint32_t
-SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
+SymbolFileDWARF::FindTypes (const SymbolContext& sc,
+ const ConstString &name,
+ const lldb_private::ClangNamespaceDecl *namespace_decl,
+ bool append,
+ uint32_t max_matches,
+ TypeList& types)
{
DWARFDebugInfo* info = DebugInfo();
if (info == NULL)
@@ -3113,6 +3124,7 @@
{
namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
namespace_decl.SetNamespaceDecl (clang_namespace_decl);
+ break;
}
}
else
@@ -3929,8 +3941,18 @@
{
if (m_apple_types_ap.get())
{
- const char *name_cstr = type_name.GetCString();
- m_apple_types_ap->FindByName (name_cstr, die_offsets);
+ if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ {
+ std::string qualified_name;
+ const char *qualified_cstr = die->GetQualifiedName(this, cu, qualified_name);
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ m_apple_types_ap->FindByName (qualified_cstr, hash_data_array);
+ DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
+ }
+ else
+ {
+ m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
+ }
}
}
else
@@ -5308,9 +5330,15 @@
if (m_using_apple_tables)
{
if (m_apple_names_ap.get())
- m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(),
- die_offsets);
+ {
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
+ dwarf_cu->GetNextCompileUnitOffset(),
+ hash_data_array))
+ {
+ DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
+ }
+ }
}
else
{
@@ -5387,7 +5415,7 @@
const char *mangled = NULL;
Declaration decl;
uint32_t i;
- Type *var_type = NULL;
+ lldb::user_id_t type_uid = LLDB_INVALID_UID;
DWARFExpression location;
bool is_external = false;
bool is_artificial = false;
@@ -5407,7 +5435,7 @@
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
+ case DW_AT_type: type_uid = form_value.Reference(dwarf_cu); break;
case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
case DW_AT_const_value:
location_is_const_value_data = true;
@@ -5457,8 +5485,6 @@
if (location.IsValid())
{
- assert(var_type != DIE_IS_BEING_PARSED);
-
ValueType scope = eValueTypeInvalid;
const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
@@ -5477,64 +5503,74 @@
// then we can correctly classify our variables.
if (tag == DW_TAG_formal_parameter)
scope = eValueTypeVariableArgument;
- else if (location.LocationContains_DW_OP_addr ())
+ else
{
- if (is_external)
+ // Check if the location has a DW_OP_addr with any address value...
+ addr_t location_has_op_addr = false;
+ if (!location_is_const_value_data)
+ location_has_op_addr = location.LocationContains_DW_OP_addr ();
+
+ if (location_has_op_addr)
{
- if (m_debug_map_symfile)
+ if (is_external)
{
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
- if (location.LocationContains_DW_OP_addr (0))
+ scope = eValueTypeVariableGlobal;
+
+ if (m_debug_map_symfile)
{
-
- // we have a possible uninitialized extern global
- Symtab *symtab = m_obj_file->GetSymtab();
- if (symtab)
+ // When leaving the DWARF in the .o files on darwin,
+ // when we have a global variable that wasn't initialized,
+ // the .o file might not have allocated a virtual
+ // address for the global variable. In this case it will
+ // have created a symbol for the global variable
+ // that is undefined and external and the value will
+ // be the byte size of the variable. When we do the
+ // address map in SymbolFileDWARFDebugMap we rely on
+ // having an address, we need to do some magic here
+ // so we can get the correct address for our global
+ // variable. The address for all of these entries
+ // will be zero, and there will be an undefined symbol
+ // in this object file, and the executable will have
+ // a matching symbol with a good address. So here we
+ // dig up the correct address and replace it in the
+ // location for the variable, and set the variable's
+ // symbol context scope to be that of the main executable
+ // so the file address will resolve correctly.
+ if (location.LocationContains_DW_OP_addr (0))
{
- ConstString const_name(name);
- Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeUndefined,
- Symtab::eDebugNo,
- Symtab::eVisibilityExtern);
- if (undefined_symbol)
+ // we have a possible uninitialized extern global
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab)
{
- ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
- if (debug_map_objfile)
+ ConstString const_name(name);
+ Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
+ eSymbolTypeUndefined,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityExtern);
+
+ if (undefined_symbol)
{
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeData,
- Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (defined_symbol)
+ ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile)
{
- const AddressRange *defined_range = defined_symbol->GetAddressRangePtr();
- if (defined_range)
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
+ eSymbolTypeData,
+ Symtab::eDebugYes,
+ Symtab::eVisibilityExtern);
+ if (defined_symbol)
{
- const addr_t defined_addr = defined_range->GetBaseAddress().GetFileAddress();
- if (defined_addr != LLDB_INVALID_ADDRESS)
+ const AddressRange *defined_range = defined_symbol->GetAddressRangePtr();
+ if (defined_range)
{
- if (location.Update_DW_OP_addr (defined_addr))
+ const addr_t defined_addr = defined_range->GetBaseAddress().GetFileAddress();
+ if (defined_addr != LLDB_INVALID_ADDRESS)
{
- symbol_context_scope = defined_symbol;
+ if (location.Update_DW_OP_addr (defined_addr))
+ {
+ symbol_context_scope = defined_symbol;
+ }
}
}
}
@@ -5544,13 +5580,16 @@
}
}
}
- scope = eValueTypeVariableGlobal;
+ else
+ {
+ scope = eValueTypeVariableStatic;
+ }
}
else
- scope = eValueTypeVariableStatic;
+ {
+ scope = eValueTypeVariableLocal;
+ }
}
- else
- scope = eValueTypeVariableLocal;
if (symbol_context_scope == NULL)
{
@@ -5578,7 +5617,7 @@
var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
name,
mangled,
- var_type,
+ SymbolFileTypeSP (new SymbolFileType(*this, type_uid)),
scope,
symbol_context_scope,
&decl,
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 706e4de..80571d0 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -30,6 +30,15 @@
using namespace lldb;
using namespace lldb_private;
+Type *
+SymbolFileType::GetType ()
+{
+ if (!m_type_sp)
+ m_type_sp = m_symbol_file.ResolveTypeUID (GetID());
+ return m_type_sp.get();
+}
+
+
Type::Type
(
lldb::user_id_t uid,
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index d5bba28..cb3f86e 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -36,7 +36,7 @@
lldb::user_id_t uid,
const char *name,
const char *mangled, // The mangled variable name for variables in namespaces
- Type *type,
+ const lldb::SymbolFileTypeSP &symfile_type_sp,
ValueType scope,
SymbolContextScope *context,
Declaration* decl_ptr,
@@ -47,7 +47,7 @@
UserID(uid),
m_name(name),
m_mangled (mangled, true),
- m_type(type),
+ m_symfile_type_sp(symfile_type_sp),
m_scope(scope),
m_owner_scope(context),
m_declaration(decl_ptr),
@@ -81,6 +81,14 @@
return m_mangled.NameMatches (regex);
}
+Type *
+Variable::GetType()
+{
+ if (m_symfile_type_sp)
+ return m_symfile_type_sp->GetType();
+ return NULL;
+}
+
void
Variable::Dump(Stream *s, bool show_context) const
{
@@ -91,11 +99,15 @@
if (m_name)
*s << ", name = \"" << m_name << "\"";
- if (m_type != NULL)
+ if (m_symfile_type_sp)
{
- *s << ", type = {" << m_type->GetID() << "} " << (void*)m_type << " (";
- m_type->DumpTypeName(s);
- s->PutChar(')');
+ Type *type = m_symfile_type_sp->GetType();
+ if (type)
+ {
+ *s << ", type = {" << type->GetID() << "} " << (void*)type << " (";
+ type->DumpTypeName(s);
+ s->PutChar(')');
+ }
}
if (m_scope != eValueTypeInvalid)
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 978ab5e..a887866 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -1471,13 +1471,19 @@
ExecutionResults execution_results = eExecutionSetupError;
result_valobj_sp.reset();
-
+
+ if (expr_cstr == NULL || expr_cstr[0] == '\0')
+ return execution_results;
+
// We shouldn't run stop hooks in expressions.
// Be sure to reset this if you return anywhere within this function.
bool old_suppress_value = m_suppress_stop_hooks;
m_suppress_stop_hooks = true;
ExecutionContext exe_ctx;
+
+ const size_t expr_cstr_len = ::strlen (expr_cstr);
+
if (frame)
{
frame->CalculateExecutionContext(exe_ctx);
@@ -1486,11 +1492,17 @@
StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
StackFrame::eExpressionPathOptionsNoSyntheticChildren;
lldb::VariableSP var_sp;
- result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr,
- use_dynamic,
- expr_path_options,
- var_sp,
- error);
+
+ // Make sure we don't have any things that we know a variable expression
+ // won't be able to deal with before calling into it
+ if (::strcspn (expr_cstr, "()+*&|!~<=/^%,?") == expr_cstr_len)
+ {
+ result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr,
+ use_dynamic,
+ expr_path_options,
+ var_sp,
+ error);
+ }
}
else if (m_process_sp)
{