Added support "__attribute__((__vector_size__(B)))" and "__attribute__((ext_vector_ty...
authorGreg Clayton <gclayton@apple.com>
Fri, 5 Apr 2013 23:27:21 +0000 (23:27 +0000)
committerGreg Clayton <gclayton@apple.com>
Fri, 5 Apr 2013 23:27:21 +0000 (23:27 +0000)
Now we can:
1 - see the return value for functions that return types that use the "ext_vector_size"
2 - dump values that use the vector attributes ("expr $ymm0")
3 - modified the DWARF parser to correctly parse GNU vector types from the DWARF by turning them into clang::Type::ExtVector types instead of just standard arrays

llvm-svn: 178924

lldb/include/lldb/Symbol/ClangASTContext.h
lldb/include/lldb/Symbol/ClangASTType.h
lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Symbol/ClangASTContext.cpp
lldb/source/Symbol/ClangASTType.cpp
lldb/test/functionalities/return-value/TestReturnValue.py
lldb/test/functionalities/return-value/call-func.c

index 1b4dd2b..2678af5 100644 (file)
@@ -53,7 +53,11 @@ public:
         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 *);
@@ -578,8 +582,8 @@ public:
     // 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,
@@ -800,7 +804,8 @@ public:
 
     lldb::clang_type_t
     CreateArrayType (lldb::clang_type_t element_type,
-                     size_t element_count);
+                     size_t element_count,
+                     bool is_vector);
 
     //------------------------------------------------------------------
     // Tag Declarations
index 39a1982..d2e33a8 100644 (file)
@@ -110,6 +110,10 @@ public:
     uint64_t
     GetClangTypeByteSize ();
 
+    static uint64_t
+    GetClangTypeByteSize (clang::ASTContext *ast_context,
+                          lldb::clang_type_t clang_type);
+    
     uint64_t
     GetClangTypeBitWidth ();
 
index fbac6a7..4905878 100644 (file)
@@ -470,7 +470,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
     // 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
     
@@ -522,7 +522,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
                 
                 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, 
@@ -567,8 +567,8 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
         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;
@@ -608,7 +608,7 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
             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);
@@ -645,140 +645,181 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
 
 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;
 }
 
@@ -792,20 +833,20 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type
     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;
@@ -838,7 +879,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type
             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;
@@ -851,8 +892,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type
                 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)
@@ -934,8 +975,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type
                             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,
@@ -960,8 +1001,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type
                             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,
@@ -1031,8 +1072,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type
             {
                 // 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);
             }
index d0fd385..2cc3fbc 100644 (file)
@@ -51,7 +51,7 @@ public:
 protected:
     lldb::ValueObjectSP
     GetReturnValueObjectSimple (lldb_private::Thread &thread,
-                    lldb_private::ClangASTType &ast_type) const;
+                                lldb_private::ClangASTType &ast_type) const;
     
 public:    
     virtual lldb::ValueObjectSP
index 751653c..4c400b2 100644 (file)
@@ -57,6 +57,7 @@ public:
     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; }
index a15a208..9eea913 100644 (file)
@@ -1589,12 +1589,12 @@ SymbolFileDWARF::ParseChildMembers
                                 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:
@@ -1837,7 +1837,7 @@ SymbolFileDWARF::ParseChildMembers
                                                                                            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);
                                         }
                                     }
                                 }
@@ -1969,7 +1969,7 @@ SymbolFileDWARF::ParseChildMembers
                                 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;
@@ -3944,7 +3944,7 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
                             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())
     //                          {
@@ -5682,7 +5682,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
                                     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: 
@@ -6041,7 +6041,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
                                 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:
@@ -6159,11 +6159,11 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
                                 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:
@@ -6600,6 +6600,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
                     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)
@@ -6625,8 +6626,9 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
                                 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:
@@ -6661,7 +6663,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
                             {
                                 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;
                             }
@@ -7026,7 +7029,7 @@ SymbolFileDWARF::ParseVariableDIE
                     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)
@@ -7097,7 +7100,7 @@ SymbolFileDWARF::ParseVariableDIE
                         }
                         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:
index 7f8c2ec..8d03e93 100644 (file)
@@ -2918,48 +2918,78 @@ ClangASTContext::GetTypeInfo
     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:
@@ -2983,7 +3013,6 @@ ClangASTContext::GetTypeInfo
         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;
@@ -3027,7 +3056,21 @@ ClangASTContext::GetTypeInfo
     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;
@@ -3182,6 +3225,11 @@ ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type
         }
         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;
@@ -4211,6 +4259,30 @@ ClangASTContext::GetChildClangTypeAtIndex
         }
         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)
@@ -5335,26 +5407,39 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl
 #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;
index 04ba032..16e0d48 100644 (file)
@@ -1227,6 +1227,12 @@ ClangASTType::GetClangTypeByteSize ()
 }
 
 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);
index 0559cba..f5673e2 100644 (file)
@@ -211,6 +211,9 @@ class ReturnValueTestCase(TestBase):
         #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
index f1a411e..c7c68d5 100644 (file)
@@ -301,6 +301,21 @@ return_one_int_one_pointer (struct one_int_one_pointer value)
   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 ()
 {
@@ -351,6 +366,9 @@ 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;
   
 }