Use llvm::APFloat for formatting if a target is available. Each target when debugging...
authorGreg Clayton <gclayton@apple.com>
Tue, 11 Jun 2013 21:56:55 +0000 (21:56 +0000)
committerGreg Clayton <gclayton@apple.com>
Tue, 11 Jun 2013 21:56:55 +0000 (21:56 +0000)
Modified the test programs to use floating point constants that always will display correctly. We had some numbers that were being rounded, and now that we are using clang, we no longer round them and we get more correct results.

llvm-svn: 183792

lldb/include/lldb/Symbol/ClangASTContext.h
lldb/source/Core/DataExtractor.cpp
lldb/source/Symbol/ClangASTContext.cpp
lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
lldb/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp
lldb/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
lldb/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp

index 305775658f42278d9586a879fe60fd68ff158e57..b3da283d6105e6a8648688eb798a82c30633f123 100644 (file)
@@ -1003,7 +1003,16 @@ public:
                                const char *s, 
                                uint8_t *dst, 
                                size_t dst_size);
-    
+
+    lldb::clang_type_t
+    GetFloatTypeFromBitSize (size_t bit_size)
+    {
+        return GetFloatTypeFromBitSize (getASTContext(), bit_size);
+    }
+
+    static lldb::clang_type_t
+    GetFloatTypeFromBitSize (clang::ASTContext *ast,
+                             size_t bit_size);
     //------------------------------------------------------------------
     // Qualifiers
     //------------------------------------------------------------------
index 5b042ce37b66b8a158f42f7e698ff28259672bd1..02ff1e0a470787740fcdbc766514dc86f566efa3 100644 (file)
 #include <sstream>
 #include <string>
 
+#include "clang/AST/ASTContext.h"
+
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/MathExtras.h"
 
+
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/DataBuffer.h"
@@ -30,6 +34,7 @@
 #include "lldb/Core/UUID.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/Target.h"
@@ -1234,8 +1239,8 @@ DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
     return bytes_consumed;
 }
 
-static lldb::offset_t
-DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix)
+static bool
+GetAPInt (const DataExtractor &data, lldb::offset_t *offset_ptr, lldb::offset_t byte_size, llvm::APInt &result)
 {
     llvm::SmallVector<uint64_t, 2> uint64_array;
     lldb::offset_t bytes_left = byte_size;
@@ -1247,20 +1252,22 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of
         {
             if (bytes_left >= 8)
             {
-                u64 = data.GetU64(&offset);
+                u64 = data.GetU64(offset_ptr);
                 bytes_left -= 8;
             }
             else
             {
-                u64 = data.GetMaxU64(&offset, (uint32_t)bytes_left);
+                u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
                 bytes_left = 0;
-            }                        
+            }
             uint64_array.push_back(u64);
         }
+        result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
+        return true;
     }
     else if (byte_order == lldb::eByteOrderBig)
     {
-        lldb::offset_t be_offset = offset + byte_size;
+        lldb::offset_t be_offset = *offset_ptr + byte_size;
         lldb::offset_t temp_offset;
         while (bytes_left > 0)
         {
@@ -1277,28 +1284,36 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of
                 temp_offset = be_offset;
                 u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
                 bytes_left = 0;
-            }                        
+            }
             uint64_array.push_back(u64);
         }
+        *offset_ptr += byte_size;
+        result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
+        return true;
     }
-    else
-        return offset;
+    return false;
+}
 
-    llvm::APInt apint (byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
-    std::string apint_str(apint.toString(radix, is_signed));
-    switch (radix)
+static lldb::offset_t
+DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix)
+{
+    llvm::APInt apint;
+    if (GetAPInt (data, &offset, byte_size, apint))
     {
-        case 2:
-            s->Write ("0b", 2);
-            break;
-        case 8:
-            s->Write ("0", 1);
-            break;
-        case 10:
-            break;
+        std::string apint_str(apint.toString(radix, is_signed));
+        switch (radix)
+        {
+            case 2:
+                s->Write ("0b", 2);
+                break;
+            case 8:
+                s->Write ("0", 1);
+                break;
+            case 10:
+                break;
+        }
+        s->Write(apint_str.c_str(), apint_str.size());
     }
-    s->Write(apint_str.c_str(), apint_str.size());
     return offset;
 }
 
@@ -1702,39 +1717,117 @@ DataExtractor::Dump (Stream *s,
 
         case eFormatFloat:
             {
-                std::ostringstream ss;
-                if (item_byte_size == sizeof(float) || item_byte_size == 2)
+                TargetSP target_sp;
+                bool used_apfloat = false;
+                if (exe_scope)
+                    target_sp = exe_scope->CalculateTarget();
+                if (target_sp)
+                {
+                    ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
+                    if (clang_ast)
+                    {
+                        clang::ASTContext *ast = clang_ast->getASTContext();
+                        if (ast)
+                        {
+                            llvm::SmallVector<char, 256> sv;
+                            // Show full precision when printing float values
+                            const unsigned format_precision = 0;
+                            const unsigned format_max_padding = 100;
+                            size_t item_bit_size = item_byte_size * 8;
+                            
+                            if (item_bit_size == ast->getTypeSize(ast->FloatTy))
+                            {
+                                llvm::APInt apint(item_bit_size, this->GetMaxU64(&offset, item_byte_size));
+                                llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->FloatTy), apint);
+                                apfloat.toString(sv, format_precision, format_max_padding);
+                            }
+                            else if (item_bit_size == ast->getTypeSize(ast->DoubleTy))
+                            {
+                                llvm::APInt apint;
+                                if (GetAPInt (*this, &offset, item_byte_size, apint))
+                                {
+                                    llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->DoubleTy), apint);
+                                    apfloat.toString(sv, format_precision, format_max_padding);
+                                }
+                            }
+                            else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy))
+                            {
+                                llvm::APInt apint;
+                                switch (target_sp->GetArchitecture().GetCore())
+                                {
+                                    case ArchSpec::eCore_x86_32_i386:
+                                    case ArchSpec::eCore_x86_32_i486:
+                                    case ArchSpec::eCore_x86_32_i486sx:
+                                    case ArchSpec::eCore_x86_64_x86_64:
+                                        // clang will assert when contructing the apfloat if we use a 16 byte integer value
+                                        if (GetAPInt (*this, &offset, 10, apint))
+                                        {
+                                            llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint);
+                                            apfloat.toString(sv, format_precision, format_max_padding);
+                                        }
+                                        break;
+                                        
+                                    default:
+                                        if (GetAPInt (*this, &offset, item_byte_size, apint))
+                                        {
+                                            llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint);
+                                            apfloat.toString(sv, format_precision, format_max_padding);
+                                        }
+                                        break;
+                                }
+                            }
+                            else if (item_bit_size == ast->getTypeSize(ast->HalfTy))
+                            {
+                                llvm::APInt apint(item_bit_size, this->GetU16(&offset));
+                                llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->HalfTy), apint);
+                                apfloat.toString(sv, format_precision, format_max_padding);
+                            }
+
+                            if (!sv.empty())
+                            {
+                                s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
+                                used_apfloat = true;
+                            }
+                        }
+                    }
+                }
+                
+                if (!used_apfloat)
                 {
-                    float f;
-                    if (item_byte_size == 2)
+                    std::ostringstream ss;
+                    if (item_byte_size == sizeof(float) || item_byte_size == 2)
+                    {
+                        float f;
+                        if (item_byte_size == 2)
+                        {
+                            uint16_t half = this->GetU16(&offset);
+                            f = half2float(half);
+                        }
+                        else
+                        {
+                            f = GetFloat (&offset);
+                        }
+                        ss.precision(std::numeric_limits<float>::digits10);
+                        ss << f;
+                    } 
+                    else if (item_byte_size == sizeof(double))
+                    {
+                        ss.precision(std::numeric_limits<double>::digits10);
+                        ss << GetDouble(&offset);
+                    }
+                    else if (item_byte_size == sizeof(long double))
                     {
-                        uint16_t half = this->GetU16(&offset);
-                        f = half2float(half);
+                        ss.precision(std::numeric_limits<long double>::digits10);
+                        ss << GetLongDouble(&offset);
                     }
                     else
                     {
-                        f = GetFloat (&offset);
+                        s->Printf("error: unsupported byte size (%zu) for float format", item_byte_size);
+                        return offset;
                     }
-                    ss.precision(std::numeric_limits<float>::digits10);
-                    ss << f;
-                } 
-                else if (item_byte_size == sizeof(double))
-                {
-                    ss.precision(std::numeric_limits<double>::digits10);
-                    ss << GetDouble(&offset);
-                }
-                else if (item_byte_size == sizeof(long double))
-                {
-                    ss.precision(std::numeric_limits<long double>::digits10);
-                    ss << GetLongDouble(&offset);
-                }
-                else
-                {
-                    s->Printf("error: unsupported byte size (%zu) for float format", item_byte_size);
-                    return offset;
+                    ss.flush();
+                    s->Printf("%s", ss.str().c_str());
                 }
-                ss.flush();
-                s->Printf("%s", ss.str().c_str());
             }
             break;
 
index a69343b1fc723c7364b532549c89fe8ce1951eeb..73ed50931e17366559a6dd74aafbb7e169e9c186 100644 (file)
@@ -6682,6 +6682,24 @@ ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_
     return 0;
 }
 
+lldb::clang_type_t
+ClangASTContext::GetFloatTypeFromBitSize (clang::ASTContext *ast,
+                                          size_t bit_size)
+{
+    if (ast)
+    {
+        if (bit_size == ast->getTypeSize(ast->FloatTy))
+            return ast->FloatTy.getAsOpaquePtr();
+        else if (bit_size == ast->getTypeSize(ast->DoubleTy))
+            return ast->DoubleTy.getAsOpaquePtr();
+        else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
+            return ast->LongDoubleTy.getAsOpaquePtr();
+        else if (bit_size == ast->getTypeSize(ast->HalfTy))
+            return ast->HalfTy.getAsOpaquePtr();
+    }
+    return NULL;
+}
+
 unsigned
 ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
 {
@@ -6704,7 +6722,7 @@ ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t cla
 
 bool
 ClangASTContext::GetCompleteType (clang_type_t clang_type)
-{   
+{
     return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
 }
 
index 1507ecefbeebc3c240b1ad37cfdf3176c80b90c9..6ab7f93067c2b6e951ebe5d2375cb756bd9fbdf8 100644 (file)
@@ -81,7 +81,7 @@ class NamedSummariesDataFormatterTestCase(TestBase):
 
         self.expect("frame variable second --summary AllUseIt",
             substrs = ['AllUseIt: x=65',
-                       'y=43.21'])
+                       'y=43.25'])
 
         self.expect("frame variable third --summary AllUseIt",
             substrs = ['AllUseIt: x=96',
index 77ff54dbcd510e002e79b477384b8a2b42abfe36..fdec5fecd3a2fba88699c95ae00b0598750f0321 100644 (file)
@@ -46,7 +46,7 @@ struct Third
 int main (int argc, const char * argv[])
 {
     First first(12,34);
-    Second second(65,43.21);
+    Second second(65,43.25);
     Third *third = new Third(96,'E');
     
     first.dummy = 1; // Set break point at this line.
index 6d3103cda4b7c62078e510f0f7fcc9f7831bdcce..27ca2e1361cf9202909d3ea655a1136e2f8b3747 100644 (file)
@@ -283,29 +283,29 @@ class SmartArrayDataFormatterTestCase(TestBase):
         
         self.expect("frame variable flarr",
                     substrs = ['flarr = arr =',
-                               '{78.5},{77.4},{78},{76.1},{76.7},{76.8},{77}'])
+                               '{78.5},{77.25},{78},{76.125},{76.75},{76.875},{77}'])
         
         self.expect("frame variable other.flarr",
                     substrs = ['flarr = arr = ',
-                               '{25.5},{25.7},{25.9},{26.4},{27.1},{27.3},{26.9}'])
+                               '{25.5},{25.25},{25.125},{26.75},{27.375},{27.5},{26.125}'])
         
 # printing full array as an array
         self.runCmd("type summary add --summary-string \"arr = ${var%float32[]}\" \"float [7]\"")
         
         self.expect("frame variable flarr",
                     substrs = ['flarr = arr =',
-                               '78.5,77.4,78,76.1,76.7,76.8,77'])
+                               '78.5,77.25,78,76.125,76.75,76.875,77'])
         
         self.expect("frame variable other.flarr",
                     substrs = ['flarr = arr =',
-                               '25.5,25.7,25.9,26.4,27.1,27.3,26.9'])
+                               '25.5,25.25,25.125,26.75,27.375,27.5,26.125'])
 
 # using array smart summary strings for pointers should make no sense
         self.runCmd("type summary add --summary-string \"arr = ${var%float32[]}\" \"float *\"")
         self.runCmd("type summary add --summary-string \"arr = ${var%int32_t[]}\" \"int *\"")
 
         self.expect("frame variable flptr", matching=False,
-                    substrs = ['78.5,77.4,78,76.1,76.7,76.8,77'])
+                    substrs = ['78.5,77.25,78,76.125,76.75,76.875,77'])
         
         self.expect("frame variable intptr", matching=False,
                     substrs = ['1,1,2,3,5'])
@@ -316,11 +316,11 @@ class SmartArrayDataFormatterTestCase(TestBase):
 
         self.expect("frame variable flarr",
                     substrs = ['flarr = arr =',
-                               '00 00 9d 42,cd cc 9a 42,00 00 9c 42,33 33 98 42,66 66 99 42,9a 99 99 42,00 00 9a 42'])
+                               '00 00 9d 42,00 80 9a 42,00 00 9c 42,00 40 98 42,00 80 99 42,00 c0 99 42,00 00 9a 42'])
         
         self.expect("frame variable other.flarr",
                     substrs = ['flarr = arr =',
-                               '00 00 cc 41,9a 99 cd 41,33 33 cf 41,33 33 d3 41,cd cc d8 41,66 66 da 41,33 33 d7 41'])
+                               '00 00 cc 41,00 00 ca 41,00 00 c9 41,00 00 d6 41,00 00 db 41,00 00 dc 41,00 00 d1 41'])
 
         self.expect("frame variable intarr",
                     substrs = ['intarr = arr =',
@@ -335,13 +335,11 @@ class SmartArrayDataFormatterTestCase(TestBase):
             
         self.expect("frame variable flarr",
                     substrs = ['flarr = arr =',
-                               '...B,cd cc 9a 42',
-                               'ff.B,9a 99 99 42'])
+                               '00 00 9d 42             ...B,00 80 9a 42             ...B,00 00 9c 42             ...B,00 40 98 42             .@.B,00 80 99 42             ...B,00 c0 99 42             ...B,00 00 9a 42             ...B'])
         
         self.expect("frame variable other.flarr",
                     substrs = ['flarr = arr =',
-                               '...A,33 33 cf 41',
-                               '33.A,cd cc d8 41'])
+                               '00 00 cc 41             ...A,00 00 ca 41             ...A,00 00 c9 41             ...A,00 00 d6 41             ...A,00 00 db 41             ...A,00 00 dc 41             ...A,00 00 d1 41             ...A'])
         
         self.expect("frame variable intarr",
                     substrs = ['intarr = arr =',
index 24ee5be9e9c72e30097cdf4938f09ce2af83acb1..9279e414be3171a72d663fd672d36c2d84651189 100644 (file)
@@ -36,12 +36,12 @@ struct SomeOtherData
         intarr[4] = 5;
         
         flarr[0] = 25.5;
-        flarr[1] = 25.7;
-        flarr[2] = 25.9;
-        flarr[3] = 26.4;
-        flarr[4] = 27.1;
-        flarr[5] = 27.3;
-        flarr[6] = 26.9;
+        flarr[1] = 25.25;
+        flarr[2] = 25.125;
+        flarr[3] = 26.75;
+        flarr[4] = 27.375;
+        flarr[5] = 27.5;
+        flarr[6] = 26.125;
     }
 };
 
@@ -51,7 +51,7 @@ int main (int argc, const char * argv[])
     char *strptr = NULL;
     strptr = "Hello world!";
     int intarr[5] = {1,1,2,3,5};
-    float flarr[7] = {78.5,77.4,78.0,76.1,76.7,76.8,77.0};
+    float flarr[7] = {78.5,77.25,78.0,76.125,76.75,76.875,77.0};
     
     SomeData data;