<rdar://problem/12560257>
Fixed zero sized arrays to work correctly. This will only happen once we get a clang that emits correct debug info for zero sized arrays. For now I have marked the TestStructTypes.py as an expected failure.
llvm-svn: 169465
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 3397b0e..d500cad 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -2046,14 +2046,14 @@
typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
IndirectFieldVector indirect_fields;
-
- for (RecordDecl::field_iterator fi = record_decl->field_begin(), fe = record_decl->field_end();
- fi != fe;
- ++fi)
+ RecordDecl::field_iterator field_pos;
+ RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+ RecordDecl::field_iterator last_field_pos = field_end_pos;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
{
- if (fi->isAnonymousStructOrUnion())
+ if (field_pos->isAnonymousStructOrUnion())
{
- QualType field_qual_type = fi->getType();
+ QualType field_qual_type = field_pos->getType();
const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
@@ -2072,7 +2072,7 @@
if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
{
NamedDecl **chain = new (*ast) NamedDecl*[2];
- chain[0] = *fi;
+ chain[0] = *field_pos;
chain[1] = nested_field_decl;
IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
record_decl,
@@ -2082,7 +2082,7 @@
chain,
2);
- indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+ indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
nested_field_decl->getAccess()));
indirect_fields.push_back(indirect_field);
@@ -2091,7 +2091,7 @@
{
int nested_chain_size = nested_indirect_field_decl->getChainingSize();
NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1];
- chain[0] = *fi;
+ chain[0] = *field_pos;
int chain_index = 1;
for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
@@ -2111,7 +2111,7 @@
chain,
nested_chain_size + 1);
- indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+ indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
nested_indirect_field_decl->getAccess()));
indirect_fields.push_back(indirect_field);
@@ -2120,6 +2120,14 @@
}
}
+ // Check the last field to see if it has an incomplete array type as its
+ // last member and if it does, the tell the record decl about it
+ if (last_field_pos != field_end_pos)
+ {
+ if (last_field_pos->getType()->isIncompleteArrayType())
+ record_decl->hasFlexibleArrayMember();
+ }
+
for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
ifi < ife;
++ifi)
@@ -3864,17 +3872,19 @@
if (parent_clang_type == NULL)
return NULL;
- if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
+ QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
+ const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+
+ const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes);
+ uint32_t bit_offset;
+ switch (parent_type_class)
{
- uint32_t bit_offset;
- child_bitfield_bit_size = 0;
- child_bitfield_bit_offset = 0;
- child_is_base_class = false;
- QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
- const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
- switch (parent_type_class)
+ case clang::Type::Builtin:
+ if (idx_is_valid)
{
- case clang::Type::Builtin:
switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
{
case clang::BuiltinType::ObjCId:
@@ -3886,270 +3896,272 @@
default:
break;
}
- break;
+ }
+ break;
- case clang::Type::Record:
- if (GetCompleteQualType (ast, parent_qual_type))
+ case clang::Type::Record:
+ if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
+ {
+ const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
+
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
{
- const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
- uint32_t child_idx = 0;
-
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
+ // We might have base classes to print out first
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
{
- // We might have base classes to print out first
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
+ const CXXRecordDecl *base_class_decl = NULL;
+
+ // Skip empty base classes
+ if (omit_empty_base_classes)
{
- const CXXRecordDecl *base_class_decl = NULL;
-
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
- base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (RecordHasFields(base_class_decl) == false)
- continue;
- }
-
- if (idx == child_idx)
- {
- if (base_class_decl == NULL)
- base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-
-
- if (base_class->isVirtual())
- bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- else
- bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
-
- // Base classes should be a multiple of 8 bits in size
- child_byte_offset = bit_offset/8;
-
- child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
-
- uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
-
- // Base classes bit sizes should be a multiple of 8 bits in size
- assert (clang_type_info_bit_size % 8 == 0);
- child_byte_size = clang_type_info_bit_size / 8;
- child_is_base_class = true;
- return base_class->getType().getAsOpaquePtr();
- }
- // We don't increment the child index in the for loop since we might
- // be skipping empty base classes
- ++child_idx;
+ base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ if (RecordHasFields(base_class_decl) == false)
+ continue;
}
- }
- // Make sure index is in range...
- uint32_t field_idx = 0;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
- {
+
if (idx == child_idx)
{
- // Print the member type if requested
- // Print the member name and equal sign
- child_name.assign(field->getNameAsString().c_str());
+ if (base_class_decl == NULL)
+ base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
- assert(field_idx < record_layout.getFieldCount());
- child_byte_size = field_type_info.first / 8;
+ if (base_class->isVirtual())
+ bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+ else
+ bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
- // Figure out the field offset within the current struct/union/class type
- bit_offset = record_layout.getFieldOffset (field_idx);
- child_byte_offset = bit_offset / 8;
- if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
+ // Base classes should be a multiple of 8 bits in size
+ child_byte_offset = bit_offset/8;
+
+ child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
- return field->getType().getAsOpaquePtr();
+ uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
+
+ // Base classes bit sizes should be a multiple of 8 bits in size
+ assert (clang_type_info_bit_size % 8 == 0);
+ child_byte_size = clang_type_info_bit_size / 8;
+ child_is_base_class = true;
+ return base_class->getType().getAsOpaquePtr();
}
+ // We don't increment the child index in the for loop since we might
+ // be skipping empty base classes
+ ++child_idx;
}
}
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, parent_qual_type))
+ // Make sure index is in range...
+ uint32_t field_idx = 0;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
{
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
+ if (idx == child_idx)
{
- uint32_t child_idx = 0;
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
+ // Print the member type if requested
+ // Print the member name and equal sign
+ child_name.assign(field->getNameAsString().c_str());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
+ assert(field_idx < record_layout.getFieldCount());
+
+ child_byte_size = field_type_info.first / 8;
+
+ // Figure out the field offset within the current struct/union/class type
+ bit_offset = record_layout.getFieldOffset (field_idx);
+ child_byte_offset = bit_offset / 8;
+ if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
+ child_bitfield_bit_offset = bit_offset % 8;
+
+ return field->getType().getAsOpaquePtr();
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ uint32_t child_idx = 0;
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+
+ const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
{
-
- const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
+ if (omit_empty_base_classes)
{
- if (omit_empty_base_classes)
+ if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
{
- if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
+ if (idx == 0)
{
- if (idx == 0)
- {
- QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-
-
- child_name.assign(superclass_interface_decl->getNameAsString().c_str());
-
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.first / 8;
- child_byte_offset = 0;
- child_is_base_class = true;
-
- return ivar_qual_type.getAsOpaquePtr();
- }
-
- ++child_idx;
- }
- }
- else
- ++child_idx;
- }
-
- const uint32_t superclass_idx = child_idx;
-
- if (idx < (child_idx + class_interface_decl->ivar_size()))
- {
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
- {
- if (child_idx == idx)
- {
- ObjCIvarDecl* ivar_decl = *ivar_pos;
+ QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
- QualType ivar_qual_type(ivar_decl->getType());
- child_name.assign(ivar_decl->getNameAsString().c_str());
+ child_name.assign(superclass_interface_decl->getNameAsString().c_str());
std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
child_byte_size = ivar_type_info.first / 8;
+ child_byte_offset = 0;
+ child_is_base_class = true;
- // Figure out the field offset within the current struct/union/class type
- // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
- // that doesn't account for the space taken up by unbacked properties, or from
- // the changing size of base classes that are newer than this class.
- // So if we have a process around that we can ask about this object, do so.
- child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
- Process *process = NULL;
- if (exe_ctx)
- process = exe_ctx->GetProcessPtr();
- if (process)
- {
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL)
- {
- ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
- child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
- }
- }
-
- // Setting this to UINT32_MAX to make sure we don't compute it twice...
- bit_offset = UINT32_MAX;
-
- if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
- {
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
- child_byte_offset = bit_offset / 8;
- }
-
- // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
- // of a bitfield within its containing object. So regardless of where we get the byte
- // offset from, we still need to get the bit offset for bitfields from the layout.
-
- if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
- {
- if (bit_offset == UINT32_MAX)
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-
- child_bitfield_bit_offset = bit_offset % 8;
- }
return ivar_qual_type.getAsOpaquePtr();
}
+
++child_idx;
}
}
+ else
+ ++child_idx;
+ }
+
+ const uint32_t superclass_idx = child_idx;
+
+ if (idx < (child_idx + class_interface_decl->ivar_size()))
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+ {
+ if (child_idx == idx)
+ {
+ ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ QualType ivar_qual_type(ivar_decl->getType());
+
+ child_name.assign(ivar_decl->getNameAsString().c_str());
+
+ std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.first / 8;
+
+ // Figure out the field offset within the current struct/union/class type
+ // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
+ // that doesn't account for the space taken up by unbacked properties, or from
+ // the changing size of base classes that are newer than this class.
+ // So if we have a process around that we can ask about this object, do so.
+ child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+ Process *process = NULL;
+ if (exe_ctx)
+ process = exe_ctx->GetProcessPtr();
+ if (process)
+ {
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL)
+ {
+ ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
+ child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
+ }
+ }
+
+ // Setting this to UINT32_MAX to make sure we don't compute it twice...
+ bit_offset = UINT32_MAX;
+
+ if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
+ {
+ bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+ child_byte_offset = bit_offset / 8;
+ }
+
+ // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
+ // of a bitfield within its containing object. So regardless of where we get the byte
+ // offset from, we still need to get the bit offset for bitfields from the layout.
+
+ if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
+ {
+ if (bit_offset == UINT32_MAX)
+ bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+
+ child_bitfield_bit_offset = bit_offset % 8;
+ }
+ return ivar_qual_type.getAsOpaquePtr();
+ }
+ ++child_idx;
+ }
}
}
}
- break;
-
- case clang::Type::ObjCObjectPointer:
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx_is_valid)
+ {
+ const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
+
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
{
- const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointer_type->getPointeeType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ child_is_deref_of_parent = true;
+ if (parent_name)
{
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- else
- {
- child_is_deref_of_parent = true;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
- // We have a pointer to an simple type
- if (idx == 0 && GetCompleteQualType(ast, pointee_type))
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ // We have a pointer to an simple type
+ if (idx == 0 && GetCompleteQualType(ast, pointee_type))
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
+ }
+ break;
case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ if (ignore_array_bounds || idx_is_valid)
{
- const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
- const uint64_t element_count = array->getSize().getLimitedValue();
-
- if (ignore_array_bounds || idx < element_count)
+ const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
+ if (array)
{
if (GetCompleteQualType (ast, array->getElementType()))
{
std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-
+
char element_name[64];
::snprintf (element_name, sizeof (element_name), "[%u]", idx);
-
+
child_name.assign(element_name);
assert(field_type_info.first % 8 == 0);
child_byte_size = field_type_info.first / 8;
@@ -4159,144 +4171,146 @@
}
}
break;
+
- case clang::Type::Pointer:
+ case clang::Type::Pointer:
+ if (idx_is_valid)
+ {
+ const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
+
+ // Don't dereference "void *" pointers
+ if (pointee_type->isVoidType())
+ return NULL;
+
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
{
- const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- // Don't dereference "void *" pointers
- if (pointee_type->isVoidType())
- return NULL;
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointer_type->getPointeeType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ child_is_deref_of_parent = true;
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ if (parent_name)
{
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- else
+
+ // We have a pointer to an simple type
+ if (idx == 0)
{
- child_is_deref_of_parent = true;
-
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
- QualType pointee_type(reference_type->getPointeeType());
- clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointee_clang_type,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
- }
- else
- {
- if (parent_name)
- {
- child_name.assign(1, '&');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
- break;
-
- case clang::Type::Elaborated:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
-
- default:
- break;
}
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (idx_is_valid)
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
+ QualType pointee_type(reference_type->getPointeeType());
+ clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointee_clang_type,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ if (parent_name)
+ {
+ child_name.assign(1, '&');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ break;
+
+ case clang::Type::Elaborated:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+
+ default:
+ break;
}
return NULL;
}
@@ -5250,17 +5264,27 @@
#pragma mark Array Types
clang_type_t
-ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
+ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count)
{
if (element_type)
{
ASTContext *ast = getASTContext();
assert (ast != NULL);
llvm::APInt ap_element_count (64, element_count);
- return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
- ap_element_count,
- ArrayType::Normal,
- 0).getAsOpaquePtr(); // ElemQuals
+ if (element_count == 0)
+ {
+ return ast->getIncompleteArrayType(QualType::getFromOpaquePtr(element_type),
+ ArrayType::Normal,
+ 0).getAsOpaquePtr();
+
+ }
+ else
+ {
+ return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
+ ap_element_count,
+ ArrayType::Normal,
+ 0).getAsOpaquePtr(); // ElemQuals
+ }
}
return NULL;
}
@@ -5931,7 +5955,7 @@
bool
ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
{
- clang_type = GetAsArrayType(clang_type);
+ clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL);
if (clang_type == 0)
return false;
@@ -6151,8 +6175,10 @@
}
clang_type_t
-ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
+ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete)
{
+ if (is_incomplete)
+ *is_incomplete = false;
if (!clang_type)
return 0;
@@ -6176,6 +6202,8 @@
*member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
if (size)
*size = 0;
+ if (is_incomplete)
+ *is_incomplete = true;
return clang_type;
case clang::Type::VariableArray:
@@ -6195,12 +6223,14 @@
case clang::Type::Typedef:
return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
member_type,
- size);
+ size,
+ is_incomplete);
case clang::Type::Elaborated:
return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
member_type,
- size);
+ size,
+ is_incomplete);
}
return 0;
}