]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/VectorType.cpp
MFV r293125: less v481.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / DataFormatters / VectorType.cpp
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/VectorType.h"
11
12 #include "lldb/Core/ValueObject.h"
13 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
14 #include "lldb/Symbol/ClangASTContext.h"
15 #include "lldb/Symbol/ClangASTType.h"
16
17 #include "lldb/Utility/LLDBAssert.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21 using namespace lldb_private::formatters;
22
23 static ClangASTType
24 GetClangTypeForFormat (lldb::Format format,
25                        ClangASTType element_type,
26                        ClangASTContext *ast_ctx)
27 {
28     lldbassert(ast_ctx && "ast_ctx needs to be not NULL");
29     
30     switch (format)
31     {
32         case lldb::eFormatAddressInfo:
33         case lldb::eFormatPointer:
34             return ast_ctx->GetPointerSizedIntType(false);
35             
36         case lldb::eFormatBoolean:
37             return ast_ctx->GetBasicType(lldb::eBasicTypeBool);
38             
39         case lldb::eFormatBytes:
40         case lldb::eFormatBytesWithASCII:
41         case lldb::eFormatChar:
42         case lldb::eFormatCharArray:
43         case lldb::eFormatCharPrintable:
44             return ast_ctx->GetBasicType(lldb::eBasicTypeChar);
45
46         case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
47             return ast_ctx->GetBasicType(lldb::eBasicTypeFloatComplex);
48
49         case lldb::eFormatCString:
50             return ast_ctx->GetBasicType(lldb::eBasicTypeChar).GetPointerType();
51
52         case lldb::eFormatFloat:
53             return ast_ctx->GetBasicType(lldb::eBasicTypeFloat);
54             
55         case lldb::eFormatHex:
56         case lldb::eFormatHexUppercase:
57         case lldb::eFormatOctal:
58             return ast_ctx->GetBasicType(lldb::eBasicTypeInt);
59
60         case lldb::eFormatHexFloat:
61             return ast_ctx->GetBasicType(lldb::eBasicTypeFloat);
62
63         case lldb::eFormatUnicode16:
64         case lldb::eFormatUnicode32:
65
66         case lldb::eFormatUnsigned:
67             return ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedInt);
68
69         case lldb::eFormatVectorOfChar:
70             return ast_ctx->GetBasicType(lldb::eBasicTypeChar);
71             
72         case lldb::eFormatVectorOfFloat32:
73             return ast_ctx->GetFloatTypeFromBitSize(32);
74             
75         case lldb::eFormatVectorOfFloat64:
76             return ast_ctx->GetFloatTypeFromBitSize(64);
77             
78         case lldb::eFormatVectorOfSInt16:
79             return ast_ctx->GetIntTypeFromBitSize(16, true);
80             
81         case lldb::eFormatVectorOfSInt32:
82             return ast_ctx->GetIntTypeFromBitSize(32, true);
83
84         case lldb::eFormatVectorOfSInt64:
85             return ast_ctx->GetIntTypeFromBitSize(64, true);
86             
87         case lldb::eFormatVectorOfSInt8:
88             return ast_ctx->GetIntTypeFromBitSize(8, true);
89
90         case lldb::eFormatVectorOfUInt128:
91             return ast_ctx->GetIntTypeFromBitSize(128, false);
92
93         case lldb::eFormatVectorOfUInt16:
94             return ast_ctx->GetIntTypeFromBitSize(16, false);
95
96         case lldb::eFormatVectorOfUInt32:
97             return ast_ctx->GetIntTypeFromBitSize(32, false);
98
99         case lldb::eFormatVectorOfUInt64:
100             return ast_ctx->GetIntTypeFromBitSize(64, false);
101
102         case lldb::eFormatVectorOfUInt8:
103             return ast_ctx->GetIntTypeFromBitSize(8, false);
104             
105         case lldb::eFormatDefault:
106             return element_type;
107         
108         case lldb::eFormatBinary:
109         case lldb::eFormatComplexInteger:
110         case lldb::eFormatDecimal:
111         case lldb::eFormatEnum:
112         case lldb::eFormatInstruction:
113         case lldb::eFormatOSType:
114         case lldb::eFormatVoid:
115         default:
116             return ast_ctx->GetIntTypeFromBitSize(8, false);
117     }
118 }
119
120 static lldb::Format
121 GetItemFormatForFormat (lldb::Format format,
122                         ClangASTType element_type)
123 {
124     switch (format)
125     {
126         case lldb::eFormatVectorOfChar:
127             return lldb::eFormatChar;
128             
129         case lldb::eFormatVectorOfFloat32:
130         case lldb::eFormatVectorOfFloat64:
131             return lldb::eFormatFloat;
132             
133         case lldb::eFormatVectorOfSInt16:
134         case lldb::eFormatVectorOfSInt32:
135         case lldb::eFormatVectorOfSInt64:
136         case lldb::eFormatVectorOfSInt8:
137             return lldb::eFormatDecimal;
138             
139         case lldb::eFormatVectorOfUInt128:
140         case lldb::eFormatVectorOfUInt16:
141         case lldb::eFormatVectorOfUInt32:
142         case lldb::eFormatVectorOfUInt64:
143         case lldb::eFormatVectorOfUInt8:
144             return lldb::eFormatUnsigned;
145             
146         case lldb::eFormatBinary:
147         case lldb::eFormatComplexInteger:
148         case lldb::eFormatDecimal:
149         case lldb::eFormatEnum:
150         case lldb::eFormatInstruction:
151         case lldb::eFormatOSType:
152         case lldb::eFormatVoid:
153             return eFormatHex;
154
155         case lldb::eFormatDefault:
156         {
157             // special case the (default, char) combination to actually display as an integer value
158             // most often, you won't want to see the ASCII characters... (and if you do, eFormatChar is a keystroke away)
159             bool is_char = element_type.IsCharType();
160             bool is_signed = false;
161             element_type.IsIntegerType(is_signed);
162             return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format;
163         }
164             break;
165             
166         default:
167             return format;
168     }
169 }
170
171 static size_t
172 CalculateNumChildren (ClangASTType container_type,
173                       ClangASTType element_type,
174                       lldb_private::ExecutionContextScope *exe_scope = nullptr // does not matter here because all we trade in are basic types
175                       )
176 {
177     auto container_size = container_type.GetByteSize(exe_scope);
178     auto element_size = element_type.GetByteSize(exe_scope);
179     
180     if (element_size)
181     {
182         if (container_size % element_size)
183             return 0;
184         return container_size / element_size;
185     }
186     return 0;
187 }
188
189 namespace lldb_private {
190     namespace formatters {
191
192         class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd
193         {
194         public:
195             VectorTypeSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
196             SyntheticChildrenFrontEnd(*valobj_sp),
197             m_parent_format (eFormatInvalid),
198             m_item_format(eFormatInvalid),
199             m_child_type(),
200             m_num_children(0)
201             {}
202             
203             virtual size_t
204             CalculateNumChildren ()
205             {
206                 return m_num_children;
207             }
208             
209             virtual lldb::ValueObjectSP
210             GetChildAtIndex (size_t idx)
211             {
212                 if (idx >= CalculateNumChildren())
213                     return lldb::ValueObjectSP();
214                 auto offset = idx * m_child_type.GetByteSize(nullptr);
215                 ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(offset, m_child_type, true));
216                 if (!child_sp)
217                     return child_sp;
218                 
219                 StreamString idx_name;
220                 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
221                 child_sp->SetName( ConstString( idx_name.GetData() ) );
222                 
223                 child_sp->SetFormat(m_item_format);
224                 
225                 return child_sp;
226             }
227
228             virtual bool
229             Update()
230             {
231                 m_parent_format = m_backend.GetFormat();
232                 ClangASTType parent_type(m_backend.GetClangType());
233                 ClangASTType element_type;
234                 parent_type.IsVectorType(&element_type, nullptr);
235                 m_child_type = ::GetClangTypeForFormat(m_parent_format, element_type, ClangASTContext::GetASTContext(parent_type.GetASTContext()));
236                 m_num_children = ::CalculateNumChildren(parent_type,
237                                                         m_child_type);
238                 m_item_format = GetItemFormatForFormat(m_parent_format,
239                                                        m_child_type);
240                 return false;
241             }
242             
243             virtual bool
244             MightHaveChildren ()
245             {
246                 return true;
247             }
248             
249             virtual size_t
250             GetIndexOfChildWithName (const ConstString &name)
251             {
252                 const char* item_name = name.GetCString();
253                 uint32_t idx = ExtractIndexFromString(item_name);
254                 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
255                     return UINT32_MAX;
256                 return idx;
257             }
258             
259             virtual
260             ~VectorTypeSyntheticFrontEnd () {}
261             
262         private:
263             lldb::Format m_parent_format;
264             lldb::Format m_item_format;
265             ClangASTType m_child_type;
266             size_t m_num_children;
267         };
268     }
269 }
270
271 bool
272 lldb_private::formatters::VectorTypeSummaryProvider (ValueObject& valobj,
273                                                      Stream& s,
274                                                      const TypeSummaryOptions&)
275 {
276     auto synthetic_children = VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP());
277     if (!synthetic_children)
278         return false;
279     
280     synthetic_children->Update();
281     
282     s.PutChar('(');
283     bool first = true;
284     
285     size_t idx = 0, len = synthetic_children->CalculateNumChildren();
286     
287     for (;
288          idx < len;
289          idx++)
290     {
291         auto child_sp = synthetic_children->GetChildAtIndex(idx);
292         if (!child_sp)
293             continue;
294         child_sp = child_sp->GetQualifiedRepresentationIfAvailable(lldb::eDynamicDontRunTarget, true);
295         
296         const char* child_value = child_sp->GetValueAsCString();
297         if (child_value && *child_value)
298         {
299             if (first)
300             {
301                 s.Printf("%s", child_value);
302                 first = false;
303             }
304             else
305             {
306                 s.Printf(", %s", child_value);
307             }
308         }
309     }
310     
311     s.PutChar(')');
312     
313     return true;
314 }
315
316 lldb_private::SyntheticChildrenFrontEnd*
317 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
318 {
319     if (!valobj_sp)
320         return NULL;
321     return (new VectorTypeSyntheticFrontEnd(valobj_sp));
322 }