[Lldb-commits] [lldb] r183792 - Use llvm::APFloat for formatting if a target is available. Each target when debugging has a "ASTContext" that helps us to use the correct floating point semantics. Now that APFloat supports toString we now use that. If we don't have a target, we still fall back on the old display methodology, but the important formatting should always have a target available and thus use the compiler floating point code.

Greg Clayton gclayton at apple.com
Tue Jun 11 14:56:56 PDT 2013


Author: gclayton
Date: Tue Jun 11 16:56:55 2013
New Revision: 183792

URL: http://llvm.org/viewvc/llvm-project?rev=183792&view=rev
Log:
Use llvm::APFloat for formatting if a target is available. Each target when debugging has a "ASTContext" that helps us to use the correct floating point semantics. Now that APFloat supports toString we now use that. If we don't have a target, we still fall back on the old display methodology, but the important formatting should always have a target available and thus use the compiler floating point code.

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.

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

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Jun 11 16:56:55 2013
@@ -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
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Tue Jun 11 16:56:55 2013
@@ -15,11 +15,15 @@
 #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 *of
     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 DataExtracto
         {
             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 DataExtracto
                 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)
                 {
-                    float f;
-                    if (item_byte_size == 2)
+                    ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
+                    if (clang_ast)
                     {
-                        uint16_t half = this->GetU16(&offset);
-                        f = half2float(half);
+                        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)
+                {
+                    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))
+                    {
+                        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;
 

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Jun 11 16:56:55 2013
@@ -6682,6 +6682,24 @@ ClangASTContext::ConvertStringToFloatVal
     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:
 
 bool
 ClangASTContext::GetCompleteType (clang_type_t clang_type)
-{   
+{
     return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
 }
 

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py Tue Jun 11 16:56:55 2013
@@ -81,7 +81,7 @@ class NamedSummariesDataFormatterTestCas
 
         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',

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp Tue Jun 11 16:56:55 2013
@@ -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.

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py Tue Jun 11 16:56:55 2013
@@ -283,29 +283,29 @@ class SmartArrayDataFormatterTestCase(Te
         
         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(Te
 
         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(Te
             
         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             . at .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 =',

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp?rev=183792&r1=183791&r2=183792&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp Tue Jun 11 16:56:55 2013
@@ -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;
     





More information about the lldb-commits mailing list