[Lldb-commits] [lldb] r177454 - The formatters for std::shared_ptr, std::weak_ptr, std::list, std::vector and std::map as provided by libc++ are now written in C++ instead of Python
Enrico Granata
egranata at apple.com
Tue Mar 19 15:58:48 PDT 2013
Author: enrico
Date: Tue Mar 19 17:58:48 2013
New Revision: 177454
URL: http://llvm.org/viewvc/llvm-project?rev=177454&view=rev
Log:
The formatters for std::shared_ptr, std::weak_ptr, std::list, std::vector and std::map as provided by libc++ are now written in C++ instead of Python
std::deque is still in Python but is much less commonly used
Added:
lldb/trunk/source/DataFormatters/CF.cpp
lldb/trunk/source/DataFormatters/Cocoa.cpp
lldb/trunk/source/DataFormatters/LibCxxList.cpp
lldb/trunk/source/DataFormatters/LibCxxMap.cpp
Modified:
lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h
lldb/trunk/include/lldb/Symbol/ClangASTContext.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp
lldb/trunk/source/DataFormatters/FormatManager.cpp
lldb/trunk/source/DataFormatters/LibCxx.cpp
lldb/trunk/source/DataFormatters/TypeSynthetic.cpp
lldb/trunk/source/Symbol/ClangASTContext.cpp
Modified: lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h Tue Mar 19 17:58:48 2013
@@ -11,6 +11,8 @@
#define liblldb_CXXFormatterFunctions_h_
#include <stdint.h>
+#include <time.h>
+
#include "lldb/lldb-forward.h"
#include "lldb/Core/ConstString.h"
@@ -49,6 +51,9 @@ namespace lldb_private {
size_t
ExtractIndexFromString (const char* item_name);
+ time_t
+ GetOSXEpoch ();
+
bool
Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* and unichar*
@@ -684,6 +689,150 @@ namespace lldb_private {
SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+ class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxSharedPtrSyntheticFrontEnd ();
+ private:
+ ValueObject* m_cntrl;
+ lldb::ValueObjectSP m_count_sp;
+ lldb::ValueObjectSP m_weak_count_sp;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_byte_order;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxStdVectorSyntheticFrontEnd ();
+ private:
+ ValueObject* m_start;
+ ValueObject* m_finish;
+ ClangASTType m_element_type;
+ uint32_t m_element_size;
+ std::map<size_t,lldb::ValueObjectSP> m_children;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxStdListSyntheticFrontEnd ();
+ private:
+ bool
+ HasLoop();
+
+ static const size_t g_list_capping_size = 255;
+ static const bool g_use_loop_detect = true;
+ lldb::addr_t m_node_address;
+ ValueObject* m_head;
+ ValueObject* m_tail;
+ ClangASTType m_element_type;
+ uint32_t m_element_size;
+ size_t m_count;
+ std::map<size_t,lldb::ValueObjectSP> m_children;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxStdMapSyntheticFrontEnd ();
+ private:
+ bool
+ GetDataType();
+
+ void
+ GetValueOffset (const lldb::ValueObjectSP& node);
+
+ static const size_t g_map_capping_size = 255;
+ ValueObject* m_tree;
+ ValueObject* m_root_node;
+ ClangASTType m_element_type;
+ uint32_t m_element_size;
+ uint32_t m_skip_size;
+ size_t m_count;
+ std::map<size_t,lldb::ValueObjectSP> m_children;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
} // namespace formatters
} // namespace lldb_private
Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Mar 19 17:58:48 2013
@@ -615,6 +615,15 @@ public:
uint64_t *bit_offset_ptr,
uint32_t *bitfield_bit_size_ptr,
bool *is_bitfield_ptr);
+
+ static size_t
+ GetIndexOfFieldWithName (clang::ASTContext *ast,
+ lldb::clang_type_t clang_type,
+ const char* name,
+ lldb::clang_type_t* field_clang_type = NULL,
+ uint64_t *bit_offset_ptr = NULL,
+ uint32_t *bitfield_bit_size_ptr = NULL,
+ bool *is_bitfield_ptr = NULL);
static uint32_t
GetNumPointeeChildren (lldb::clang_type_t clang_type);
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Mar 19 17:58:48 2013
@@ -549,6 +549,10 @@
94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256E16B0A4260059775D /* TypeSummary.cpp */; };
94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256F16B0A4270059775D /* TypeSynthetic.cpp */; };
94CB257416B1D3880059775D /* FormatCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB257316B1D3870059775D /* FormatCache.cpp */; };
+ 94CD704D16F8DDEA00CF1E42 /* CF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704B16F8DDEA00CF1E42 /* CF.cpp */; };
+ 94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */; };
+ 94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */; };
+ 94CD705216F8F5BC00CF1E42 /* LibCxxMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */; };
94D0B10C16D5535900EA9C70 /* LibCxx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */; };
94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */; };
94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A716CEB55F00833B6E /* NSArray.cpp */; };
@@ -1603,6 +1607,10 @@
94CB256F16B0A4270059775D /* TypeSynthetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSynthetic.cpp; path = source/DataFormatters/TypeSynthetic.cpp; sourceTree = "<group>"; };
94CB257316B1D3870059775D /* FormatCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatCache.cpp; path = source/DataFormatters/FormatCache.cpp; sourceTree = "<group>"; };
94CB257516B1D3910059775D /* FormatCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatCache.h; path = include/lldb/DataFormatters/FormatCache.h; sourceTree = "<group>"; };
+ 94CD704B16F8DDEA00CF1E42 /* CF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CF.cpp; path = source/DataFormatters/CF.cpp; sourceTree = "<group>"; };
+ 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Cocoa.cpp; path = source/DataFormatters/Cocoa.cpp; sourceTree = "<group>"; };
+ 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxList.cpp; path = source/DataFormatters/LibCxxList.cpp; sourceTree = "<group>"; };
+ 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxMap.cpp; path = source/DataFormatters/LibCxxMap.cpp; sourceTree = "<group>"; };
94D0B10A16D5535900EA9C70 /* LibCxx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxx.cpp; path = source/DataFormatters/LibCxx.cpp; sourceTree = "<group>"; };
94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibStdcpp.cpp; path = source/DataFormatters/LibStdcpp.cpp; sourceTree = "<group>"; };
94D6A0A716CEB55F00833B6E /* NSArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSArray.cpp; path = source/DataFormatters/NSArray.cpp; sourceTree = "<group>"; };
@@ -3422,6 +3430,8 @@
94CB255616B0683B0059775D /* DataFormatters */ = {
isa = PBXGroup;
children = (
+ 94CD704B16F8DDEA00CF1E42 /* CF.cpp */,
+ 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */,
94CB255F16B069800059775D /* CXXFormatterFunctions.h */,
94CB255716B069770059775D /* CXXFormatterFunctions.cpp */,
94CB256016B069800059775D /* DataVisualization.h */,
@@ -3434,6 +3444,8 @@
94CB255A16B069770059775D /* FormatManager.cpp */,
94CB256316B069800059775D /* FormatNavigator.h */,
94D0B10A16D5535900EA9C70 /* LibCxx.cpp */,
+ 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */,
+ 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */,
94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */,
94D6A0A716CEB55F00833B6E /* NSArray.cpp */,
94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */,
@@ -3939,6 +3951,7 @@
2689FFF113353DB600698AC0 /* BreakpointID.cpp in Sources */,
2689FFF313353DB600698AC0 /* BreakpointIDList.cpp in Sources */,
2689FFF513353DB600698AC0 /* BreakpointList.cpp in Sources */,
+ 94CD704D16F8DDEA00CF1E42 /* CF.cpp in Sources */,
2689FFF713353DB600698AC0 /* BreakpointLocation.cpp in Sources */,
2689FFF913353DB600698AC0 /* BreakpointLocationCollection.cpp in Sources */,
2689FFFB13353DB600698AC0 /* BreakpointLocationList.cpp in Sources */,
@@ -3946,6 +3959,7 @@
2689FFFF13353DB600698AC0 /* BreakpointResolver.cpp in Sources */,
2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */,
2689000313353DB600698AC0 /* BreakpointResolverFileLine.cpp in Sources */,
+ 94CD705216F8F5BC00CF1E42 /* LibCxxMap.cpp in Sources */,
2689000513353DB600698AC0 /* BreakpointResolverName.cpp in Sources */,
2689000713353DB600698AC0 /* BreakpointSite.cpp in Sources */,
2689000913353DB600698AC0 /* BreakpointSiteList.cpp in Sources */,
@@ -4292,12 +4306,14 @@
2697A39315E404B1003E682C /* OptionValueArch.cpp in Sources */,
94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
94D6A0AC16CEB55F00833B6E /* NSSet.cpp in Sources */,
+ 94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */,
2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */,
947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */,
262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */,
94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */,
94CB255B16B069770059775D /* CXXFormatterFunctions.cpp in Sources */,
94CB255C16B069770059775D /* DataVisualization.cpp in Sources */,
+ 94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */,
94CB255D16B069770059775D /* FormatClasses.cpp in Sources */,
94CB255E16B069770059775D /* FormatManager.cpp in Sources */,
94CB256616B096F10059775D /* TypeCategory.cpp in Sources */,
Added: lldb/trunk/source/DataFormatters/CF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/CF.cpp?rev=177454&view=auto
==============================================================================
--- lldb/trunk/source/DataFormatters/CF.cpp (added)
+++ lldb/trunk/source/DataFormatters/CF.cpp Tue Mar 19 17:58:48 2013
@@ -0,0 +1,299 @@
+//===-- CF.cpp ----------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ time_t epoch = GetOSXEpoch();
+ epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
+ tm *tm_date = localtime(&epoch);
+ if (!tm_date)
+ return false;
+ std::string buffer(1024,0);
+ if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
+ return false;
+ stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+ return true;
+}
+
+bool
+lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint32_t count = 0;
+
+ bool is_type_ok = false; // check to see if this is a CFBag we know about
+ if (descriptor->IsCFType())
+ {
+ ConstString type_name(valobj.GetTypeName());
+ if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag"))
+ {
+ if (valobj.IsPointerType())
+ is_type_ok = true;
+ }
+ }
+
+ if (is_type_ok == false)
+ {
+ StackFrameSP frame_sp(valobj.GetFrameSP());
+ if (!frame_sp)
+ return false;
+ ValueObjectSP count_sp;
+ StreamString expr;
+ expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
+ if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
+ return false;
+ if (!count_sp)
+ return false;
+ count = count_sp->GetValueAsUnsigned(0);
+ }
+ else
+ {
+ uint32_t offset = 2*ptr_size+4 + valobj_addr;
+ Error error;
+ count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ stream.Printf("@\"%u value%s\"",
+ count,(count == 1 ? "" : "s"));
+ return true;
+}
+
+bool
+lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint32_t count = 0;
+
+ bool is_type_ok = false; // check to see if this is a CFBag we know about
+ if (descriptor->IsCFType())
+ {
+ ConstString type_name(valobj.GetTypeName());
+ if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
+ {
+ if (valobj.IsPointerType())
+ is_type_ok = true;
+ }
+ }
+
+ if (is_type_ok == false)
+ return false;
+
+ Error error;
+ count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
+ addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
+ if (error.Fail())
+ return false;
+ // make sure we do not try to read huge amounts of data
+ if (num_bytes > 1024)
+ num_bytes = 1024;
+ DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
+ num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
+ if (error.Fail())
+ return false;
+ for (int byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
+ {
+ uint8_t byte = buffer_sp->GetBytes()[byte_idx];
+ bool bit0 = (byte & 1) == 1;
+ bool bit1 = (byte & 2) == 2;
+ bool bit2 = (byte & 4) == 4;
+ bool bit3 = (byte & 8) == 8;
+ bool bit4 = (byte & 16) == 16;
+ bool bit5 = (byte & 32) == 32;
+ bool bit6 = (byte & 64) == 64;
+ bool bit7 = (byte & 128) == 128;
+ stream.Printf("%c%c%c%c %c%c%c%c ",
+ (bit7 ? '1' : '0'),
+ (bit6 ? '1' : '0'),
+ (bit5 ? '1' : '0'),
+ (bit4 ? '1' : '0'),
+ (bit3 ? '1' : '0'),
+ (bit2 ? '1' : '0'),
+ (bit1 ? '1' : '0'),
+ (bit0 ? '1' : '0'));
+ count -= 8;
+ }
+ {
+ // print the last byte ensuring we do not print spurious bits
+ uint8_t byte = buffer_sp->GetBytes()[num_bytes-1];
+ bool bit0 = (byte & 1) == 1;
+ bool bit1 = (byte & 2) == 2;
+ bool bit2 = (byte & 4) == 4;
+ bool bit3 = (byte & 8) == 8;
+ bool bit4 = (byte & 16) == 16;
+ bool bit5 = (byte & 32) == 32;
+ bool bit6 = (byte & 64) == 64;
+ bool bit7 = (byte & 128) == 128;
+ if (count)
+ {
+ stream.Printf("%c",bit7 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit6 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit5 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit4 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit3 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit2 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit1 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ {
+ stream.Printf("%c",bit0 ? '1' : '0');
+ count -= 1;
+ }
+ }
+ return true;
+}
+
+bool
+lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint32_t count = 0;
+
+ bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
+ if (descriptor->IsCFType())
+ {
+ ConstString type_name(valobj.GetTypeName());
+ if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap"))
+ {
+ if (valobj.IsPointerType())
+ is_type_ok = true;
+ }
+ }
+
+ if (is_type_ok == false)
+ {
+ StackFrameSP frame_sp(valobj.GetFrameSP());
+ if (!frame_sp)
+ return false;
+ ValueObjectSP count_sp;
+ StreamString expr;
+ expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
+ if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
+ return false;
+ if (!count_sp)
+ return false;
+ count = count_sp->GetValueAsUnsigned(0);
+ }
+ else
+ {
+ uint32_t offset = 2*ptr_size;
+ Error error;
+ count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ stream.Printf("@\"%u item%s\"",
+ count,(count == 1 ? "" : "s"));
+ return true;
+}
Modified: lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp (original)
+++ lldb/trunk/source/DataFormatters/CXXFormatterFunctions.cpp Tue Mar 19 17:58:48 2013
@@ -9,8 +9,6 @@
#include "lldb/lldb-python.h"
-#include <time.h>
-
#include "lldb/DataFormatters/CXXFormatterFunctions.h"
#include "llvm/Support/ConvertUTF.h"
@@ -642,656 +640,6 @@ lldb_private::formatters::NSDataSummaryP
return true;
}
-bool
-lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSBundle"))
- {
- uint64_t offset = 5 * ptr_size;
- ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
- StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
- if (was_nsstring_ok && summary_stream.GetSize() > 0)
- {
- stream.Printf("%s",summary_stream.GetData());
- return true;
- }
- }
- // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
- // which is encoded differently and needs to be handled by running code
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream);
-}
-
-bool
-lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"__NSTimeZone"))
- {
- uint64_t offset = ptr_size;
- ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
- StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
- if (was_nsstring_ok && summary_stream.GetSize() > 0)
- {
- stream.Printf("%s",summary_stream.GetData());
- return true;
- }
- }
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
-}
-
-bool
-lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSConcreteNotification"))
- {
- uint64_t offset = ptr_size;
- ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
- StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
- if (was_nsstring_ok && summary_stream.GetSize() > 0)
- {
- stream.Printf("%s",summary_stream.GetData());
- return true;
- }
- }
- // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
- // which is encoded differently and needs to be handled by running code
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
-}
-
-bool
-lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- uint64_t port_number = 0;
-
- do
- {
- if (!strcmp(class_name,"NSMachPort"))
- {
- uint64_t offset = (ptr_size == 4 ? 12 : 20);
- Error error;
- port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
- if (error.Success())
- break;
- }
- if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number))
- return false;
- } while (false);
-
- stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
- return true;
-}
-
-bool
-lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint32_t count = 0;
-
- bool is_type_ok = false; // check to see if this is a CFBag we know about
- if (descriptor->IsCFType())
- {
- ConstString type_name(valobj.GetTypeName());
- if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag"))
- {
- if (valobj.IsPointerType())
- is_type_ok = true;
- }
- }
-
- if (is_type_ok == false)
- {
- StackFrameSP frame_sp(valobj.GetFrameSP());
- if (!frame_sp)
- return false;
- ValueObjectSP count_sp;
- StreamString expr;
- expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
- if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
- return false;
- if (!count_sp)
- return false;
- count = count_sp->GetValueAsUnsigned(0);
- }
- else
- {
- uint32_t offset = 2*ptr_size+4 + valobj_addr;
- Error error;
- count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
- if (error.Fail())
- return false;
- }
- stream.Printf("@\"%u value%s\"",
- count,(count == 1 ? "" : "s"));
- return true;
-}
-
-bool
-lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint32_t count = 0;
-
- bool is_type_ok = false; // check to see if this is a CFBag we know about
- if (descriptor->IsCFType())
- {
- ConstString type_name(valobj.GetTypeName());
- if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
- {
- if (valobj.IsPointerType())
- is_type_ok = true;
- }
- }
-
- if (is_type_ok == false)
- return false;
-
- Error error;
- count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
- addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
- if (error.Fail())
- return false;
- // make sure we do not try to read huge amounts of data
- if (num_bytes > 1024)
- num_bytes = 1024;
- DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
- num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
- if (error.Fail())
- return false;
- for (int byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
- {
- uint8_t byte = buffer_sp->GetBytes()[byte_idx];
- bool bit0 = (byte & 1) == 1;
- bool bit1 = (byte & 2) == 2;
- bool bit2 = (byte & 4) == 4;
- bool bit3 = (byte & 8) == 8;
- bool bit4 = (byte & 16) == 16;
- bool bit5 = (byte & 32) == 32;
- bool bit6 = (byte & 64) == 64;
- bool bit7 = (byte & 128) == 128;
- stream.Printf("%c%c%c%c %c%c%c%c ",
- (bit7 ? '1' : '0'),
- (bit6 ? '1' : '0'),
- (bit5 ? '1' : '0'),
- (bit4 ? '1' : '0'),
- (bit3 ? '1' : '0'),
- (bit2 ? '1' : '0'),
- (bit1 ? '1' : '0'),
- (bit0 ? '1' : '0'));
- count -= 8;
- }
- {
- // print the last byte ensuring we do not print spurious bits
- uint8_t byte = buffer_sp->GetBytes()[num_bytes-1];
- bool bit0 = (byte & 1) == 1;
- bool bit1 = (byte & 2) == 2;
- bool bit2 = (byte & 4) == 4;
- bool bit3 = (byte & 8) == 8;
- bool bit4 = (byte & 16) == 16;
- bool bit5 = (byte & 32) == 32;
- bool bit6 = (byte & 64) == 64;
- bool bit7 = (byte & 128) == 128;
- if (count)
- {
- stream.Printf("%c",bit7 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit6 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit5 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit4 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit3 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit2 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit1 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit0 ? '1' : '0');
- count -= 1;
- }
- }
- return true;
-}
-
-bool
-lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint32_t count = 0;
-
- bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
- if (descriptor->IsCFType())
- {
- ConstString type_name(valobj.GetTypeName());
- if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap"))
- {
- if (valobj.IsPointerType())
- is_type_ok = true;
- }
- }
-
- if (is_type_ok == false)
- {
- StackFrameSP frame_sp(valobj.GetFrameSP());
- if (!frame_sp)
- return false;
- ValueObjectSP count_sp;
- StreamString expr;
- expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
- if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
- return false;
- if (!count_sp)
- return false;
- count = count_sp->GetValueAsUnsigned(0);
- }
- else
- {
- uint32_t offset = 2*ptr_size;
- Error error;
- count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
- if (error.Fail())
- return false;
- }
- stream.Printf("@\"%u item%s\"",
- count,(count == 1 ? "" : "s"));
- return true;
-}
-
-bool
-lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- uint64_t count = 0;
-
- do {
- if (!strcmp(class_name,"NSIndexSet") || !strcmp(class_name,"NSMutableIndexSet"))
- {
- Error error;
- uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 4, 0, error);
- if (error.Fail())
- return false;
- // this means the set is empty - count = 0
- if ((mode & 1) == 1)
- {
- count = 0;
- break;
- }
- if ((mode & 2) == 2)
- mode = 1; // this means the set only has one range
- else
- mode = 2; // this means the set has multiple ranges
- if (mode == 1)
- {
- count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+3*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else
- {
- // read a pointer to the data at 2*ptr_size
- count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- // read the data at 2*ptr_size from the first location
- count = process_sp->ReadUnsignedIntegerFromMemory(count+2*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- }
- else
- {
- if (!ExtractValueFromObjCExpression(valobj, "unsigned long long int", "count", count))
- return false;
- }
- } while (false);
- stream.Printf("%llu index%s",
- count,
- (count == 1 ? "" : "es"));
- return true;
-}
-
-bool
-lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
- {
- if (descriptor->IsTagged())
- {
- // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
- int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
- uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
-
- switch (i_bits)
- {
- case 0:
- stream.Printf("(char)%hhd",(char)value);
- break;
- case 4:
- stream.Printf("(short)%hd",(short)value);
- break;
- case 8:
- stream.Printf("(int)%d",(int)value);
- break;
- case 12:
- stream.Printf("(long)%" PRId64,value);
- break;
- default:
- stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
- break;
- }
- return true;
- }
- else
- {
- Error error;
- uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
- uint64_t data_location = valobj_addr + 2*ptr_size;
- uint64_t value = 0;
- if (error.Fail())
- return false;
- switch (data_type)
- {
- case 1: // 0B00001
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(char)%hhd",(char)value);
- break;
- case 2: // 0B0010
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(short)%hd",(short)value);
- break;
- case 3: // 0B0011
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(int)%d",(int)value);
- break;
- case 17: // 0B10001
- data_location += 8;
- case 4: // 0B0100
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(long)%" PRId64,value);
- break;
- case 5: // 0B0101
- {
- uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
- if (error.Fail())
- return false;
- float flt_value = *((float*)&flt_as_int);
- stream.Printf("(float)%f",flt_value);
- break;
- }
- case 6: // 0B0110
- {
- uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
- if (error.Fail())
- return false;
- double dbl_value = *((double*)&dbl_as_lng);
- stream.Printf("(double)%g",dbl_value);
- break;
- }
- default:
- stream.Printf("absurd: dt=%d",data_type);
- break;
- }
- return true;
- }
- }
- else
- {
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "stringValue", stream);
- }
-}
-
static bool
ReadAsciiBufferAndDumpToStream (lldb::addr_t location,
lldb::ProcessSP& process_sp,
@@ -1488,71 +836,6 @@ lldb_private::formatters::RuntimeSpecifi
}
bool
-lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (strcmp(class_name, "NSURL") == 0)
- {
- uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
- uint64_t offset_base = offset_text + ptr_size;
- ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
- ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
- if (!text)
- return false;
- if (text->GetValueAsUnsigned(0) == 0)
- return false;
- StreamString summary;
- if (!NSStringSummaryProvider(*text, summary))
- return false;
- if (base && base->GetValueAsUnsigned(0))
- {
- if (summary.GetSize() > 0)
- summary.GetString().resize(summary.GetSize()-1);
- summary.Printf(" -- ");
- StreamString base_summary;
- if (NSURLSummaryProvider(*base, base_summary) && base_summary.GetSize() > 0)
- summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
- }
- if (summary.GetSize())
- {
- stream.Printf("%s",summary.GetData());
- return true;
- }
- }
- else
- {
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "description", stream);
- }
- return false;
-}
-
-bool
lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
{
const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
@@ -1623,7 +906,7 @@ lldb_private::formatters::ObjCSELSummary
// POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
// this call gives the POSIX equivalent of the Cocoa epoch
time_t
-GetOSXEpoch ()
+lldb_private::formatters::GetOSXEpoch ()
{
static time_t epoch = 0;
if (!epoch)
@@ -1644,107 +927,6 @@ GetOSXEpoch ()
return epoch;
}
-bool
-lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t date_value_bits = 0;
- double date_value = 0.0;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (strcmp(class_name,"NSDate") == 0 ||
- strcmp(class_name,"__NSDate") == 0 ||
- strcmp(class_name,"__NSTaggedDate") == 0)
- {
- if (descriptor->IsTagged())
- {
- uint64_t info_bits = (valobj_addr & 0xF0ULL) >> 4;
- uint64_t value_bits = (valobj_addr & ~0x0000000000000000FFULL) >> 8;
- date_value_bits = ((value_bits << 8) | (info_bits << 4));
- date_value = *((double*)&date_value_bits);
- }
- else
- {
- Error error;
- date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 8, 0, error);
- date_value = *((double*)&date_value_bits);
- if (error.Fail())
- return false;
- }
- }
- else if (!strcmp(class_name,"NSCalendarDate"))
- {
- Error error;
- date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
- date_value = *((double*)&date_value_bits);
- if (error.Fail())
- return false;
- }
- else
- {
- if (ExtractValueFromObjCExpression(valobj, "NSTimeInterval", "ExtractValueFromObjCExpression", date_value_bits) == false)
- return false;
- date_value = *((double*)&date_value_bits);
- }
- if (date_value == -63114076800)
- {
- stream.Printf("0001-12-30 00:00:00 +0000");
- return true;
- }
- // this snippet of code assumes that time_t == seconds since Jan-1-1970
- // this is generally true and POSIXly happy, but might break if a library
- // vendor decides to get creative
- time_t epoch = GetOSXEpoch();
- epoch = epoch + (time_t)date_value;
- tm *tm_date = localtime(&epoch);
- if (!tm_date)
- return false;
- std::string buffer(1024,0);
- if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
- return false;
- stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
- return true;
-}
-
-bool
-lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- time_t epoch = GetOSXEpoch();
- epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
- tm *tm_date = localtime(&epoch);
- if (!tm_date)
- return false;
- std::string buffer(1024,0);
- if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
- return false;
- stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
- return true;
-}
-
size_t
lldb_private::formatters::ExtractIndexFromString (const char* item_name)
{
Added: lldb/trunk/source/DataFormatters/Cocoa.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/Cocoa.cpp?rev=177454&view=auto
==============================================================================
--- lldb/trunk/source/DataFormatters/Cocoa.cpp (added)
+++ lldb/trunk/source/DataFormatters/Cocoa.cpp Tue Mar 19 17:58:48 2013
@@ -0,0 +1,565 @@
+//===-- Cocoa.cpp -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"NSBundle"))
+ {
+ uint64_t offset = 5 * ptr_size;
+ ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+ StreamString summary_stream;
+ bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
+ if (was_nsstring_ok && summary_stream.GetSize() > 0)
+ {
+ stream.Printf("%s",summary_stream.GetData());
+ return true;
+ }
+ }
+ // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
+ // which is encoded differently and needs to be handled by running code
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream);
+}
+
+bool
+lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"__NSTimeZone"))
+ {
+ uint64_t offset = ptr_size;
+ ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+ StreamString summary_stream;
+ bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
+ if (was_nsstring_ok && summary_stream.GetSize() > 0)
+ {
+ stream.Printf("%s",summary_stream.GetData());
+ return true;
+ }
+ }
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
+}
+
+bool
+lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"NSConcreteNotification"))
+ {
+ uint64_t offset = ptr_size;
+ ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+ StreamString summary_stream;
+ bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
+ if (was_nsstring_ok && summary_stream.GetSize() > 0)
+ {
+ stream.Printf("%s",summary_stream.GetData());
+ return true;
+ }
+ }
+ // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
+ // which is encoded differently and needs to be handled by running code
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
+}
+
+bool
+lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ uint64_t port_number = 0;
+
+ do
+ {
+ if (!strcmp(class_name,"NSMachPort"))
+ {
+ uint64_t offset = (ptr_size == 4 ? 12 : 20);
+ Error error;
+ port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
+ if (error.Success())
+ break;
+ }
+ if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number))
+ return false;
+ } while (false);
+
+ stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
+ return true;
+}
+
+bool
+lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ uint64_t count = 0;
+
+ do {
+ if (!strcmp(class_name,"NSIndexSet") || !strcmp(class_name,"NSMutableIndexSet"))
+ {
+ Error error;
+ uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 4, 0, error);
+ if (error.Fail())
+ return false;
+ // this means the set is empty - count = 0
+ if ((mode & 1) == 1)
+ {
+ count = 0;
+ break;
+ }
+ if ((mode & 2) == 2)
+ mode = 1; // this means the set only has one range
+ else
+ mode = 2; // this means the set has multiple ranges
+ if (mode == 1)
+ {
+ count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+3*ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ else
+ {
+ // read a pointer to the data at 2*ptr_size
+ count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ // read the data at 2*ptr_size from the first location
+ count = process_sp->ReadUnsignedIntegerFromMemory(count+2*ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ }
+ else
+ {
+ if (!ExtractValueFromObjCExpression(valobj, "unsigned long long int", "count", count))
+ return false;
+ }
+ } while (false);
+ stream.Printf("%llu index%s",
+ count,
+ (count == 1 ? "" : "es"));
+ return true;
+}
+
+bool
+lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
+ {
+ if (descriptor->IsTagged())
+ {
+ // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
+ int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
+ uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
+
+ switch (i_bits)
+ {
+ case 0:
+ stream.Printf("(char)%hhd",(char)value);
+ break;
+ case 4:
+ stream.Printf("(short)%hd",(short)value);
+ break;
+ case 8:
+ stream.Printf("(int)%d",(int)value);
+ break;
+ case 12:
+ stream.Printf("(long)%" PRId64,value);
+ break;
+ default:
+ stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
+ break;
+ }
+ return true;
+ }
+ else
+ {
+ Error error;
+ uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
+ uint64_t data_location = valobj_addr + 2*ptr_size;
+ uint64_t value = 0;
+ if (error.Fail())
+ return false;
+ switch (data_type)
+ {
+ case 1: // 0B00001
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(char)%hhd",(char)value);
+ break;
+ case 2: // 0B0010
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(short)%hd",(short)value);
+ break;
+ case 3: // 0B0011
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(int)%d",(int)value);
+ break;
+ case 17: // 0B10001
+ data_location += 8;
+ case 4: // 0B0100
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(long)%" PRId64,value);
+ break;
+ case 5: // 0B0101
+ {
+ uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
+ if (error.Fail())
+ return false;
+ float flt_value = *((float*)&flt_as_int);
+ stream.Printf("(float)%f",flt_value);
+ break;
+ }
+ case 6: // 0B0110
+ {
+ uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
+ if (error.Fail())
+ return false;
+ double dbl_value = *((double*)&dbl_as_lng);
+ stream.Printf("(double)%g",dbl_value);
+ break;
+ }
+ default:
+ stream.Printf("absurd: dt=%d",data_type);
+ break;
+ }
+ return true;
+ }
+ }
+ else
+ {
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "stringValue", stream);
+ }
+}
+
+bool
+lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (strcmp(class_name, "NSURL") == 0)
+ {
+ uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
+ uint64_t offset_base = offset_text + ptr_size;
+ ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
+ ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
+ if (!text)
+ return false;
+ if (text->GetValueAsUnsigned(0) == 0)
+ return false;
+ StreamString summary;
+ if (!NSStringSummaryProvider(*text, summary))
+ return false;
+ if (base && base->GetValueAsUnsigned(0))
+ {
+ if (summary.GetSize() > 0)
+ summary.GetString().resize(summary.GetSize()-1);
+ summary.Printf(" -- ");
+ StreamString base_summary;
+ if (NSURLSummaryProvider(*base, base_summary) && base_summary.GetSize() > 0)
+ summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
+ }
+ if (summary.GetSize())
+ {
+ stream.Printf("%s",summary.GetData());
+ return true;
+ }
+ }
+ else
+ {
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "description", stream);
+ }
+ return false;
+}
+
+bool
+lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t date_value_bits = 0;
+ double date_value = 0.0;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (strcmp(class_name,"NSDate") == 0 ||
+ strcmp(class_name,"__NSDate") == 0 ||
+ strcmp(class_name,"__NSTaggedDate") == 0)
+ {
+ if (descriptor->IsTagged())
+ {
+ uint64_t info_bits = (valobj_addr & 0xF0ULL) >> 4;
+ uint64_t value_bits = (valobj_addr & ~0x0000000000000000FFULL) >> 8;
+ date_value_bits = ((value_bits << 8) | (info_bits << 4));
+ date_value = *((double*)&date_value_bits);
+ }
+ else
+ {
+ Error error;
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 8, 0, error);
+ date_value = *((double*)&date_value_bits);
+ if (error.Fail())
+ return false;
+ }
+ }
+ else if (!strcmp(class_name,"NSCalendarDate"))
+ {
+ Error error;
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
+ date_value = *((double*)&date_value_bits);
+ if (error.Fail())
+ return false;
+ }
+ else
+ {
+ if (ExtractValueFromObjCExpression(valobj, "NSTimeInterval", "ExtractValueFromObjCExpression", date_value_bits) == false)
+ return false;
+ date_value = *((double*)&date_value_bits);
+ }
+ if (date_value == -63114076800)
+ {
+ stream.Printf("0001-12-30 00:00:00 +0000");
+ return true;
+ }
+ // this snippet of code assumes that time_t == seconds since Jan-1-1970
+ // this is generally true and POSIXly happy, but might break if a library
+ // vendor decides to get creative
+ time_t epoch = GetOSXEpoch();
+ epoch = epoch + (time_t)date_value;
+ tm *tm_date = localtime(&epoch);
+ if (!tm_date)
+ return false;
+ std::string buffer(1024,0);
+ if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
+ return false;
+ stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+ return true;
+}
Modified: lldb/trunk/source/DataFormatters/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/FormatManager.cpp?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/FormatManager.cpp (original)
+++ lldb/trunk/source/DataFormatters/FormatManager.cpp Tue Mar 19 17:58:48 2013
@@ -623,24 +623,16 @@ FormatManager::LoadLibcxxFormatters()
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdvector_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdlist_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdmap_SynthProvider")));
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__1::vector<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__1::list<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__1::map<.+> >(( )?&)?$"), stl_synth_flags, true);
+
libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)shared_ptr<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)weak_ptr<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
+
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
Modified: lldb/trunk/source/DataFormatters/LibCxx.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/LibCxx.cpp?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/LibCxx.cpp (original)
+++ lldb/trunk/source/DataFormatters/LibCxx.cpp Tue Mar 19 17:58:48 2013
@@ -136,7 +136,7 @@ lldb_private::formatters::LibcxxVectorBo
m_count = 0;
return false;
}
- return true;
+ return false;
}
bool
@@ -219,7 +219,7 @@ lldb_private::formatters::LibCxxMapItera
ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().DontAllowSyntheticChildren(),
NULL).get();
- return (m_pair_ptr != NULL);
+ return false;
}
size_t
@@ -285,3 +285,218 @@ lldb_private::formatters::LibCxxVectorIt
return NULL;
return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name));
}
+
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_cntrl(NULL),
+m_count_sp(),
+m_weak_count_sp(),
+m_ptr_size(0),
+m_byte_order(lldb::eByteOrderInvalid)
+{
+ if (valobj_sp)
+ Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren ()
+{
+ return (m_cntrl ? 1 : 0);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (!m_cntrl)
+ return lldb::ValueObjectSP();
+
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return lldb::ValueObjectSP();
+
+ if (idx == 0)
+ return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
+
+ if (idx > 2)
+ return lldb::ValueObjectSP();
+
+ if (idx == 1)
+ {
+ if (!m_count_sp)
+ {
+ ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_owners_"),true));
+ if (!shared_owners_sp)
+ return lldb::ValueObjectSP();
+ uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
+ DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
+ m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_owners_sp->GetClangAST(), shared_owners_sp->GetClangType()));
+ }
+ return m_count_sp;
+ }
+ else /* if (idx == 2) */
+ {
+ if (!m_weak_count_sp)
+ {
+ ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_weak_owners_"),true));
+ if (!shared_weak_owners_sp)
+ return lldb::ValueObjectSP();
+ uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
+ DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
+ m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_weak_owners_sp->GetClangAST(), shared_weak_owners_sp->GetClangType()));
+ }
+ return m_weak_count_sp;
+ }
+}
+
+bool
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update()
+{
+ m_count_sp.reset();
+ m_weak_count_sp.reset();
+ m_cntrl = NULL;
+
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ TargetSP target_sp(valobj_sp->GetTargetSP());
+ if (!target_sp)
+ return false;
+
+ m_byte_order = target_sp->GetArchitecture().GetByteOrder();
+ m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
+
+ lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"),true));
+
+ m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular dependency
+ return false;
+}
+
+bool
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (name == ConstString("__ptr_"))
+ return 0;
+ if (name == ConstString("count"))
+ return 1;
+ if (name == ConstString("weak_count"))
+ return 2;
+ return UINT32_MAX;
+}
+
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp));
+}
+
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_start(NULL),
+m_finish(NULL),
+m_element_type(),
+m_element_size(0),
+m_children()
+{
+ if (valobj_sp)
+ Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (!m_start || !m_finish)
+ return 0;
+ uint64_t start_val = m_start->GetValueAsUnsigned(0);
+ uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
+
+ if (start_val == 0 || finish_val == 0)
+ return 0;
+
+ if (start_val >= finish_val)
+ return 0;
+
+ size_t num_children = (finish_val - start_val);
+ if (num_children % m_element_size)
+ return 0;
+ return num_children/m_element_size;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (!m_start || !m_finish)
+ return lldb::ValueObjectSP();
+
+ auto cached = m_children.find(idx);
+ if (cached != m_children.end())
+ return cached->second;
+
+ uint64_t offset = idx * m_element_size;
+ offset = offset + m_start->GetValueAsUnsigned(0);
+ StreamString name;
+ name.Printf("[%zu]",idx);
+ ValueObjectSP child_sp = ValueObject::CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
+ m_children[idx] = child_sp;
+ return child_sp;
+}
+
+bool
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
+{
+ m_start = m_finish = NULL;
+ m_children.clear();
+ ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
+ if (!data_type_finder_sp)
+ return false;
+ data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
+ if (!data_type_finder_sp)
+ return false;
+ m_element_type = ClangASTType(data_type_finder_sp->GetClangAST(),data_type_finder_sp->GetClangType());
+ m_element_type.SetClangType(m_element_type.GetASTContext(), m_element_type.GetPointeeType());
+ m_element_size = m_element_type.GetTypeByteSize();
+ // store raw pointers or end up with a circular dependency
+ m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get();
+ m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get();
+ return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (!m_start || !m_finish)
+ return UINT32_MAX;
+ return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd ()
+{
+ // these need to stay around because they are child objects who will follow their parent's life cycle
+ // delete m_start;
+ // delete m_finish;
+}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));
+}
Added: lldb/trunk/source/DataFormatters/LibCxxList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/LibCxxList.cpp?rev=177454&view=auto
==============================================================================
--- lldb/trunk/source/DataFormatters/LibCxxList.cpp (added)
+++ lldb/trunk/source/DataFormatters/LibCxxList.cpp Tue Mar 19 17:58:48 2013
@@ -0,0 +1,288 @@
+//===-- LibCxxList.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+class ListEntry
+{
+public:
+ ListEntry () {}
+ ListEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
+ ListEntry (const ListEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
+ ListEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
+
+ ValueObjectSP
+ next ()
+ {
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetChildMemberWithName(ConstString("__next_"), true);
+ }
+
+ ValueObjectSP
+ prev ()
+ {
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetChildMemberWithName(ConstString("__prev_"), true);
+ }
+
+ uint64_t
+ value ()
+ {
+ if (!m_entry_sp)
+ return 0;
+ return m_entry_sp->GetValueAsUnsigned(0);
+ }
+
+ bool
+ null()
+ {
+ return (value() == 0);
+ }
+
+ ValueObjectSP
+ GetEntry ()
+ {
+ return m_entry_sp;
+ }
+
+ void
+ SetEntry (ValueObjectSP entry)
+ {
+ m_entry_sp = entry;
+ }
+
+ bool
+ operator == (const ListEntry& rhs) const
+ {
+ return (rhs.m_entry_sp.get() == m_entry_sp.get());
+ }
+
+private:
+ ValueObjectSP m_entry_sp;
+};
+
+class ListIterator
+{
+public:
+ ListIterator () {}
+ ListIterator (ListEntry entry) : m_entry(entry) {}
+ ListIterator (ValueObjectSP entry) : m_entry(entry) {}
+ ListIterator (const ListIterator& rhs) : m_entry(rhs.m_entry) {}
+ ListIterator (ValueObject* entry) : m_entry(entry) {}
+
+ ValueObjectSP
+ value ()
+ {
+ return m_entry.GetEntry();
+ }
+
+ ValueObjectSP
+ advance (size_t count)
+ {
+ if (count == 0)
+ return m_entry.GetEntry();
+ if (count == 1)
+ {
+ next ();
+ return m_entry.GetEntry();
+ }
+ while (count > 0)
+ {
+ next ();
+ count--;
+ if (m_entry.null())
+ return lldb::ValueObjectSP();
+ }
+ return m_entry.GetEntry();
+ }
+
+ bool
+ operator == (const ListIterator& rhs) const
+ {
+ return (rhs.m_entry == m_entry);
+ }
+
+protected:
+ void
+ next ()
+ {
+ m_entry.SetEntry(m_entry.next());
+ }
+
+ void
+ prev ()
+ {
+ m_entry.SetEntry(m_entry.prev());
+ }
+private:
+ ListEntry m_entry;
+};
+
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_node_address(),
+m_head(NULL),
+m_tail(NULL),
+m_element_type(),
+m_element_size(0),
+m_count(UINT32_MAX),
+m_children()
+{
+ if (valobj_sp)
+ Update();
+}
+
+bool
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop()
+{
+ if (g_use_loop_detect == false)
+ return false;
+ ListEntry slow(m_head);
+ ListEntry fast1(m_head);
+ ListEntry fast2(m_head);
+ while (slow.next() && slow.next()->GetValueAsUnsigned(0) != m_node_address)
+ {
+ auto slow_value = slow.value();
+ fast1.SetEntry(fast2.next());
+ fast2.SetEntry(fast1.next());
+ if (fast1.value() == slow_value || fast2.value() == slow_value)
+ return true;
+ slow.SetEntry(slow.next());
+ }
+ return false;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (m_count != UINT32_MAX)
+ return m_count;
+ if (!m_head || !m_tail || m_node_address == 0)
+ return 0;
+ uint64_t next_val = m_head->GetValueAsUnsigned(0);
+ uint64_t prev_val = m_tail->GetValueAsUnsigned(0);
+ if (next_val == 0 || prev_val == 0)
+ return 0;
+ if (next_val == m_node_address)
+ return 0;
+ if (next_val == prev_val)
+ return 1;
+ if (HasLoop())
+ return 0;
+ uint64_t size = 2;
+ ListEntry current(m_head);
+ while (current.next() && current.next()->GetValueAsUnsigned(0) != m_node_address)
+ {
+ size++;
+ current.SetEntry(current.next());
+ if (size > g_list_capping_size)
+ break;
+ }
+ return m_count = (size-1);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+
+ if (!m_head || !m_tail || m_node_address == 0)
+ return lldb::ValueObjectSP();
+
+ auto cached = m_children.find(idx);
+ if (cached != m_children.end())
+ return cached->second;
+
+ ListIterator current(m_head);
+ ValueObjectSP current_sp(current.advance(idx));
+ if (!current_sp)
+ return lldb::ValueObjectSP();
+ current_sp = current_sp->GetChildMemberWithName(ConstString("__value_"), true);
+ if (!current_sp)
+ return lldb::ValueObjectSP();
+ // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
+ DataExtractor data;
+ current_sp->GetData(data);
+ StreamString name;
+ name.Printf("[%zu]",idx);
+ return (m_children[idx] = ValueObject::CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type));
+}
+
+bool
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update()
+{
+ m_head = m_tail = NULL;
+ m_node_address = 0;
+ m_count = UINT32_MAX;
+ Error err;
+ ValueObjectSP backend_addr(m_backend.AddressOf(err));
+ if (err.Fail() || backend_addr.get() == NULL)
+ return false;
+ m_node_address = backend_addr->GetValueAsUnsigned(0);
+ if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
+ return false;
+ ValueObjectSP impl_sp(m_backend.GetChildMemberWithName(ConstString("__end_"),true));
+ if (!impl_sp)
+ return false;
+ auto list_type = m_backend.GetClangType();
+ if (ClangASTContext::IsReferenceType(list_type))
+ {
+ clang::QualType qt = clang::QualType::getFromOpaquePtr(list_type);
+ list_type = qt.getNonReferenceType().getAsOpaquePtr();
+ }
+ if (ClangASTContext::GetNumTemplateArguments(m_backend.GetClangAST(), list_type) == 0)
+ return false;
+ lldb::TemplateArgumentKind kind;
+ m_element_type = ClangASTType(m_backend.GetClangAST(), ClangASTContext::GetTemplateArgument(m_backend.GetClangAST(), list_type, 0, kind));
+ m_element_size = m_element_type.GetTypeByteSize();
+ m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
+ m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
+ return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::~LibcxxStdListSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibcxxStdListSyntheticFrontEnd(valobj_sp));
+}
+
Added: lldb/trunk/source/DataFormatters/LibCxxMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/LibCxxMap.cpp?rev=177454&view=auto
==============================================================================
--- lldb/trunk/source/DataFormatters/LibCxxMap.cpp (added)
+++ lldb/trunk/source/DataFormatters/LibCxxMap.cpp Tue Mar 19 17:58:48 2013
@@ -0,0 +1,384 @@
+//===-- LibCxxList.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+class MapEntry
+{
+public:
+ MapEntry () {}
+ MapEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
+ MapEntry (const MapEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
+ MapEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
+
+ ValueObjectSP
+ left ()
+ {
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetChildMemberWithName(ConstString("__left_"), true);
+ }
+
+ ValueObjectSP
+ right ()
+ {
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetChildMemberWithName(ConstString("__right_"), true);
+ }
+
+ ValueObjectSP
+ parent ()
+ {
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetChildMemberWithName(ConstString("__parent_"), true);
+ }
+
+ uint64_t
+ value ()
+ {
+ if (!m_entry_sp)
+ return 0;
+ return m_entry_sp->GetValueAsUnsigned(0);
+ }
+
+ bool
+ null()
+ {
+ return (value() == 0);
+ }
+
+ ValueObjectSP
+ GetEntry ()
+ {
+ return m_entry_sp;
+ }
+
+ void
+ SetEntry (ValueObjectSP entry)
+ {
+ m_entry_sp = entry;
+ }
+
+ bool
+ operator == (const MapEntry& rhs) const
+ {
+ return (rhs.m_entry_sp.get() == m_entry_sp.get());
+ }
+
+private:
+ ValueObjectSP m_entry_sp;
+};
+
+class MapIterator
+{
+public:
+ MapIterator () {}
+ MapIterator (MapEntry entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth) {}
+ MapIterator (ValueObjectSP entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth) {}
+ MapIterator (const MapIterator& rhs) : m_entry(rhs.m_entry),m_max_depth(rhs.m_max_depth) {}
+ MapIterator (ValueObject* entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth) {}
+
+ ValueObjectSP
+ value ()
+ {
+ return m_entry.GetEntry();
+ }
+
+ ValueObjectSP
+ advance (size_t count)
+ {
+ if (count == 0)
+ return m_entry.GetEntry();
+ if (count == 1)
+ {
+ next ();
+ return m_entry.GetEntry();
+ }
+ size_t steps = 0;
+ while (count > 0)
+ {
+ next ();
+ count--;
+ if (m_entry.null())
+ return lldb::ValueObjectSP();
+ steps++;
+ if (steps > m_max_depth)
+ return lldb::ValueObjectSP();
+ }
+ return m_entry.GetEntry();
+ }
+protected:
+ void
+ next ()
+ {
+ m_entry.SetEntry(increment(m_entry.GetEntry()));
+ }
+
+private:
+ ValueObjectSP
+ tree_min (ValueObjectSP x_sp)
+ {
+ MapEntry x(x_sp);
+ if (x.null())
+ return ValueObjectSP();
+ MapEntry left(x.left());
+ size_t steps = 0;
+ while (left.null() == false)
+ {
+ x.SetEntry(left.GetEntry());
+ left.SetEntry(x.left());
+ steps++;
+ if (steps > m_max_depth)
+ return lldb::ValueObjectSP();
+ }
+ return x.GetEntry();
+ }
+
+ ValueObjectSP
+ tree_max (ValueObjectSP x_sp)
+ {
+ MapEntry x(x_sp);
+ if (x.null())
+ return ValueObjectSP();
+ MapEntry right(x.right());
+ size_t steps = 0;
+ while (right.null() == false)
+ {
+ x.SetEntry(right.GetEntry());
+ right.SetEntry(x.right());
+ steps++;
+ if (steps > m_max_depth)
+ return lldb::ValueObjectSP();
+ }
+ return x.GetEntry();
+ }
+
+ bool
+ is_left_child (ValueObjectSP x_sp)
+ {
+ MapEntry x(x_sp);
+ if (x.null())
+ return false;
+ MapEntry rhs(x.parent());
+ rhs.SetEntry(rhs.left());
+ return x.value() == rhs.value();
+ }
+
+ ValueObjectSP
+ increment (ValueObjectSP x_sp)
+ {
+ MapEntry node(x_sp);
+ if (node.null())
+ return ValueObjectSP();
+ MapEntry right(node.right());
+ if (right.null() == false)
+ return tree_min(right.GetEntry());
+ size_t steps = 0;
+ while (!is_left_child(node.GetEntry()))
+ {
+ node.SetEntry(node.parent());
+ steps++;
+ if (steps > m_max_depth)
+ return lldb::ValueObjectSP();
+ }
+ return node.parent();
+ }
+
+ MapEntry m_entry;
+ size_t m_max_depth;
+};
+
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_tree(NULL),
+m_root_node(NULL),
+m_element_type(),
+m_element_size(0),
+m_skip_size(UINT32_MAX),
+m_count(UINT32_MAX),
+m_children()
+{
+ if (valobj_sp)
+ Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (m_count != UINT32_MAX)
+ return m_count;
+ if (m_tree == NULL)
+ return 0;
+ ValueObjectSP m_item(m_tree->GetChildMemberWithName(ConstString("__pair3_"), true));
+ if (!m_item)
+ return 0;
+ m_item = m_item->GetChildMemberWithName(ConstString("__first_"), true);
+ if (!m_item)
+ return 0;
+ m_count = m_item->GetValueAsUnsigned(0);
+ return m_count;
+}
+
+bool
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType()
+{
+ if (m_element_type.GetOpaqueQualType() && m_element_type.GetASTContext())
+ return true;
+ m_element_type.Clear();
+ ValueObjectSP deref;
+ Error error;
+ deref = m_root_node->Dereference(error);
+ if (!deref || error.Fail())
+ return false;
+ deref = deref->GetChildMemberWithName(ConstString("__value_"), true);
+ if (!deref)
+ return false;
+ m_element_type.SetClangType(deref->GetClangAST(), deref->GetClangType());
+ m_element_size = m_element_type.GetTypeByteSize();
+ return true;
+}
+
+void
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const lldb::ValueObjectSP& node)
+{
+ if (m_skip_size != UINT32_MAX)
+ return;
+ if (!node)
+ return;
+ ClangASTType node_type(node->GetClangAST(),node->GetClangType());
+ uint64_t bit_offset;
+ if (ClangASTContext::GetIndexOfFieldWithName(node->GetClangAST(),node->GetClangType(),"__value_",NULL,&bit_offset) == UINT32_MAX)
+ return;
+ m_skip_size = bit_offset / 8u;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ if (m_tree == NULL || m_root_node == NULL)
+ return lldb::ValueObjectSP();
+
+ auto cached = m_children.find(idx);
+ if (cached != m_children.end())
+ return cached->second;
+
+ bool need_to_skip = (idx > 0);
+ MapIterator iterator(m_root_node, CalculateNumChildren());
+ ValueObjectSP iterated_sp(iterator.advance(idx));
+ if (iterated_sp.get() == NULL)
+ {
+ // this tree is garbage - stop
+ m_tree = NULL; // this will stop all future searches until an Update() happens
+ return iterated_sp;
+ }
+ if (GetDataType())
+ {
+ if (!need_to_skip)
+ {
+ Error error;
+ iterated_sp = iterated_sp->Dereference(error);
+ if (!iterated_sp || error.Fail())
+ {
+ m_tree = NULL;
+ return lldb::ValueObjectSP();
+ }
+ GetValueOffset(iterated_sp);
+ iterated_sp = iterated_sp->GetChildMemberWithName(ConstString("__value_"), true);
+ if (!iterated_sp)
+ {
+ m_tree = NULL;
+ return lldb::ValueObjectSP();
+ }
+ }
+ else
+ {
+ // because of the way our debug info is made, we need to read item 0 first
+ // so that we can cache information used to generate other elements
+ if (m_skip_size == UINT32_MAX)
+ GetChildAtIndex(0);
+ if (m_skip_size == UINT32_MAX)
+ {
+ m_tree = NULL;
+ return lldb::ValueObjectSP();
+ }
+ iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, m_element_type, true);
+ if (!iterated_sp)
+ {
+ m_tree = NULL;
+ return lldb::ValueObjectSP();
+ }
+ }
+ }
+ else
+ {
+ m_tree = NULL;
+ return lldb::ValueObjectSP();
+ }
+ // at this point we have a valid
+ // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
+ DataExtractor data;
+ iterated_sp->GetData(data);
+ StreamString name;
+ name.Printf("[%zu]",idx);
+ return (m_children[idx] = ValueObject::CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type));
+}
+
+bool
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update()
+{
+ m_count = UINT32_MAX;
+ m_tree = m_root_node = NULL;
+ m_children.clear();
+ m_tree = m_backend.GetChildMemberWithName(ConstString("__tree_"), true).get();
+ if (!m_tree)
+ return NULL;
+ m_root_node = m_tree->GetChildMemberWithName(ConstString("__begin_node_"), true).get();
+ return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::~LibcxxStdMapSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibcxxStdMapSyntheticFrontEnd(valobj_sp));
+}
Modified: lldb/trunk/source/DataFormatters/TypeSynthetic.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/TypeSynthetic.cpp?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/TypeSynthetic.cpp (original)
+++ lldb/trunk/source/DataFormatters/TypeSynthetic.cpp Tue Mar 19 17:58:48 2013
@@ -53,7 +53,7 @@ std::string
CXXSyntheticChildren::GetDescription()
{
StreamString sstr;
- sstr.Printf("%s%s%s Generator at %p - %s\n",
+ sstr.Printf("%s%s%s Generator at %p - %s",
Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=177454&r1=177453&r2=177454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Mar 19 17:58:48 2013
@@ -3673,6 +3673,31 @@ ClangASTContext::GetFieldAtIndex (clang:
return NULL;
}
+size_t
+ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast,
+ lldb::clang_type_t clang_type,
+ const char* name,
+ lldb::clang_type_t* field_clang_type,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr)
+{
+ auto count = ClangASTContext::GetNumFields(ast, clang_type);
+ lldb::clang_type_t field_clang_type_internal;
+ std::string field_name;
+ for (auto index = 0; index < count; index++)
+ {
+ field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
+ if ( strcmp(field_name.c_str(), name) == 0 )
+ {
+ if (field_clang_type)
+ *field_clang_type = field_clang_type_internal;
+ return index;
+ }
+ }
+ return UINT32_MAX;
+}
+
lldb::BasicType
ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type)
{
More information about the lldb-commits
mailing list