Index: include/lldb/Symbol/SymbolFile.h =================================================================== --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -128,7 +128,9 @@ virtual size_t ParseFunctionBlocks(const SymbolContext &sc) = 0; 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; + virtual Type * + ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx = {}) = 0; virtual bool CompleteType(CompilerType &compiler_type) = 0; virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {} virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { Index: include/lldb/Symbol/Variable.h =================================================================== --- include/lldb/Symbol/Variable.h +++ include/lldb/Symbol/Variable.h @@ -64,7 +64,7 @@ bool NameMatches(const RegularExpression ®ex) const; Type *GetType(); - + lldb::LanguageType GetLanguage() const; lldb::ValueType GetScope() const { return m_scope; } Index: packages/Python/lldbsuite/test/lang/c/vla/Makefile =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/c/vla/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py @@ -0,0 +1,26 @@ +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')) + + for i in range(2): + self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%i]) + self.expect("expr vla[%d]"%i, substrs=["int", "%d"%i]) + array = ["int [2]", "1", "2"] + self.expect("fr v -d run-target -- vla", substrs=array) + + process.Continue() + for i in range(4): + self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%i]) + self.expect("expr vla[%d]"%i, substrs=["int", "%d"%i]) + array = ["int [4]", "1", "2", "3", "4"] + self.expect("fr v -d run-target -- vla", substrs=array) Index: packages/Python/lldbsuite/test/lang/c/vla/main.c =================================================================== --- /dev/null +++ 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] = i; + + pause(); // break here + return vla[a-1]; +} + +int main (void) { + return foo(2) + foo(4); +} Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp =================================================================== --- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -23,6 +23,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/Variable.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" @@ -207,16 +208,32 @@ if (!CouldHaveDynamicValue(in_value)) return false; + ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); + + // Handle variables with incomplete array types. + auto *type = in_value.GetCompilerType().GetOpaqueQualType(); + auto qual_type = clang::QualType::getFromOpaquePtr(type).getCanonicalType(); + if (qual_type->getTypeClass() == clang::Type::IncompleteArray) { + if (auto variable = in_value.GetVariable()) { + auto *lldb_type = variable->GetType(); + auto *symbol_file = lldb_type->GetSymbolFile(); + auto uid = lldb_type->GetID(); + if (auto dyn_type = symbol_file->ResolveTypeUID(uid, exe_ctx)) { + class_type_or_name.SetCompilerType(dyn_type->GetFullCompilerType()); + value_type = Value::ValueType::eValueTypeLoadAddress; + dynamic_address = in_value.GetAddressOf(); + return true; + } + } + } + // First job, pull out the address at 0 offset from the object. AddressType address_type; lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); if (original_ptr == LLDB_INVALID_ADDRESS) return false; - ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); - Process *process = exe_ctx.GetProcessPtr(); - if (process == nullptr) return false; Index: source/Plugins/SymbolFile/DWARF/DWARFASTParser.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -14,6 +14,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/Target/ExecutionContext.h" class DWARFDIE; @@ -21,10 +22,10 @@ public: virtual ~DWARFASTParser() {} - virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, - lldb_private::Log *log, - bool *type_is_new_ptr) = 0; + virtual lldb::TypeSP + ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx = {}) = 0; virtual lldb_private::Function * ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -36,9 +36,10 @@ ~DWARFASTParserClang() override; // DWARFASTParser interface. - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; + lldb::TypeSP ParseTypeFromDWARF( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; lldb_private::Function * ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, @@ -104,7 +105,8 @@ void ParseChildArrayInfo(const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, std::vector &element_orders, - uint32_t &byte_stride, uint32_t &bit_stride); + uint32_t &byte_stride, uint32_t &bit_stride, + const lldb_private::ExecutionContextRef exe_ctx); size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc, lldb_private::CompilerType &compiler_type, @@ -131,7 +133,9 @@ void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die); - lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log); + lldb::TypeSP + ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log, + const lldb_private::ExecutionContextRef exe_ctx = {}); //---------------------------------------------------------------------- // Return true if this type is a declaration to a type in an external Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -15,6 +15,7 @@ #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" #include "DWARFDefines.h" +#include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDebugMap.h" @@ -137,7 +138,9 @@ return false; } -TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) { +TypeSP DWARFASTParserClang::ParseTypeFromDWO( + const DWARFDIE &die, Log *log, + const lldb_private::ExecutionContextRef exe_ctx) { ModuleSP dwo_module_sp = die.GetContainingDWOModule(); if (!dwo_module_sp) return TypeSP(); @@ -168,7 +171,7 @@ if (num_dwo_types != 1) return TypeSP(); - // We found a real definition for this type in the Clang module, so lets use + // We found a real definition for this type in the Clang module, so let's use // it and cache the fact that we found a complete type for this die. TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0); if (!dwo_type_sp) @@ -188,8 +191,16 @@ NULL, LLDB_INVALID_UID, Type::eEncodingInvalid, &dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward)); + // We are ready to put this type into the uniqued list up at the module + // level. dwarf->GetTypeList()->Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + // Cache the type if it isn't context-specific. + auto &cache = dwarf->GetDIEToType(); + if (exe_ctx.GetFrameSP()) + cache.erase(die.GetDIE()); + else + cache[die.GetDIE()] = type_sp.get(); + clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); if (tag_decl) LinkDeclContextToDIE(tag_decl, die); @@ -228,9 +239,9 @@ } } -TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, - const DWARFDIE &die, Log *log, - bool *type_is_new_ptr) { +TypeSP DWARFASTParserClang::ParseTypeFromDWARF( + const SymbolContext &sc, const DWARFDIE &die, Log *log, + bool *type_is_new_ptr, const lldb_private::ExecutionContextRef exe_ctx) { TypeSP type_sp; if (type_is_new_ptr) @@ -251,8 +262,8 @@ context_die.GetOffset(), die.GetTagAsCString(), die.GetName()); } Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); - TypeList *type_list = dwarf->GetTypeList(); - if (type_ptr == NULL) { + // If an execution context is present, re-parse the type. + if (type_ptr == NULL || exe_ctx.GetFrameSP()) { if (type_is_new_ptr) *type_is_new_ptr = true; @@ -1736,7 +1747,7 @@ if (element_type) { std::vector element_orders; ParseChildArrayInfo(sc, die, first_index, element_orders, - byte_stride, bit_stride); + byte_stride, bit_stride, exe_ctx); if (byte_stride == 0 && bit_stride == 0) byte_stride = element_type->GetByteSize(); CompilerType array_element_type = @@ -1886,10 +1897,14 @@ } // We are ready to put this type into the uniqued list up at the module - // level - type_list->Insert(type_sp); - - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + // level. + dwarf->GetTypeList()->Insert(type_sp); + // Cache the type if it isn't context-specific. + auto &cache = dwarf->GetDIEToType(); + if (exe_ctx.GetFrameSP()) + cache.erase(die.GetDIE()); + else + cache[die.GetDIE()] = type_sp.get(); } } else if (type_ptr != DIE_IS_BEING_PARSED) { type_sp = type_ptr->shared_from_this(); @@ -3442,7 +3457,7 @@ void DWARFASTParserClang::ParseChildArrayInfo( const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, std::vector &element_orders, uint32_t &byte_stride, - uint32_t &bit_stride) { + uint32_t &bit_stride, const lldb_private::ExecutionContextRef exe_ctx) { if (!parent_die) return; @@ -3468,7 +3483,25 @@ 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 (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); + if (auto log = LogChannelDWARF::GetLogIfAll( + DWARF_LOG_DEBUG_INFO)) + log->Printf("Reparsing array type; dynamic size=%lld", + num_elements); + + break; + } + } + } else + num_elements = form_value.Unsigned(); break; case DW_AT_bit_stride: Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h @@ -33,9 +33,10 @@ ~DWARFASTParserGo() override; - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; + lldb::TypeSP ParseTypeFromDWARF( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; lldb_private::Function * ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp @@ -49,7 +49,8 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::Log *log, bool *type_is_new_ptr) { + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx) { TypeSP type_sp; if (type_is_new_ptr) Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h @@ -32,9 +32,10 @@ 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::TypeSP ParseTypeFromDWARF( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; lldb_private::Function * ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp @@ -276,7 +276,8 @@ lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF( const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::Log *log, bool *type_is_new_ptr) { + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx) { if (type_is_new_ptr) *type_is_new_ptr = false; Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h @@ -22,9 +22,10 @@ lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die); - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; + lldb::TypeSP ParseTypeFromDWARF( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::Log *log, bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; lldb_private::Function * ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp @@ -53,10 +53,9 @@ decl, compiler_type, Type::eResolveStateFull); } -lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc, - const DWARFDIE &die, - Log *log, - bool *type_is_new_ptr) { +lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF( + const SymbolContext &sc, const DWARFDIE &die, Log *log, + bool *type_is_new_ptr, const lldb_private::ExecutionContextRef exe_ctx) { if (type_is_new_ptr) *type_is_new_ptr = false; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -144,13 +144,16 @@ size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::Type * + ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; - lldb_private::Type *ResolveType(const DWARFDIE &die, - bool assert_not_being_parsed = true, - bool resolve_function_context = false); + lldb_private::Type * + ResolveType(const DWARFDIE &die, bool assert_not_being_parsed = true, + bool resolve_function_context = false, + const lldb_private::ExecutionContextRef exe_ctx = {}); SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid); @@ -371,7 +374,8 @@ bool parse_siblings, bool parse_children); lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, bool *type_is_new); + const DWARFDIE &die, bool *type_is_new, + const lldb_private::ExecutionContextRef exe_ctx = {}); lldb_private::Type *ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed); @@ -404,8 +408,10 @@ lldb_private::Symbol * GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name); - lldb::TypeSP GetTypeForDIE(const DWARFDIE &die, - bool resolve_function_context = false); + /// If exe_ctx is non-null, the type may only be valid within that context. + lldb::TypeSP + GetTypeForDIE(const DWARFDIE &die, bool resolve_function_context = false, + const lldb_private::ExecutionContextRef exe_ctx = {}); void SetDebugMapModule(const lldb::ModuleSP &module_sp) { m_debug_map_module_wp = module_sp; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1362,23 +1362,23 @@ return CompilerDeclContext(); } -Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { +Type *SymbolFileDWARF::ResolveTypeUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContextRef exe_ctx) { // 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; + return ResolveType(type_die, true, false, exe_ctx); + return nullptr; } Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) { return ResolveType(GetDIE(die_ref), true); } -Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die, - bool assert_not_being_parsed) { +Type *SymbolFileDWARF::ResolveTypeUID( + const DWARFDIE &die, bool assert_not_being_parsed) { if (die) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); if (log) @@ -1486,11 +1486,12 @@ return false; } -Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die, - bool assert_not_being_parsed, - bool resolve_function_context) { +Type * +SymbolFileDWARF::ResolveType(const DWARFDIE &die, bool assert_not_being_parsed, + bool resolve_function_context, + const lldb_private::ExecutionContextRef exe_ctx) { if (die) { - Type *type = GetTypeForDIE(die, resolve_function_context).get(); + Type *type = GetTypeForDIE(die, resolve_function_context, exe_ctx).get(); if (assert_not_being_parsed) { if (type != DIE_IS_BEING_PARSED) @@ -2592,33 +2593,37 @@ return namespace_decl_ctx; } -TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, - bool resolve_function_context) { - TypeSP type_sp; - if (die) { - Type *type_ptr = GetDIEToType().lookup(die.GetDIE()); - if (type_ptr == NULL) { - CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); - assert(lldb_cu); - SymbolContext sc(lldb_cu); - const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE(); - while (parent_die != nullptr) { - if (parent_die->Tag() == DW_TAG_subprogram) - break; - parent_die = parent_die->GetParent(); - } - SymbolContext sc_backup = sc; - if (resolve_function_context && parent_die != nullptr && - !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc)) - sc = sc_backup; - - type_sp = ParseType(sc, die, NULL); - } else if (type_ptr != DIE_IS_BEING_PARSED) { - // Grab the existing type from the master types lists - type_sp = type_ptr->shared_from_this(); - } +TypeSP SymbolFileDWARF::GetTypeForDIE( + const DWARFDIE &die, bool resolve_function_context, + const lldb_private::ExecutionContextRef exe_ctx) { + if (!die) + return {}; + Type *type_ptr = GetDIEToType().lookup(die.GetDIE()); + if (type_ptr == DIE_IS_BEING_PARSED) + return {}; + + // If an execution context is present, re-parse the type. + if (type_ptr && !exe_ctx.GetFrameSP()) { + // Grab the existing type from the master types lists + return type_ptr->shared_from_this(); } - return type_sp; + + // Parse the type. + CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); + assert(lldb_cu); + SymbolContext sc(lldb_cu); + const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE(); + while (parent_die) { + if (parent_die->Tag() == DW_TAG_subprogram) + break; + parent_die = parent_die->GetParent(); + } + SymbolContext sc_backup = sc; + if (resolve_function_context && parent_die && + !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc)) + sc = sc_backup; + + return ParseType(sc, die, NULL, exe_ctx); } DWARFDIE @@ -3000,8 +3005,10 @@ return type_sp; } -TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, - bool *type_is_new_ptr) { +TypeSP +SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, + bool *type_is_new_ptr, + const lldb_private::ExecutionContextRef exe_ctx) { TypeSP type_sp; if (die) { @@ -3012,10 +3019,11 @@ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); if (dwarf_ast) { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr); + type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr, + exe_ctx); if (type_sp) { TypeList *type_list = GetTypeList(); - if (type_list) + if (type_list && !exe_ctx.GetFrameSP()) type_list->Insert(type_sp); if (die.Tag() == DW_TAG_subprogram) { Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -76,7 +76,9 @@ size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::Type * + ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; lldb_private::CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; lldb_private::CompilerDeclContext Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -694,11 +694,12 @@ return 0; } -Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { +Type *SymbolFileDWARFDebugMap::ResolveTypeUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContextRef exe_ctx) { const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); if (oso_dwarf) - return oso_dwarf->ResolveTypeUID(type_uid); + return oso_dwarf->ResolveTypeUID(type_uid, exe_ctx); return NULL; } Index: source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h =================================================================== --- source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -116,7 +116,9 @@ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override { return 0; } - lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override { + lldb_private::Type * + ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx) override { return nullptr; } bool CompleteType(lldb_private::CompilerType &compiler_type) override { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -84,7 +84,9 @@ size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::Type * + ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -558,7 +558,9 @@ return num_added; } -lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { +lldb_private::Type * +SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx) { auto find_result = m_types.find(type_uid); if (find_result != m_types.end()) return find_result->second.get(); Index: source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h =================================================================== --- source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -79,7 +79,9 @@ size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::Type * + ResolveTypeUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContextRef exe_ctx = {}) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; Index: source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp =================================================================== --- source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -235,7 +235,8 @@ return 0; } -Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { +Type *SymbolFileSymtab::ResolveTypeUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContextRef exe_ctx) { return NULL; } Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -3696,6 +3696,9 @@ return IsPossibleDynamicType( llvm::cast(qual_type)->desugar().getAsOpaquePtr(), dynamic_pointee_type, check_cplusplus, check_objc); + + case clang::Type::IncompleteArray: + return true; default: break; }