diff options
10 files changed, 384 insertions, 1 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 810bed78d40..eedce3d28d9 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -864,7 +864,7 @@ public: lldb::Format GetFormat () const; - void + virtual void SetFormat (lldb::Format format) { if (format != m_format) diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index aa784add740..f37096a0849 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -143,6 +143,14 @@ public: virtual bool SetValueFromCString (const char *value_str, Error& error); + virtual void + SetFormat (lldb::Format format) + { + if (m_parent) + m_parent->SetFormat(format); + this->ValueObject::SetFormat(format); + } + protected: virtual bool UpdateValue (); diff --git a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h index 81856aae1d4..f869b1f00e9 100644 --- a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -398,6 +398,7 @@ namespace lldb_private { SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); + SyntheticChildrenFrontEnd* VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); } // namespace formatters } // namespace lldb_private diff --git a/lldb/include/lldb/DataFormatters/VectorType.h b/lldb/include/lldb/DataFormatters/VectorType.h new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/lldb/include/lldb/DataFormatters/VectorType.h diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index aeb676d7c7a..8cf2bc46586 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -758,6 +758,7 @@ 940B04E11A89860E0045D5F7 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 940B04E01A89860E0045D5F7 /* libedit.dylib */; }; 940B04E41A8987680045D5F7 /* argdumper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 942829C01A89835300521B30 /* argdumper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 94145431175E63B500284436 /* lldb-versioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 94145430175D7FDE00284436 /* lldb-versioning.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9418EBCD1AA910910058B02E /* VectorType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9418EBCC1AA910910058B02E /* VectorType.cpp */; }; 941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 941BCC8014E48C4000BB969C /* SBTypeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568714E355F2003A195C /* SBTypeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568814E355F2003A195C /* SBTypeSummary.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2387,6 +2388,8 @@ 940B04DE1A8986070045D5F7 /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libncurses.dylib; sourceTree = DEVELOPER_DIR; }; 940B04E01A89860E0045D5F7 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libedit.dylib; sourceTree = DEVELOPER_DIR; }; 94145430175D7FDE00284436 /* lldb-versioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-versioning.h"; path = "include/lldb/lldb-versioning.h"; sourceTree = "<group>"; }; + 9418EBCB1AA9108B0058B02E /* VectorType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VectorType.h; path = include/lldb/DataFormatters/VectorType.h; sourceTree = "<group>"; }; + 9418EBCC1AA910910058B02E /* VectorType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VectorType.cpp; path = source/DataFormatters/VectorType.cpp; sourceTree = "<group>"; }; 94235B9A1A8D5FD800EB2EED /* SBVariablesOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBVariablesOptions.h; path = include/lldb/API/SBVariablesOptions.h; sourceTree = "<group>"; }; 94235B9B1A8D5FF300EB2EED /* SBVariablesOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBVariablesOptions.cpp; path = source/API/SBVariablesOptions.cpp; sourceTree = "<group>"; }; 94235B9D1A8D601A00EB2EED /* SBVariablesOptions.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBVariablesOptions.i; sourceTree = "<group>"; }; @@ -5037,6 +5040,8 @@ 94CD131919BA33B400DB7BED /* TypeValidator.cpp */, 945215DD17F639E600521C0B /* ValueObjectPrinter.h */, 945215DE17F639EE00521C0B /* ValueObjectPrinter.cpp */, + 9418EBCB1AA9108B0058B02E /* VectorType.h */, + 9418EBCC1AA910910058B02E /* VectorType.cpp */, ); name = DataFormatters; sourceTree = "<group>"; @@ -5977,6 +5982,7 @@ 94BA8B70176F97CE005A91B5 /* CommandHistory.cpp in Sources */, 2689007713353E1A00698AC0 /* CFCData.cpp in Sources */, 2689007813353E1A00698AC0 /* CFCMutableArray.cpp in Sources */, + 9418EBCD1AA910910058B02E /* VectorType.cpp in Sources */, 2689007913353E1A00698AC0 /* CFCMutableDictionary.cpp in Sources */, 2689007A13353E1A00698AC0 /* CFCMutableSet.cpp in Sources */, 2689007B13353E1A00698AC0 /* CFCString.cpp in Sources */, diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index bdd26219c38..c94ad345f8b 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -1216,6 +1216,15 @@ FormatManager::LoadSystemFormatters() AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags); + SyntheticChildren::Flags synth_flags; + synth_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true); + + AddCXXSynthetic(sys_category_sp, + lldb_private::formatters::VectorTypeSyntheticFrontEndCreator, + "vector_type synthetic children", + ConstString("unsigned char __attribute__\\(\\(ext_vector_type\\([0-9]+\\)\\)\\)"), + synth_flags, + true); #endif } diff --git a/lldb/source/DataFormatters/VectorType.cpp b/lldb/source/DataFormatters/VectorType.cpp new file mode 100644 index 00000000000..b35e9c03333 --- /dev/null +++ b/lldb/source/DataFormatters/VectorType.cpp @@ -0,0 +1,259 @@ +//===-- VectorType.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/ValueObject.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTType.h" + +#include "lldb/Utility/LLDBAssert.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +static ClangASTType +GetClangTypeForFormat (lldb::Format format, + ClangASTContext *ast_ctx) +{ + lldbassert(ast_ctx && "ast_ctx needs to be not NULL"); + + switch (format) + { + case lldb::eFormatAddressInfo: + case lldb::eFormatPointer: + return ast_ctx->GetPointerSizedIntType(false); + + case lldb::eFormatBoolean: + return ast_ctx->GetBasicType(lldb::eBasicTypeBool); + + case lldb::eFormatBytes: + case lldb::eFormatBytesWithASCII: + case lldb::eFormatChar: + case lldb::eFormatCharArray: + case lldb::eFormatCharPrintable: + return ast_ctx->GetBasicType(lldb::eBasicTypeChar); + + case lldb::eFormatComplex /* lldb::eFormatComplexFloat */: + return ast_ctx->GetBasicType(lldb::eBasicTypeFloatComplex); + + case lldb::eFormatCString: + return ast_ctx->GetBasicType(lldb::eBasicTypeChar).GetPointerType(); + + case lldb::eFormatFloat: + return ast_ctx->GetBasicType(lldb::eBasicTypeFloat); + + case lldb::eFormatHex: + case lldb::eFormatHexUppercase: + case lldb::eFormatOctal: + return ast_ctx->GetBasicType(lldb::eBasicTypeInt); + + case lldb::eFormatHexFloat: + return ast_ctx->GetBasicType(lldb::eBasicTypeFloat); + + case lldb::eFormatUnicode16: + case lldb::eFormatUnicode32: + + case lldb::eFormatUnsigned: + return ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedInt); + + case lldb::eFormatVectorOfChar: + return ast_ctx->GetBasicType(lldb::eBasicTypeChar); + + case lldb::eFormatVectorOfFloat32: + return ast_ctx->GetFloatTypeFromBitSize(32); + + case lldb::eFormatVectorOfFloat64: + return ast_ctx->GetFloatTypeFromBitSize(64); + + case lldb::eFormatVectorOfSInt16: + return ast_ctx->GetIntTypeFromBitSize(16, true); + + case lldb::eFormatVectorOfSInt32: + return ast_ctx->GetIntTypeFromBitSize(32, true); + + case lldb::eFormatVectorOfSInt64: + return ast_ctx->GetIntTypeFromBitSize(64, true); + + case lldb::eFormatVectorOfSInt8: + return ast_ctx->GetIntTypeFromBitSize(8, true); + + case lldb::eFormatVectorOfUInt128: + return ast_ctx->GetIntTypeFromBitSize(128, false); + + case lldb::eFormatVectorOfUInt16: + return ast_ctx->GetIntTypeFromBitSize(16, false); + + case lldb::eFormatVectorOfUInt32: + return ast_ctx->GetIntTypeFromBitSize(32, false); + + case lldb::eFormatVectorOfUInt64: + return ast_ctx->GetIntTypeFromBitSize(64, false); + + case lldb::eFormatVectorOfUInt8: + return ast_ctx->GetIntTypeFromBitSize(8, false); + + case lldb::eFormatBinary: + case lldb::eFormatComplexInteger: + case lldb::eFormatDecimal: + case lldb::eFormatDefault: + case lldb::eFormatEnum: + case lldb::eFormatInstruction: + case lldb::eFormatOSType: + case lldb::eFormatVoid: + default: + return ast_ctx->GetIntTypeFromBitSize(8, false); + } +} + +static lldb::Format +GetItemFormatForFormat (lldb::Format format) +{ + switch (format) + { + case lldb::eFormatVectorOfChar: + return lldb::eFormatChar; + + case lldb::eFormatVectorOfFloat32: + case lldb::eFormatVectorOfFloat64: + return lldb::eFormatFloat; + + case lldb::eFormatVectorOfSInt16: + case lldb::eFormatVectorOfSInt32: + case lldb::eFormatVectorOfSInt64: + case lldb::eFormatVectorOfSInt8: + return lldb::eFormatDecimal; + + case lldb::eFormatVectorOfUInt128: + case lldb::eFormatVectorOfUInt16: + case lldb::eFormatVectorOfUInt32: + case lldb::eFormatVectorOfUInt64: + case lldb::eFormatVectorOfUInt8: + return lldb::eFormatUnsigned; + + case lldb::eFormatBinary: + case lldb::eFormatComplexInteger: + case lldb::eFormatDecimal: + case lldb::eFormatDefault: + case lldb::eFormatEnum: + case lldb::eFormatInstruction: + case lldb::eFormatOSType: + case lldb::eFormatVoid: + return eFormatHex; + + default: + return format; + } +} + +static size_t +CalculateNumChildren (ClangASTType container_type, + ClangASTType element_type, + lldb_private::ExecutionContextScope *exe_scope = nullptr // does not matter here because all we trade in are basic types + ) +{ + auto container_size = container_type.GetByteSize(exe_scope); + auto element_size = element_type.GetByteSize(exe_scope); + + if (element_size) + { + if (container_size % element_size) + return 0; + return container_size / element_size; + } + return 0; +} + +namespace lldb_private { + namespace formatters { + + class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd + { + public: + VectorTypeSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : + SyntheticChildrenFrontEnd(*valobj_sp), + m_parent_format (eFormatInvalid), + m_item_format(eFormatInvalid), + m_child_type(), + m_num_children(0) + {} + + virtual size_t + CalculateNumChildren () + { + return m_num_children; + } + + virtual lldb::ValueObjectSP + GetChildAtIndex (size_t idx) + { + if (idx >= CalculateNumChildren()) + return lldb::ValueObjectSP(); + auto offset = idx * m_child_type.GetByteSize(nullptr); + ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(offset, m_child_type, true)); + if (!child_sp) + return child_sp; + + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + child_sp->SetName( ConstString( idx_name.GetData() ) ); + + child_sp->SetFormat(m_item_format); + + return child_sp; + } + + virtual bool + Update() + { + m_parent_format = m_backend.GetFormat(); + ClangASTType parent_type(m_backend.GetClangType()); + m_child_type = ::GetClangTypeForFormat(m_parent_format, ClangASTContext::GetASTContext(parent_type.GetASTContext())); + m_num_children = ::CalculateNumChildren(parent_type, + m_child_type); + m_item_format = GetItemFormatForFormat(m_parent_format); + return false; + } + + virtual bool + MightHaveChildren () + { + return true; + } + + virtual size_t + GetIndexOfChildWithName (const ConstString &name) + { + const char* item_name = name.GetCString(); + uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; + } + + virtual + ~VectorTypeSyntheticFrontEnd () {} + + private: + lldb::Format m_parent_format; + lldb::Format m_item_format; + ClangASTType m_child_type; + size_t m_num_children; + }; + } +} + +lldb_private::SyntheticChildrenFrontEnd* +lldb_private::formatters::VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) +{ + if (!valobj_sp) + return NULL; + return (new VectorTypeSyntheticFrontEnd(valobj_sp)); +} diff --git a/lldb/test/functionalities/data-formatter/vector-types/Makefile b/lldb/test/functionalities/data-formatter/vector-types/Makefile new file mode 100644 index 00000000000..314f1cb2f07 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/vector-types/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py b/lldb/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py new file mode 100644 index 00000000000..6a335a9129a --- /dev/null +++ b/lldb/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py @@ -0,0 +1,78 @@ +""" +Check that vector types format properly +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * +import lldbutil + +class VectorTypesFormattingTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # rdar://problem/14035604 + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dsym_test + def test_with_dsym_and_run_command(self): + """Check that vector types format properly""" + self.buildDsym() + self.propagate_test_commands() + + # rdar://problem/14035604 + @dwarf_test + def test_with_dwarf_and_run_command(self): + """Check that vector types format properly""" + self.buildDwarf() + self.propagate_test_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.line = line_number('main.cpp', '// break here') + + def propagate_test_commands(self): + """Check that vector types format properly""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + pass + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + pass # my code never fails + + v = self.frame().FindVariable("v") + v.SetPreferSyntheticValue(True) + v.SetFormat(lldb.eFormatVectorOfFloat32) + + if self.TraceOn(): print v + + self.assertTrue(v.GetNumChildren() == 4, "v as float32[] has 4 children") + self.assertTrue(v.GetChildAtIndex(0).GetData().float[0] == 1.25, "child 0 == 1.25") + self.assertTrue(v.GetChildAtIndex(1).GetData().float[0] == 1.25, "child 1 == 1.25") + self.assertTrue(v.GetChildAtIndex(2).GetData().float[0] == 2.50, "child 2 == 2.50") + self.assertTrue(v.GetChildAtIndex(3).GetData().float[0] == 2.50, "child 3 == 2.50") + + self.expect("expr -f int16_t[] -- v", substrs=['[0] = 0', '[1] = 16288', '[2] = 0', '[3] = 16288', '[4] = 0', '[5] = 16416', '[6] = 0', '[7] = 16416']) + self.expect("expr -f uint128_t[] -- v", substrs=['[0] = 85236745249553456609335044694184296448']) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/data-formatter/vector-types/main.cpp b/lldb/test/functionalities/data-formatter/vector-types/main.cpp new file mode 100644 index 00000000000..b9d67ad20ab --- /dev/null +++ b/lldb/test/functionalities/data-formatter/vector-types/main.cpp @@ -0,0 +1,17 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +typedef float float4 __attribute__((ext_vector_type(4))); +typedef unsigned char vec __attribute__((ext_vector_type(16))); + +int main() { + float4 f4 = {1.25, 1.25, 2.50, 2.50}; + vec v = (vec)f4; + return 0; // break here +} |

