eTypeIsTemplate = (1u << 14),
eTypeIsTypedef = (1u << 15),
eTypeIsVector = (1u << 16),
- eTypeIsScalar = (1u << 17)
+ eTypeIsScalar = (1u << 17),
+ eTypeIsInteger = (1u << 18),
+ eTypeIsFloat = (1u << 19),
+ eTypeIsComplex = (1u << 20),
+ eTypeIsSigned = (1u << 21)
};
typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
// Returns a mask containing bits from the ClangASTContext::eTypeXXX enumerations
static uint32_t
GetTypeInfo (lldb::clang_type_t clang_type,
- clang::ASTContext *ast, // The AST for clang_type (can be NULL)
- lldb::clang_type_t *pointee_or_element_type); // (can be NULL)
+ clang::ASTContext *ast, // The AST for clang_type (can be NULL)
+ lldb::clang_type_t *pointee_or_element_type); // (can be NULL)
static uint32_t
GetNumChildren (clang::ASTContext *ast,
lldb::clang_type_t
CreateArrayType (lldb::clang_type_t element_type,
- size_t element_count);
+ size_t element_count,
+ bool is_vector);
//------------------------------------------------------------------
// Tag Declarations
uint64_t
GetClangTypeByteSize ();
+ static uint64_t
+ GetClangTypeByteSize (clang::ASTContext *ast_context,
+ lldb::clang_type_t clang_type);
+
uint64_t
GetClangTypeBitWidth ();
// For now, assume that the types in the AST values come from the Target's
// scratch AST.
- clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+ clang::ASTContext *ast = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
// Extract the register context so we can read arguments from registers
if (ClangASTContext::IsIntegerType (value_type, is_signed))
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
ReadIntegerArgument(value->GetScalar(),
bit_width,
return error;
}
- clang::ASTContext *ast_context = new_value_sp->GetClangAST();
- if (!ast_context)
+ clang::ASTContext *ast = new_value_sp->GetClangAST();
+ if (!ast)
{
error.SetErrorString ("Null clang AST for return value.");
return error;
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
if (bit_width <= 64)
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
ValueObjectSP
ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
- ClangASTType &ast_type) const
+ ClangASTType &ast_type) const
{
ValueObjectSP return_valobj_sp;
Value value;
- clang_type_t value_type = ast_type.GetOpaqueQualType();
- if (!value_type)
+ clang_type_t return_value_type = ast_type.GetOpaqueQualType();
+ if (!return_value_type)
return return_valobj_sp;
- clang::ASTContext *ast_context = ast_type.GetASTContext();
- if (!ast_context)
+ clang::ASTContext *ast = ast_type.GetASTContext();
+ if (!ast)
return return_valobj_sp;
- value.SetContext (Value::eContextTypeClangType, value_type);
+ value.SetContext (Value::eContextTypeClangType, return_value_type);
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return return_valobj_sp;
- bool is_signed;
- bool is_complex;
- uint32_t count;
-
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
+ const uint32_t type_flags = ClangASTContext::GetTypeInfo (return_value_type, ast, NULL);
+ if (type_flags & ClangASTContext::eTypeIsScalar)
{
- // For now, assume that the types in the AST values come from the Target's
- // scratch AST.
-
-
- // Extract the register context so we can read arguments from registers
-
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
-
- switch (bit_width)
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & ClangASTContext::eTypeIsInteger)
{
- default:
- case 128:
- // Scalar can't hold 128-bit literals, so we don't handle this
- return return_valobj_sp;
- case 64:
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- break;
- case 32:
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & 0xffffffff);
- else
- value.GetScalar() = (uint32_t)(raw_value & 0xffffffff);
- break;
- case 16:
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & 0xffff);
- else
- value.GetScalar() = (uint16_t)(raw_value & 0xffff);
- break;
- case 8:
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & 0xff);
- else
- value.GetScalar() = (uint8_t)(raw_value & 0xff);
- break;
+ // Extract the register context so we can read arguments from registers
+
+ const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
+ const bool is_signed = (type_flags & ClangASTContext::eTypeIsSigned) != 0;
+ switch (byte_size)
+ {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
}
- }
- else if (ClangASTContext::IsFloatingPointType(value_type, count, is_complex))
- {
- // Don't handle complex yet.
- if (is_complex)
- return return_valobj_sp;
-
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
- if (bit_width <= 64)
+ else if (type_flags & ClangASTContext::eTypeIsFloat)
{
- const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
- RegisterValue xmm0_value;
- if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
+ if (type_flags & ClangASTContext::eTypeIsComplex)
{
- DataExtractor data;
- if (xmm0_value.GetData(data))
+ // Don't handle complex yet.
+ }
+ else
+ {
+ const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ if (byte_size <= sizeof(long double))
{
- lldb::offset_t offset = 0;
- switch (bit_width)
+ const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
+ if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
{
- default:
- return return_valobj_sp;
- case 32:
- value.GetScalar() = (float) data.GetFloat(&offset);
- break;
- case 64:
- value.GetScalar() = (double) data.GetDouble(&offset);
- break;
+ DataExtractor data;
+ if (xmm0_value.GetData(data))
+ {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float))
+ {
+ value.GetScalar() = (float) data.GetFloat(&offset);
+ success = true;
+ }
+ else if (byte_size == sizeof(double))
+ {
+ value.GetScalar() = (double) data.GetDouble(&offset);
+ success = true;
+ }
+ else if (byte_size == sizeof(long double))
+ {
+ // Don't handle long double since that can be encoded as 80 bit floats...
+ }
+ }
}
}
}
}
- else if (bit_width == 128)
- {
- // FIXME: x86_64 returns long doubles in stmm0, which is in some 80 bit long double
- // format, and so we'll have to write some code to convert that into 128 bit long doubles.
-// const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("stmm0", 0);
-// RegisterValue st0_value;
-// if (reg_ctx->ReadRegister (st0_info, st0_value))
-// {
-// DataExtractor data;
-// if (st0_value.GetData(data))
-// {
-// uint32_t offset = 0;
-// value.GetScalar() = (long double) data.GetLongDouble (&offset);
-// return true;
-// }
-// }
-
- return return_valobj_sp;
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+ ast_type.GetASTContext(),
+ value,
+ ConstString(""));
+
}
- else if (ClangASTContext::IsPointerType (value_type))
+ else if (type_flags & ClangASTContext::eTypeIsPointer)
{
unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+ ast_type.GetASTContext(),
+ value,
+ ConstString(""));
}
- else
+ else if (type_flags & ClangASTContext::eTypeIsVector)
{
- return return_valobj_sp;
+ const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ if (byte_size > 0)
+ {
+
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("ymm0", 0);
+ if (altivec_reg == NULL)
+ {
+ altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ if (altivec_reg == NULL)
+ altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+ }
+
+ if (altivec_reg)
+ {
+ if (byte_size <= altivec_reg->byte_size)
+ {
+ ProcessSP process_sp (thread.GetProcess());
+ if (process_sp)
+ {
+ std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(altivec_reg, reg_value))
+ {
+ Error error;
+ if (reg_value.GetAsMemoryData (altivec_reg,
+ heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(),
+ byte_order,
+ error))
+ {
+ DataExtractor data (DataBufferSP (heap_data_ap.release()),
+ byte_order,
+ process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create (&thread,
+ ast,
+ return_value_type,
+ ConstString(""),
+ data);
+ }
+ }
+ }
+ }
+ }
+ }
}
- // If we get here, we have a valid Value, so make our ValueObject out of it:
-
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
- value,
- ConstString(""));
return return_valobj_sp;
}
if (return_valobj_sp)
return return_valobj_sp;
- clang_type_t ret_value_type = ast_type.GetOpaqueQualType();
- if (!ret_value_type)
+ clang_type_t return_value_type = ast_type.GetOpaqueQualType();
+ if (!return_value_type)
return return_valobj_sp;
- clang::ASTContext *ast_context = ast_type.GetASTContext();
- if (!ast_context)
+ clang::ASTContext *ast = ast_type.GetASTContext();
+ if (!ast)
return return_valobj_sp;
RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
if (!reg_ctx_sp)
return return_valobj_sp;
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, ret_value_type);
- if (ClangASTContext::IsAggregateType(ret_value_type))
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, return_value_type);
+ if (ClangASTContext::IsAggregateType(return_value_type))
{
Target *target = exe_ctx.GetTargetPtr();
bool is_memory = true;
uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far
uint32_t integer_bytes = 0; // Tracks how much of the rax/rds registers we've consumed so far
- uint32_t num_children = ClangASTContext::GetNumFields (ast_context, ret_value_type);
+ uint32_t num_children = ClangASTContext::GetNumFields (ast, return_value_type);
// Since we are in the small struct regime, assume we are not in memory.
is_memory = false;
bool is_complex;
uint32_t count;
- clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context, ret_value_type, idx, name, &field_bit_offset, NULL, NULL);
- size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, field_clang_type);
+ clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast, return_value_type, idx, name, &field_bit_offset, NULL, NULL);
+ size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast, field_clang_type);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
else
{
uint64_t next_field_bit_offset = 0;
- clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
- ret_value_type,
+ clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
+ return_value_type,
idx + 1,
name,
&next_field_bit_offset,
else
{
uint64_t prev_field_bit_offset = 0;
- clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
- ret_value_type,
+ clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
+ return_value_type,
idx - 1,
name,
&prev_field_bit_offset,
{
// The result is in our data buffer. Let's make a variable object out of it:
return_valobj_sp = ValueObjectConstResult::Create (&thread,
- ast_context,
- ret_value_type,
+ ast,
+ return_value_type,
ConstString(""),
return_ext);
}
protected:
lldb::ValueObjectSP
GetReturnValueObjectSimple (lldb_private::Thread &thread,
- lldb_private::ClangASTType &ast_type) const;
+ lldb_private::ClangASTType &ast_type) const;
public:
virtual lldb::ValueObjectSP
uint64_t Reference(const DWARFCompileUnit* cu) const;
uint64_t Reference (dw_offset_t offset) const;
bool ResolveCompileUnitReferences(const DWARFCompileUnit* cu);
+ bool Boolean() const { return m_value.value.uval != 0; }
uint64_t Unsigned() const { return m_value.value.uval; }
void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
int64_t Signed() const { return m_value.value.sval; }
break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
- case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
+ case DW_AT_external: is_external = form_value.Boolean(); break;
default:
case DW_AT_declaration:
MakeUserID(parent_die->GetOffset()));
}
- member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0);
+ member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0, false);
}
}
}
accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
break;
- case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
+ case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
default:
case DW_AT_sibling:
break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_location:
// if (form_value.BlockData())
// {
break;
case DW_AT_declaration:
- is_forward_declaration = form_value.Unsigned() != 0;
+ is_forward_declaration = form_value.Boolean();
break;
case DW_AT_APPLE_runtime_class:
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; //is_forward_declaration = form_value.Unsigned() != 0; break;
+ case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_bit_stride:
case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Unsigned() != 0; break;
- case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
- case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
- case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_inline: is_inline = form_value.Boolean(); break;
+ case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
+ case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_external:
int64_t first_index = 0;
uint32_t byte_stride = 0;
uint32_t bit_stride = 0;
+ bool is_vector = false;
const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
if (num_attributes > 0)
case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
+ case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break;
case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Unsigned() != 0; break;
+ case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_data_location:
{
num_elements = *pos;
clang_type = ast.CreateArrayType (array_element_type,
- num_elements);
+ num_elements,
+ is_vector);
array_element_type = clang_type;
array_element_bit_stride = num_elements ? array_element_bit_stride * num_elements : array_element_bit_stride;
}
case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_uid = form_value.Reference(dwarf_cu); break;
- case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
+ case DW_AT_external: is_external = form_value.Boolean(); break;
case DW_AT_const_value:
// If we have already found a DW_AT_location attribute, ignore this attribute.
if (!has_explicit_location)
}
break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration:
case DW_AT_description:
switch (type_class)
{
case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
{
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- if (ast && pointee_or_element_clang_type)
- *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
- return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue | eTypeIsObjC;
+ const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+
+ uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
+ switch (builtin_type->getKind())
+ {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ if (ast && pointee_or_element_clang_type)
+ *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
break;
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
- default:
- break;
+
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ builtin_type_flags |= eTypeIsScalar;
+ if (builtin_type->isInteger())
+ {
+ builtin_type_flags |= eTypeIsInteger;
+ if (builtin_type->isSignedInteger())
+ builtin_type_flags |= eTypeIsSigned;
+ }
+ else if (builtin_type->isFloatingPoint())
+ builtin_type_flags |= eTypeIsFloat;
+ break;
+ default:
+ break;
+ }
+ return builtin_type_flags;
}
- return eTypeIsBuiltIn | eTypeHasValue;
- case clang::Type::BlockPointer:
+ case clang::Type::BlockPointer:
if (pointee_or_element_clang_type)
*pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
- case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
+ case clang::Type::Complex:
+ {
+ uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+ const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal());
+ if (complex_type)
+ {
+ QualType complex_element_type (complex_type->getElementType());
+ if (complex_element_type->isIntegerType())
+ complex_type_flags |= eTypeIsFloat;
+ else if (complex_element_type->isFloatingType())
+ complex_type_flags |= eTypeIsInteger;
+ }
+ return complex_type_flags;
+ }
+ break;
case clang::Type::ConstantArray:
case clang::Type::DependentSizedArray:
return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
ast,
pointee_or_element_clang_type);
- case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
case clang::Type::InjectedClassName: return 0;
case clang::Type::TypeOfExpr: return 0;
case clang::Type::TypeOf: return 0;
case clang::Type::UnresolvedUsing: return 0;
- case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ {
+ uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
+ const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal());
+ if (vector_type)
+ {
+ if (vector_type->isIntegerType())
+ vector_type_flags |= eTypeIsFloat;
+ else if (vector_type->isFloatingType())
+ vector_type_flags |= eTypeIsInteger;
+ }
+ return vector_type_flags;
+ }
default: return 0;
}
return 0;
}
break;
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements();
+ break;
+
case clang::Type::ConstantArray:
num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
break;
}
break;
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ if (idx_is_valid)
+ {
+ const VectorType *array = cast<VectorType>(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), "[%zu]", idx);
+
+ child_name.assign(element_name);
+ assert(field_type_info.first % 8 == 0);
+ child_byte_size = field_type_info.first / 8;
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return array->getElementType().getAsOpaquePtr();
+ }
+ }
+ }
+ break;
+
case clang::Type::ConstantArray:
case clang::Type::IncompleteArray:
if (ignore_array_bounds || idx_is_valid)
#pragma mark Array Types
clang_type_t
-ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count)
+ClangASTContext::CreateArrayType (clang_type_t element_type,
+ size_t element_count,
+ bool is_vector)
{
if (element_type)
{
ASTContext *ast = getASTContext();
assert (ast != NULL);
- llvm::APInt ap_element_count (64, element_count);
- if (element_count == 0)
- {
- return ast->getIncompleteArrayType(QualType::getFromOpaquePtr(element_type),
- ArrayType::Normal,
- 0).getAsOpaquePtr();
+ QualType element_qual_type(QualType::getFromOpaquePtr(element_type));
+
+ if (is_vector)
+ {
+ return ast->getExtVectorType(element_qual_type, element_count).getAsOpaquePtr();
}
else
{
- return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
- ap_element_count,
- ArrayType::Normal,
- 0).getAsOpaquePtr(); // ElemQuals
+
+ llvm::APInt ap_element_count (64, element_count);
+ if (element_count == 0)
+ {
+ return ast->getIncompleteArrayType(element_qual_type,
+ ArrayType::Normal,
+ 0).getAsOpaquePtr();
+
+ }
+ else
+ {
+ return ast->getConstantArrayType(element_qual_type,
+ ap_element_count,
+ ArrayType::Normal,
+ 0).getAsOpaquePtr(); // ElemQuals
+ }
}
}
return NULL;
}
uint64_t
+ClangASTType::GetClangTypeByteSize (clang::ASTContext *ast_context, clang_type_t clang_type)
+{
+ return (GetClangTypeBitWidth (ast_context, clang_type) + 7) / 8;
+}
+
+uint64_t
ClangASTType::GetClangTypeBitWidth ()
{
return GetClangTypeBitWidth (m_ast, m_type);
#self.return_and_test_struct_value ("return_one_int_one_double_packed")
self.return_and_test_struct_value ("return_one_int_one_long")
+ self.return_and_test_struct_value ("return_vector_size_float32")
+ self.return_and_test_struct_value ("return_ext_vector_size_float32")
+
if __name__ == '__main__':
import atexit
return value;
}
+typedef float vector_size_float32 __attribute__((__vector_size__(16)));
+typedef float ext_vector_size_float32 __attribute__((ext_vector_type(4)));
+
+vector_size_float32
+return_vector_size_float32 (vector_size_float32 value)
+{
+ return value;
+}
+
+ext_vector_size_float32
+return_ext_vector_size_float32 (ext_vector_size_float32 value)
+{
+ return value;
+}
+
int
main ()
{
return_one_int_one_double_packed ((struct one_int_one_double_packed) {10, 20.0});
return_one_int_one_long ((struct one_int_one_long) {10, 20});
+ return_vector_size_float32 (( vector_size_float32 ){1.5, 2.25, 4.125, 8.0625});
+ return_ext_vector_size_float32 ((ext_vector_size_float32){ 16.5, 32.25, 64.125, 128.0625});
+
return 0;
}