aprantl updated this revision to Diff 172388.
aprantl added a comment.
Herald added subscribers: kbarton, nemanjai.
Version that only overrides GetNumChildren to avoid creating dynamic clang
types.
https://reviews.llvm.org/D53530
Files:
include/lldb/Symbol/ClangASTContext.h
include/lldb/Symbol/CompilerType.h
include/lldb/Symbol/GoASTContext.h
include/lldb/Symbol/JavaASTContext.h
include/lldb/Symbol/OCamlASTContext.h
include/lldb/Symbol/SymbolFile.h
include/lldb/Symbol/TypeSystem.h
packages/Python/lldbsuite/test/lang/c/vla/Makefile
packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
packages/Python/lldbsuite/test/lang/c/vla/main.c
source/Core/ValueObjectCast.cpp
source/Core/ValueObjectChild.cpp
source/Core/ValueObjectConstResult.cpp
source/Core/ValueObjectDynamicValue.cpp
source/Core/ValueObjectMemory.cpp
source/Core/ValueObjectRegister.cpp
source/Core/ValueObjectVariable.cpp
source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
source/Plugins/Language/CPlusPlus/BlockPointer.cpp
source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
source/Symbol/ClangASTContext.cpp
source/Symbol/CompilerType.cpp
source/Symbol/GoASTContext.cpp
source/Symbol/JavaASTContext.cpp
source/Symbol/OCamlASTContext.cpp
source/Symbol/Type.cpp
source/Symbol/Variable.cpp
Index: source/Symbol/Variable.cpp
===================================================================
--- source/Symbol/Variable.cpp
+++ source/Symbol/Variable.cpp
@@ -603,7 +603,7 @@
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());
Index: source/Symbol/Type.cpp
===================================================================
--- source/Symbol/Type.cpp
+++ source/Symbol/Type.cpp
@@ -342,7 +342,7 @@
}
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() {
Index: source/Symbol/OCamlASTContext.cpp
===================================================================
--- source/Symbol/OCamlASTContext.cpp
+++ source/Symbol/OCamlASTContext.cpp
@@ -509,7 +509,8 @@
}
uint32_t OCamlASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
- bool omit_empty_base_classes) {
+ bool omit_empty_base_classes,
+ const ExecutionContext *exe_ctx) {
if (!type || !GetCompleteType(type))
return 0;
Index: source/Symbol/JavaASTContext.cpp
===================================================================
--- source/Symbol/JavaASTContext.cpp
+++ source/Symbol/JavaASTContext.cpp
@@ -915,12 +915,14 @@
}
uint32_t JavaASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
- bool omit_empty_base_classes) {
+ bool omit_empty_base_classes,
+ const ExecutionContext *exe_ctx) {
GetCompleteType(type);
if (JavaReferenceType *ref =
llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
- return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes);
+ return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes,
+ exe_ctx);
if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
return GetNumFields(type) + GetNumDirectBaseClasses(type);
Index: source/Symbol/GoASTContext.cpp
===================================================================
--- source/Symbol/GoASTContext.cpp
+++ source/Symbol/GoASTContext.cpp
@@ -864,19 +864,20 @@
}
uint32_t GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
- bool omit_empty_base_classes) {
+ bool omit_empty_base_classes,
+ const ExecutionContext *exe_ctx) {
if (!type || !GetCompleteType(type))
return 0;
GoType *t = static_cast<GoType *>(type);
if (t->GetGoKind() == GoType::KIND_PTR) {
CompilerType elem = t->GetElementType();
if (elem.IsAggregateType())
- return elem.GetNumChildren(omit_empty_base_classes);
+ return elem.GetNumChildren(omit_empty_base_classes, exe_ctx);
return 1;
} else if (GoArray *array = t->GetArray()) {
return array->GetLength();
} else if (t->IsTypedef()) {
- return t->GetElementType().GetNumChildren(omit_empty_base_classes);
+ return t->GetElementType().GetNumChildren(omit_empty_base_classes, exe_ctx);
}
return GetNumFields(type);
Index: source/Symbol/CompilerType.cpp
===================================================================
--- source/Symbol/CompilerType.cpp
+++ source/Symbol/CompilerType.cpp
@@ -535,10 +535,12 @@
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 {
Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -5400,8 +5400,21 @@
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 @@
case clang::Type::Complex:
return 0;
-
case clang::Type::Record:
if (GetCompleteQualType(getASTContext(), qual_type)) {
const clang::RecordType *record_type =
@@ -5501,7 +5513,7 @@
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,14 +5532,22 @@
->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 =
llvm::cast<clang::PointerType>(qual_type.getTypePtr());
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 @@
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,29 +5576,29 @@
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:
num_children =
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 @@
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 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(
Index: source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
===================================================================
--- source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -80,6 +80,9 @@
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;
Index: source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
===================================================================
--- source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -239,6 +239,12 @@
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;
}
Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
===================================================================
--- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -85,6 +85,9 @@
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;
Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
===================================================================
--- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -587,6 +587,11 @@
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());
Index: source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
===================================================================
--- source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -113,6 +113,10 @@
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,
Index: source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
===================================================================
--- source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1433,6 +1433,13 @@
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);
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -77,6 +77,10 @@
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
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -518,7 +518,8 @@
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 @@
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) {
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -144,6 +144,9 @@
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;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1416,6 +1416,17 @@
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);
}
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ 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 @@
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,
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1734,9 +1734,12 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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) {
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ 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 @@
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_
Index: source/Plugins/Language/CPlusPlus/BlockPointer.cpp
===================================================================
--- source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -89,7 +89,7 @@
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 {
Index: source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
===================================================================
--- source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -773,7 +773,7 @@
// 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();
Index: source/Core/ValueObjectVariable.cpp
===================================================================
--- source/Core/ValueObjectVariable.cpp
+++ source/Core/ValueObjectVariable.cpp
@@ -98,8 +98,9 @@
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;
}
Index: source/Core/ValueObjectRegister.cpp
===================================================================
--- source/Core/ValueObjectRegister.cpp
+++ source/Core/ValueObjectRegister.cpp
@@ -279,7 +279,8 @@
}
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;
}
Index: source/Core/ValueObjectMemory.cpp
===================================================================
--- source/Core/ValueObjectMemory.cpp
+++ source/Core/ValueObjectMemory.cpp
@@ -128,8 +128,10 @@
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;
}
Index: source/Core/ValueObjectDynamicValue.cpp
===================================================================
--- source/Core/ValueObjectDynamicValue.cpp
+++ source/Core/ValueObjectDynamicValue.cpp
@@ -92,7 +92,8 @@
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);
Index: source/Core/ValueObjectConstResult.cpp
===================================================================
--- source/Core/ValueObjectConstResult.cpp
+++ source/Core/ValueObjectConstResult.cpp
@@ -208,7 +208,8 @@
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;
}
Index: source/Core/ValueObjectChild.cpp
===================================================================
--- source/Core/ValueObjectChild.cpp
+++ source/Core/ValueObjectChild.cpp
@@ -51,7 +51,8 @@
}
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;
}
Index: source/Core/ValueObjectCast.cpp
===================================================================
--- source/Core/ValueObjectCast.cpp
+++ source/Core/ValueObjectCast.cpp
@@ -44,7 +44,9 @@
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;
}
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] = a-i;
+
+ pause(); // break here
+ return vla[a-1];
+}
+
+int main (void) {
+ return foo(2) + foo(4);
+}
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'))
+
+ def test(a):
+ 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)])
+ array = ["int []", "2", "1"]
+ self.expect("frame var vla", substrs=array)
+ self.expect("expr vla", error=True, substrs=["incomplete"])
+
+ test(2)
+ process.Continue()
+ test(4)
+
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: include/lldb/Symbol/TypeSystem.h
===================================================================
--- include/lldb/Symbol/TypeSystem.h
+++ include/lldb/Symbol/TypeSystem.h
@@ -286,7 +286,8 @@
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);
Index: include/lldb/Symbol/SymbolFile.h
===================================================================
--- include/lldb/Symbol/SymbolFile.h
+++ include/lldb/Symbol/SymbolFile.h
@@ -143,6 +143,23 @@
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) {
Index: include/lldb/Symbol/OCamlASTContext.h
===================================================================
--- include/lldb/Symbol/OCamlASTContext.h
+++ include/lldb/Symbol/OCamlASTContext.h
@@ -173,7 +173,8 @@
lldb::Format GetFormat(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;
lldb::BasicType
GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
Index: include/lldb/Symbol/JavaASTContext.h
===================================================================
--- include/lldb/Symbol/JavaASTContext.h
+++ include/lldb/Symbol/JavaASTContext.h
@@ -223,7 +223,8 @@
bool *is_bitfield_ptr) 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;
uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override;
Index: include/lldb/Symbol/GoASTContext.h
===================================================================
--- include/lldb/Symbol/GoASTContext.h
+++ include/lldb/Symbol/GoASTContext.h
@@ -248,7 +248,8 @@
lldb::Format GetFormat(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;
lldb::BasicType
GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
Index: include/lldb/Symbol/CompilerType.h
===================================================================
--- include/lldb/Symbol/CompilerType.h
+++ include/lldb/Symbol/CompilerType.h
@@ -301,7 +301,8 @@
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;
Index: include/lldb/Symbol/ClangASTContext.h
===================================================================
--- include/lldb/Symbol/ClangASTContext.h
+++ include/lldb/Symbol/ClangASTContext.h
@@ -744,7 +744,8 @@
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;
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits