summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ValueObject.h2
-rw-r--r--lldb/include/lldb/Core/ValueObjectSyntheticFilter.h8
-rw-r--r--lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h1
-rw-r--r--lldb/include/lldb/DataFormatters/VectorType.h0
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj6
-rw-r--r--lldb/source/DataFormatters/FormatManager.cpp9
-rw-r--r--lldb/source/DataFormatters/VectorType.cpp259
-rw-r--r--lldb/test/functionalities/data-formatter/vector-types/Makefile5
-rw-r--r--lldb/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py78
-rw-r--r--lldb/test/functionalities/data-formatter/vector-types/main.cpp17
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
+}
OpenPOWER on IntegriCloud