Skip to content

Commit 0ddbf36

Browse files
author
Enrico Granata
committedMar 6, 2015
Provide synthetic children for some vector types
Unlike GDB, we tackle the problem of representing vector types in different styles by having a synthetic child provider that recognizes the format you're trying to apply to the variable, and coming up with the right type and number of child values to match that format This makes for a more compact representation and less visual noise Fixes rdar://5429347 llvm-svn: 231449
1 parent d07b2b4 commit 0ddbf36

File tree

10 files changed

+384
-1
lines changed

10 files changed

+384
-1
lines changed
 

‎lldb/include/lldb/Core/ValueObject.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ class ValueObject : public UserID
864864
lldb::Format
865865
GetFormat () const;
866866

867-
void
867+
virtual void
868868
SetFormat (lldb::Format format)
869869
{
870870
if (format != m_format)

‎lldb/include/lldb/Core/ValueObjectSyntheticFilter.h

+8
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ class ValueObjectSynthetic : public ValueObject
143143
virtual bool
144144
SetValueFromCString (const char *value_str, Error& error);
145145

146+
virtual void
147+
SetFormat (lldb::Format format)
148+
{
149+
if (m_parent)
150+
m_parent->SetFormat(format);
151+
this->ValueObject::SetFormat(format);
152+
}
153+
146154
protected:
147155
virtual bool
148156
UpdateValue ();

‎lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h

+1
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ namespace lldb_private {
398398

399399
SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
400400

401+
SyntheticChildrenFrontEnd* VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
401402
} // namespace formatters
402403
} // namespace lldb_private
403404

‎lldb/include/lldb/DataFormatters/VectorType.h

Whitespace-only changes.

‎lldb/lldb.xcodeproj/project.pbxproj

+6
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@
758758
940B04E11A89860E0045D5F7 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 940B04E01A89860E0045D5F7 /* libedit.dylib */; };
759759
940B04E41A8987680045D5F7 /* argdumper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 942829C01A89835300521B30 /* argdumper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
760760
94145431175E63B500284436 /* lldb-versioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 94145430175D7FDE00284436 /* lldb-versioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
761+
9418EBCD1AA910910058B02E /* VectorType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9418EBCC1AA910910058B02E /* VectorType.cpp */; };
761762
941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
762763
941BCC8014E48C4000BB969C /* SBTypeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568714E355F2003A195C /* SBTypeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
763764
941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568814E355F2003A195C /* SBTypeSummary.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -2387,6 +2388,8 @@
23872388
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; };
23882389
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; };
23892390
94145430175D7FDE00284436 /* lldb-versioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-versioning.h"; path = "include/lldb/lldb-versioning.h"; sourceTree = "<group>"; };
2391+
9418EBCB1AA9108B0058B02E /* VectorType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VectorType.h; path = include/lldb/DataFormatters/VectorType.h; sourceTree = "<group>"; };
2392+
9418EBCC1AA910910058B02E /* VectorType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VectorType.cpp; path = source/DataFormatters/VectorType.cpp; sourceTree = "<group>"; };
23902393
94235B9A1A8D5FD800EB2EED /* SBVariablesOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBVariablesOptions.h; path = include/lldb/API/SBVariablesOptions.h; sourceTree = "<group>"; };
23912394
94235B9B1A8D5FF300EB2EED /* SBVariablesOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBVariablesOptions.cpp; path = source/API/SBVariablesOptions.cpp; sourceTree = "<group>"; };
23922395
94235B9D1A8D601A00EB2EED /* SBVariablesOptions.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBVariablesOptions.i; sourceTree = "<group>"; };
@@ -5037,6 +5040,8 @@
50375040
94CD131919BA33B400DB7BED /* TypeValidator.cpp */,
50385041
945215DD17F639E600521C0B /* ValueObjectPrinter.h */,
50395042
945215DE17F639EE00521C0B /* ValueObjectPrinter.cpp */,
5043+
9418EBCB1AA9108B0058B02E /* VectorType.h */,
5044+
9418EBCC1AA910910058B02E /* VectorType.cpp */,
50405045
);
50415046
name = DataFormatters;
50425047
sourceTree = "<group>";
@@ -5977,6 +5982,7 @@
59775982
94BA8B70176F97CE005A91B5 /* CommandHistory.cpp in Sources */,
59785983
2689007713353E1A00698AC0 /* CFCData.cpp in Sources */,
59795984
2689007813353E1A00698AC0 /* CFCMutableArray.cpp in Sources */,
5985+
9418EBCD1AA910910058B02E /* VectorType.cpp in Sources */,
59805986
2689007913353E1A00698AC0 /* CFCMutableDictionary.cpp in Sources */,
59815987
2689007A13353E1A00698AC0 /* CFCMutableSet.cpp in Sources */,
59825988
2689007B13353E1A00698AC0 /* CFCString.cpp in Sources */,

‎lldb/source/DataFormatters/FormatManager.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,15 @@ FormatManager::LoadSystemFormatters()
12161216

12171217
AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
12181218

1219+
SyntheticChildren::Flags synth_flags;
1220+
synth_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1221+
1222+
AddCXXSynthetic(sys_category_sp,
1223+
lldb_private::formatters::VectorTypeSyntheticFrontEndCreator,
1224+
"vector_type synthetic children",
1225+
ConstString("unsigned char __attribute__\\(\\(ext_vector_type\\([0-9]+\\)\\)\\)"),
1226+
synth_flags,
1227+
true);
12191228
#endif
12201229
}
12211230

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
//===-- VectorType.cpp ---------------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "lldb/DataFormatters/CXXFormatterFunctions.h"
11+
12+
#include "lldb/Core/ValueObject.h"
13+
#include "lldb/Symbol/ClangASTContext.h"
14+
#include "lldb/Symbol/ClangASTType.h"
15+
16+
#include "lldb/Utility/LLDBAssert.h"
17+
18+
using namespace lldb;
19+
using namespace lldb_private;
20+
using namespace lldb_private::formatters;
21+
22+
static ClangASTType
23+
GetClangTypeForFormat (lldb::Format format,
24+
ClangASTContext *ast_ctx)
25+
{
26+
lldbassert(ast_ctx && "ast_ctx needs to be not NULL");
27+
28+
switch (format)
29+
{
30+
case lldb::eFormatAddressInfo:
31+
case lldb::eFormatPointer:
32+
return ast_ctx->GetPointerSizedIntType(false);
33+
34+
case lldb::eFormatBoolean:
35+
return ast_ctx->GetBasicType(lldb::eBasicTypeBool);
36+
37+
case lldb::eFormatBytes:
38+
case lldb::eFormatBytesWithASCII:
39+
case lldb::eFormatChar:
40+
case lldb::eFormatCharArray:
41+
case lldb::eFormatCharPrintable:
42+
return ast_ctx->GetBasicType(lldb::eBasicTypeChar);
43+
44+
case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
45+
return ast_ctx->GetBasicType(lldb::eBasicTypeFloatComplex);
46+
47+
case lldb::eFormatCString:
48+
return ast_ctx->GetBasicType(lldb::eBasicTypeChar).GetPointerType();
49+
50+
case lldb::eFormatFloat:
51+
return ast_ctx->GetBasicType(lldb::eBasicTypeFloat);
52+
53+
case lldb::eFormatHex:
54+
case lldb::eFormatHexUppercase:
55+
case lldb::eFormatOctal:
56+
return ast_ctx->GetBasicType(lldb::eBasicTypeInt);
57+
58+
case lldb::eFormatHexFloat:
59+
return ast_ctx->GetBasicType(lldb::eBasicTypeFloat);
60+
61+
case lldb::eFormatUnicode16:
62+
case lldb::eFormatUnicode32:
63+
64+
case lldb::eFormatUnsigned:
65+
return ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedInt);
66+
67+
case lldb::eFormatVectorOfChar:
68+
return ast_ctx->GetBasicType(lldb::eBasicTypeChar);
69+
70+
case lldb::eFormatVectorOfFloat32:
71+
return ast_ctx->GetFloatTypeFromBitSize(32);
72+
73+
case lldb::eFormatVectorOfFloat64:
74+
return ast_ctx->GetFloatTypeFromBitSize(64);
75+
76+
case lldb::eFormatVectorOfSInt16:
77+
return ast_ctx->GetIntTypeFromBitSize(16, true);
78+
79+
case lldb::eFormatVectorOfSInt32:
80+
return ast_ctx->GetIntTypeFromBitSize(32, true);
81+
82+
case lldb::eFormatVectorOfSInt64:
83+
return ast_ctx->GetIntTypeFromBitSize(64, true);
84+
85+
case lldb::eFormatVectorOfSInt8:
86+
return ast_ctx->GetIntTypeFromBitSize(8, true);
87+
88+
case lldb::eFormatVectorOfUInt128:
89+
return ast_ctx->GetIntTypeFromBitSize(128, false);
90+
91+
case lldb::eFormatVectorOfUInt16:
92+
return ast_ctx->GetIntTypeFromBitSize(16, false);
93+
94+
case lldb::eFormatVectorOfUInt32:
95+
return ast_ctx->GetIntTypeFromBitSize(32, false);
96+
97+
case lldb::eFormatVectorOfUInt64:
98+
return ast_ctx->GetIntTypeFromBitSize(64, false);
99+
100+
case lldb::eFormatVectorOfUInt8:
101+
return ast_ctx->GetIntTypeFromBitSize(8, false);
102+
103+
case lldb::eFormatBinary:
104+
case lldb::eFormatComplexInteger:
105+
case lldb::eFormatDecimal:
106+
case lldb::eFormatDefault:
107+
case lldb::eFormatEnum:
108+
case lldb::eFormatInstruction:
109+
case lldb::eFormatOSType:
110+
case lldb::eFormatVoid:
111+
default:
112+
return ast_ctx->GetIntTypeFromBitSize(8, false);
113+
}
114+
}
115+
116+
static lldb::Format
117+
GetItemFormatForFormat (lldb::Format format)
118+
{
119+
switch (format)
120+
{
121+
case lldb::eFormatVectorOfChar:
122+
return lldb::eFormatChar;
123+
124+
case lldb::eFormatVectorOfFloat32:
125+
case lldb::eFormatVectorOfFloat64:
126+
return lldb::eFormatFloat;
127+
128+
case lldb::eFormatVectorOfSInt16:
129+
case lldb::eFormatVectorOfSInt32:
130+
case lldb::eFormatVectorOfSInt64:
131+
case lldb::eFormatVectorOfSInt8:
132+
return lldb::eFormatDecimal;
133+
134+
case lldb::eFormatVectorOfUInt128:
135+
case lldb::eFormatVectorOfUInt16:
136+
case lldb::eFormatVectorOfUInt32:
137+
case lldb::eFormatVectorOfUInt64:
138+
case lldb::eFormatVectorOfUInt8:
139+
return lldb::eFormatUnsigned;
140+
141+
case lldb::eFormatBinary:
142+
case lldb::eFormatComplexInteger:
143+
case lldb::eFormatDecimal:
144+
case lldb::eFormatDefault:
145+
case lldb::eFormatEnum:
146+
case lldb::eFormatInstruction:
147+
case lldb::eFormatOSType:
148+
case lldb::eFormatVoid:
149+
return eFormatHex;
150+
151+
default:
152+
return format;
153+
}
154+
}
155+
156+
static size_t
157+
CalculateNumChildren (ClangASTType container_type,
158+
ClangASTType element_type,
159+
lldb_private::ExecutionContextScope *exe_scope = nullptr // does not matter here because all we trade in are basic types
160+
)
161+
{
162+
auto container_size = container_type.GetByteSize(exe_scope);
163+
auto element_size = element_type.GetByteSize(exe_scope);
164+
165+
if (element_size)
166+
{
167+
if (container_size % element_size)
168+
return 0;
169+
return container_size / element_size;
170+
}
171+
return 0;
172+
}
173+
174+
namespace lldb_private {
175+
namespace formatters {
176+
177+
class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd
178+
{
179+
public:
180+
VectorTypeSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
181+
SyntheticChildrenFrontEnd(*valobj_sp),
182+
m_parent_format (eFormatInvalid),
183+
m_item_format(eFormatInvalid),
184+
m_child_type(),
185+
m_num_children(0)
186+
{}
187+
188+
virtual size_t
189+
CalculateNumChildren ()
190+
{
191+
return m_num_children;
192+
}
193+
194+
virtual lldb::ValueObjectSP
195+
GetChildAtIndex (size_t idx)
196+
{
197+
if (idx >= CalculateNumChildren())
198+
return lldb::ValueObjectSP();
199+
auto offset = idx * m_child_type.GetByteSize(nullptr);
200+
ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(offset, m_child_type, true));
201+
if (!child_sp)
202+
return child_sp;
203+
204+
StreamString idx_name;
205+
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
206+
child_sp->SetName( ConstString( idx_name.GetData() ) );
207+
208+
child_sp->SetFormat(m_item_format);
209+
210+
return child_sp;
211+
}
212+
213+
virtual bool
214+
Update()
215+
{
216+
m_parent_format = m_backend.GetFormat();
217+
ClangASTType parent_type(m_backend.GetClangType());
218+
m_child_type = ::GetClangTypeForFormat(m_parent_format, ClangASTContext::GetASTContext(parent_type.GetASTContext()));
219+
m_num_children = ::CalculateNumChildren(parent_type,
220+
m_child_type);
221+
m_item_format = GetItemFormatForFormat(m_parent_format);
222+
return false;
223+
}
224+
225+
virtual bool
226+
MightHaveChildren ()
227+
{
228+
return true;
229+
}
230+
231+
virtual size_t
232+
GetIndexOfChildWithName (const ConstString &name)
233+
{
234+
const char* item_name = name.GetCString();
235+
uint32_t idx = ExtractIndexFromString(item_name);
236+
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
237+
return UINT32_MAX;
238+
return idx;
239+
}
240+
241+
virtual
242+
~VectorTypeSyntheticFrontEnd () {}
243+
244+
private:
245+
lldb::Format m_parent_format;
246+
lldb::Format m_item_format;
247+
ClangASTType m_child_type;
248+
size_t m_num_children;
249+
};
250+
}
251+
}
252+
253+
lldb_private::SyntheticChildrenFrontEnd*
254+
lldb_private::formatters::VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
255+
{
256+
if (!valobj_sp)
257+
return NULL;
258+
return (new VectorTypeSyntheticFrontEnd(valobj_sp));
259+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
LEVEL = ../../../make
2+
3+
CXX_SOURCES := main.cpp
4+
5+
include $(LEVEL)/Makefile.rules

0 commit comments

Comments
 (0)
Please sign in to comment.