diff options
33 files changed, 231 insertions, 51 deletions
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index 633d1d88ebe..eba43c34a50 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -744,7 +744,8 @@ public: size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) override; + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) override; CompilerType GetBuiltinTypeByName(const ConstString &name) override; diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index 1170832a739..b97e336e348 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -301,7 +301,8 @@ public: size_t GetTypeBitAlign() const; - uint32_t GetNumChildren(bool omit_empty_base_classes) const; + uint32_t GetNumChildren(bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) const; lldb::BasicType GetBasicTypeEnumeration() const; diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index c9dcd1817c2..01bbc388703 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -143,6 +143,23 @@ public: virtual size_t ParseTypes(const SymbolContext &sc) = 0; virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0; virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0; + + + /// The characteristics of an array type. + struct ArrayInfo { + int64_t first_index; + llvm::SmallVector<uint64_t, 1> element_orders; + uint32_t byte_stride; + uint32_t bit_stride; + }; + /// If \c type_uid points to an array type, return its characteristics. + /// To support variable-length array types, this function takes an + /// optional \p ExtecutionContext. If \c exe_ctx is non-null, the + /// dynamic characteristics for that context are returned. + virtual llvm::Optional<ArrayInfo> + GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) = 0; + virtual bool CompleteType(CompilerType &compiler_type) = 0; virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {} virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index 2f152e84da8..b9405ee63f3 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -284,7 +284,8 @@ public: virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0; virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) = 0; + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) = 0; virtual CompilerType GetBuiltinTypeByName(const ConstString &name); diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/vla/Makefile b/lldb/packages/Python/lldbsuite/test/lang/c/vla/Makefile new file mode 100644 index 00000000000..b09a579159d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/c/vla/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py b/lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py new file mode 100644 index 00000000000..0d3a0a69a50 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py @@ -0,0 +1,25 @@ +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestVLA(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_vla(self): + self.build() + _, process, _, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec('main.c')) + + def test(a, array): + for i in range(a): + self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%(a-i)]) + self.expect("expr vla[%d]"%i, substrs=["int", "%d"%(a-i)]) + self.expect("frame var vla", substrs=array) + self.expect("expr vla", error=True, substrs=["incomplete"]) + + test(2, ["int []", "[0] = 2, [1] = 1"]) + process.Continue() + test(4, ["int []", "[0] = 4, [1] = 3, [2] = 2, [3] = 1"]) + diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/vla/main.c b/lldb/packages/Python/lldbsuite/test/lang/c/vla/main.c new file mode 100644 index 00000000000..ba9cc185560 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/c/vla/main.c @@ -0,0 +1,15 @@ +void pause() {} + +int foo(int a) { + int vla[a]; + + for (int i = 0; i < a; ++i) + vla[i] = a-i; + + pause(); // break here + return vla[a-1]; +} + +int main (void) { + return foo(2) + foo(4); +} diff --git a/lldb/source/Core/ValueObjectCast.cpp b/lldb/source/Core/ValueObjectCast.cpp index f6ec026e079..da71141178a 100644 --- a/lldb/source/Core/ValueObjectCast.cpp +++ b/lldb/source/Core/ValueObjectCast.cpp @@ -44,7 +44,9 @@ ValueObjectCast::~ValueObjectCast() {} CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; } size_t ValueObjectCast::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren( + true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index 00526c65656..174fd92fa72 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -51,7 +51,8 @@ lldb::ValueType ValueObjectChild::GetValueType() const { } size_t ValueObjectChild::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index e02ed1d5300..2364a0e38ff 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -208,7 +208,8 @@ uint64_t ValueObjectConstResult::GetByteSize() { void ValueObjectConstResult::SetByteSize(size_t size) { m_byte_size = size; } size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index d835e6965d4..e13170ed200 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -92,7 +92,8 @@ ConstString ValueObjectDynamicValue::GetDisplayTypeName() { size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasType()) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } else return m_parent->GetNumChildren(max); diff --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp index 1a816463eec..466eae7e960 100644 --- a/lldb/source/Core/ValueObjectMemory.cpp +++ b/lldb/source/Core/ValueObjectMemory.cpp @@ -128,8 +128,10 @@ size_t ValueObjectMemory::CalculateNumChildren(uint32_t max) { return child_count <= max ? child_count : max; } + ExecutionContext exe_ctx(GetExecutionContextRef()); const bool omit_empty_base_classes = true; - auto child_count = m_compiler_type.GetNumChildren(omit_empty_base_classes); + auto child_count = + m_compiler_type.GetNumChildren(omit_empty_base_classes, &exe_ctx); return child_count <= max ? child_count : max; } diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp index 818df06a446..3f76fd50193 100644 --- a/lldb/source/Core/ValueObjectRegister.cpp +++ b/lldb/source/Core/ValueObjectRegister.cpp @@ -279,7 +279,8 @@ ConstString ValueObjectRegister::GetTypeName() { } size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index e09bb17a219..2f017aa36f7 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -98,8 +98,9 @@ size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) { if (!type.IsValid()) return 0; + ExecutionContext exe_ctx(GetExecutionContextRef()); const bool omit_empty_base_classes = true; - auto child_count = type.GetNumChildren(omit_empty_base_classes); + auto child_count = type.GetNumChildren(omit_empty_base_classes, &exe_ctx); return child_count <= max ? child_count : max; } diff --git a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp index 8047ff332b6..8d4e122e307 100644 --- a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp +++ b/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp @@ -773,7 +773,7 @@ private: // get number of children const bool omit_empty_base_classes = true; - uint32_t n = m_type.GetNumChildren(omit_empty_base_classes); + uint32_t n = m_type.GetNumChildren(omit_empty_base_classes, nullptr); if (!n) { LLDB_LOG(m_log, LOG_PREFIX "No children found in struct"); return ValueObjectSP(); diff --git a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 82b7ac1675f..bb1a47c263c 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -89,7 +89,7 @@ public: size_t CalculateNumChildren() override { const bool omit_empty_base_classes = false; - return m_block_struct_type.GetNumChildren(omit_empty_base_classes); + return m_block_struct_type.GetNumChildren(omit_empty_base_classes, nullptr); } lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index ae7c770d6ef..b439d7fe590 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -12,10 +12,15 @@ #include "DWARFDefines.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" class DWARFDIE; +namespace lldb_private { +class ExecutionContext; +} +class SymbolFileDWARF; class DWARFASTParser { public: @@ -45,6 +50,10 @@ public: virtual std::vector<DWARFDIE> GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0; + + static llvm::Optional<lldb_private::SymbolFile::ArrayInfo> + ParseChildArrayInfo(const DWARFDIE &parent_die, + const lldb_private::ExecutionContext *exe_ctx = nullptr); }; #endif // SymbolFileDWARF_DWARFASTParser_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 718ae66fd1f..ee3942a83b7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1734,9 +1734,12 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, Type *element_type = dwarf->ResolveTypeUID(type_die_ref); if (element_type) { - std::vector<uint64_t> element_orders; - ParseChildArrayInfo(sc, die, first_index, element_orders, - byte_stride, bit_stride); + auto array_info = ParseChildArrayInfo(die); + if (array_info) { + first_index = array_info->first_index; + byte_stride = array_info->byte_stride; + bit_stride = array_info->bit_stride; + } if (byte_stride == 0 && bit_stride == 0) byte_stride = element_type->GetByteSize(); CompilerType array_element_type = @@ -1786,12 +1789,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, } uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; - if (element_orders.size() > 0) { + if (array_info && array_info->element_orders.size() > 0) { uint64_t num_elements = 0; - std::vector<uint64_t>::const_reverse_iterator pos; - std::vector<uint64_t>::const_reverse_iterator end = - element_orders.rend(); - for (pos = element_orders.rbegin(); pos != end; ++pos) { + auto end = array_info->element_orders.rend(); + for (auto pos = array_info->element_orders.rbegin(); pos != end; + ++pos) { num_elements = *pos; clang_type = m_ast.CreateArrayType(array_element_type, num_elements, is_vector); @@ -1810,6 +1812,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID, &decl, clang_type, Type::eResolveStateFull)); type_sp->SetEncodingType(element_type); + m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), + die.GetID()); } } } break; @@ -3439,12 +3443,12 @@ size_t DWARFASTParserClang::ParseChildParameters( return arg_idx; } -void DWARFASTParserClang::ParseChildArrayInfo( - const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, - std::vector<uint64_t> &element_orders, uint32_t &byte_stride, - uint32_t &bit_stride) { +llvm::Optional<SymbolFile::ArrayInfo> +DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, + const ExecutionContext *exe_ctx) { + SymbolFile::ArrayInfo array_info; if (!parent_die) - return; + return llvm::None; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { @@ -3468,15 +3472,31 @@ void DWARFASTParserClang::ParseChildArrayInfo( break; case DW_AT_count: - num_elements = form_value.Unsigned(); + if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { + if (var_die.Tag() == DW_TAG_variable) + if (exe_ctx) { + if (auto frame = exe_ctx->GetFrameSP()) { + Status error; + lldb::VariableSP var_sp; + auto valobj_sp = frame->GetValueForVariableExpressionPath( + var_die.GetName(), eNoDynamicValues, 0, var_sp, + error); + if (valobj_sp) { + num_elements = valobj_sp->GetValueAsUnsigned(0); + break; + } + } + } + } else + num_elements = form_value.Unsigned(); break; case DW_AT_bit_stride: - bit_stride = form_value.Unsigned(); + array_info.bit_stride = form_value.Unsigned(); break; case DW_AT_byte_stride: - byte_stride = form_value.Unsigned(); + array_info.byte_stride = form_value.Unsigned(); break; case DW_AT_lower_bound: @@ -3510,11 +3530,12 @@ void DWARFASTParserClang::ParseChildArrayInfo( num_elements = upper_bound - lower_bound + 1; } - element_orders.push_back(num_elements); + array_info.element_orders.push_back(num_elements); } } break; } } + return array_info; } Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index f444ee25d16..2d84d5ad40b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -28,6 +28,7 @@ class DWARFDebugInfoEntry; class DWARFDIECollection; +class SymbolFileDWARF; class DWARFASTParserClang : public DWARFASTParser { public: @@ -101,11 +102,6 @@ protected: std::vector<clang::ParmVarDecl *> &function_param_decls, unsigned &type_quals); - void ParseChildArrayInfo(const lldb_private::SymbolContext &sc, - const DWARFDIE &parent_die, int64_t &first_index, - std::vector<uint64_t> &element_orders, - uint32_t &byte_stride, uint32_t &bit_stride); - size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc, lldb_private::CompilerType &compiler_type, bool is_signed, uint32_t enumerator_byte_size, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index e7549c8887b..aef3d4b8565 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1415,6 +1415,17 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { return nullptr; } +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileDWARF::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + DWARFDIE type_die = GetDIEFromUID(type_uid); + if (type_die) + return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx); + else + return llvm::None; +} + Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) { return ResolveType(GetDIE(die_ref), true); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 2e93e9c8f97..0cd03ad2bb9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -141,6 +141,9 @@ public: ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 5901dccdc47..cf4233e6e31 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -518,7 +518,8 @@ uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { - if (oso_idx < m_compile_unit_infos.size()) + unsigned size = m_compile_unit_infos.size(); + if (oso_idx < size) return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); return NULL; } @@ -702,6 +703,16 @@ Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { return NULL; } +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx); + return llvm::None; +} + bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { bool success = false; if (compiler_type) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 075c6892c1b..e67133c9f95 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -77,6 +77,10 @@ public: ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; + lldb_private::CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; lldb_private::CompilerDeclContext diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 9125dab3caa..676d2eb0213 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1533,6 +1533,13 @@ Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { return &*type_sp; } +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileNativePDB::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + return llvm::None; +} + + bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { // If this is not in our map, it's an error. clang::TagDecl *tag_decl = m_clang->GetAsTagDecl(compiler_type); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 94fa58011fb..fd842b93e28 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -113,6 +113,10 @@ public: return 0; } Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; + bool CompleteType(CompilerType &compiler_type) override; uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 0baa7675f24..6096218552b 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -587,6 +587,11 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { return result.get(); } +llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + return llvm::None; +} + bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { std::lock_guard<std::recursive_mutex> guard( GetObjectFile()->GetModule()->GetMutex()); diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index d8f0c66d448..8b95ff5c168 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -85,6 +85,9 @@ public: ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index c8d96a50417..8375abf384b 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -239,6 +239,12 @@ Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { return NULL; } +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileSymtab::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + return llvm::None; +} + bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) { return false; } diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 4c31292896e..f8df9931e45 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -80,6 +80,9 @@ public: ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 12a83da9cb6..f98135216a5 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -5400,8 +5400,21 @@ static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl, return false; } +static llvm::Optional<SymbolFile::ArrayInfo> +GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file, + clang::QualType qual_type, + const ExecutionContext *exe_ctx) { + if (qual_type->isIncompleteArrayType()) + if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr())) + if (auto *dwarf_parser = ast.GetDWARFParser()) + return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(), + exe_ctx); + return llvm::None; +} + uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) { + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) { if (!type) return 0; @@ -5423,7 +5436,6 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, case clang::Type::Complex: return 0; - case clang::Type::Record: if (GetCompleteQualType(getASTContext(), qual_type)) { const clang::RecordType *record_type = @@ -5501,7 +5513,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, clang::QualType pointee_type = pointer_type->getPointeeType(); uint32_t num_pointee_children = CompilerType(getASTContext(), pointee_type) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -5520,6 +5532,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, ->getSize() .getLimitedValue(); break; + case clang::Type::IncompleteArray: + if (auto array_info = + GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx)) + // Only 1-dimensional arrays are supported. + num_children = array_info->element_orders.size() + ? array_info->element_orders.back() + : 0; + break; case clang::Type::Pointer: { const clang::PointerType *pointer_type = @@ -5527,7 +5547,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, clang::QualType pointee_type(pointer_type->getPointeeType()); uint32_t num_pointee_children = CompilerType(getASTContext(), pointee_type) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); if (num_pointee_children == 0) { // We have a pointer to a pointee type that claims it has no children. We // will want to look at @@ -5543,7 +5563,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, clang::QualType pointee_type = reference_type->getPointeeType(); uint32_t num_pointee_children = CompilerType(getASTContext(), pointee_type) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -5556,14 +5576,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type) ->getDecl() ->getUnderlyingType()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; case clang::Type::Auto: num_children = CompilerType(getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; case clang::Type::Elaborated: @@ -5571,14 +5591,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, CompilerType( getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; case clang::Type::Paren: num_children = CompilerType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; default: break; @@ -6455,7 +6475,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( child_is_base_class = false; language_flags = 0; - const bool idx_is_valid = idx < GetNumChildren(type, omit_empty_base_classes); + const bool idx_is_valid = + idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx); int32_t bit_offset; switch (parent_type_class) { case clang::Type::Builtin: @@ -6677,8 +6698,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( CompilerType base_class_clang_type( getASTContext(), getASTContext()->getObjCInterfaceType( superclass_interface_decl)); - if (base_class_clang_type.GetNumChildren( - omit_empty_base_classes) > 0) { + if (base_class_clang_type.GetNumChildren(omit_empty_base_classes, + exe_ctx) > 0) { if (idx == 0) { clang::QualType ivar_qual_type( getASTContext()->getObjCInterfaceType( diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index adb79824794..fbee6a2f347 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -535,10 +535,12 @@ lldb::Format CompilerType::GetFormat() const { return m_type_system->GetFormat(m_type); } -uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes) const { +uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) const { if (!IsValid()) return 0; - return m_type_system->GetNumChildren(m_type, omit_empty_base_classes); + return m_type_system->GetNumChildren(m_type, omit_empty_base_classes, + exe_ctx); } lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 6d7ec43710f..1162a941fd3 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -342,7 +342,7 @@ uint64_t Type::GetByteSize() { } uint32_t Type::GetNumChildren(bool omit_empty_base_classes) { - return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes); + return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes, nullptr); } bool Type::IsAggregateType() { diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index af84872a97a..429657c786c 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -603,7 +603,7 @@ static void PrivateAutoComplete( case eTypeClassObjCObjectPointer: case eTypeClassPointer: { bool omit_empty_base_classes = true; - if (compiler_type.GetNumChildren(omit_empty_base_classes) > 0) + if (compiler_type.GetNumChildren(omit_empty_base_classes, nullptr) > 0) matches.AppendString((prefix_path + "->").str()); else { matches.AppendString(prefix_path.str()); |