]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/TypeFormat.cpp
Merge ^/head r296369 through r296409.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / DataFormatters / TypeFormat.cpp
1 //===-- TypeFormat.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/TypeFormat.h"
11
12 // C Includes
13
14 // C++ Includes
15
16 // Other libraries and framework includes
17
18 // Project includes
19 #include "lldb/lldb-public.h"
20 #include "lldb/lldb-enumerations.h"
21
22 #include "lldb/Core/StreamString.h"
23 #include "lldb/DataFormatters/FormatManager.h"
24 #include "lldb/Symbol/CompilerType.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Symbol/TypeList.h"
27 #include "lldb/Target/Target.h"
28
29 using namespace lldb;
30 using namespace lldb_private;
31
32 TypeFormatImpl::TypeFormatImpl (const Flags& flags) :
33 m_flags(flags),
34 m_my_revision(0)
35 {
36 }
37
38 TypeFormatImpl::~TypeFormatImpl ()
39 {
40 }
41
42 TypeFormatImpl_Format::TypeFormatImpl_Format (lldb::Format f,
43                                               const TypeFormatImpl::Flags& flags) :
44 TypeFormatImpl(flags),
45 m_format (f)
46 {
47 }
48
49 TypeFormatImpl_Format::~TypeFormatImpl_Format ()
50 {
51 }
52
53 bool
54 TypeFormatImpl_Format::FormatObject (ValueObject *valobj,
55                                      std::string& dest) const
56 {
57     if (!valobj)
58         return false;
59     if (valobj->CanProvideValue())
60     {
61         Value& value(valobj->GetValue());
62         const Value::ContextType context_type = value.GetContextType();
63         ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
64         DataExtractor data;
65         
66         if (context_type == Value::eContextTypeRegisterInfo)
67         {
68             const RegisterInfo *reg_info = value.GetRegisterInfo();
69             if (reg_info)
70             {
71                 Error error;
72                 valobj->GetData(data, error);
73                 if (error.Fail())
74                     return false;
75                 
76                 StreamString reg_sstr;
77                 data.Dump (&reg_sstr,
78                            0,
79                            GetFormat(),
80                            reg_info->byte_size,
81                            1,
82                            UINT32_MAX,
83                            LLDB_INVALID_ADDRESS,
84                            0,
85                            0,
86                            exe_ctx.GetBestExecutionContextScope());
87                 dest.swap(reg_sstr.GetString());
88             }
89         }
90         else
91         {
92             CompilerType compiler_type = value.GetCompilerType ();
93             if (compiler_type)
94             {
95                 // put custom bytes to display in the DataExtractor to override the default value logic
96                 if (GetFormat() == eFormatCString)
97                 {
98                     lldb_private::Flags type_flags(compiler_type.GetTypeInfo(NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags
99                     if (type_flags.Test(eTypeIsPointer) && !type_flags.Test(eTypeIsObjC))
100                     {
101                         // if we are dumping a pointer as a c-string, get the pointee data as a string
102                         TargetSP target_sp(valobj->GetTargetSP());
103                         if (target_sp)
104                         {
105                             size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
106                             Error error;
107                             DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
108                             Address address(valobj->GetPointerValue());
109                             if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
110                                 data.SetData(buffer_sp);
111                         }
112                     }
113                 }
114                 else
115                 {
116                     Error error;
117                     valobj->GetData(data, error);
118                     if (error.Fail())
119                         return false;
120                 }
121                 
122                 StreamString sstr;
123                 compiler_type.DumpTypeValue (&sstr,                         // The stream to use for display
124                                           GetFormat(),                  // Format to display this type with
125                                           data,                         // Data to extract from
126                                           0,                             // Byte offset into "m_data"
127                                           valobj->GetByteSize(),                 // Byte size of item in "m_data"
128                                           valobj->GetBitfieldBitSize(),          // Bitfield bit size
129                                           valobj->GetBitfieldBitOffset(),        // Bitfield bit offset
130                                           exe_ctx.GetBestExecutionContextScope());
131                 // Given that we do not want to set the ValueObject's m_error
132                 // for a formatting error (or else we wouldn't be able to reformat
133                 // until a next update), an empty string is treated as a "false"
134                 // return from here, but that's about as severe as we get
135                 // CompilerType::DumpTypeValue() should always return
136                 // something, even if that something is an error message
137                 if (sstr.GetString().empty())
138                     dest.clear();
139                 else
140                     dest.swap(sstr.GetString());
141             }
142         }
143         return !dest.empty();
144     }
145     else
146         return false;
147 }
148
149 std::string
150 TypeFormatImpl_Format::GetDescription()
151 {
152     StreamString sstr;
153     sstr.Printf ("%s%s%s%s",
154                  FormatManager::GetFormatAsCString (GetFormat()),
155                  Cascades() ? "" : " (not cascading)",
156                  SkipsPointers() ? " (skip pointers)" : "",
157                  SkipsReferences() ? " (skip references)" : "");
158     return sstr.GetString();
159 }
160
161 TypeFormatImpl_EnumType::TypeFormatImpl_EnumType (ConstString type_name,
162                                                   const TypeFormatImpl::Flags& flags) :
163 TypeFormatImpl(flags),
164 m_enum_type(type_name),
165 m_types()
166 {
167 }
168
169 TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType ()
170 {
171 }
172
173 bool
174 TypeFormatImpl_EnumType::FormatObject (ValueObject *valobj,
175                                        std::string& dest) const
176 {
177     dest.clear();
178     if (!valobj)
179         return false;
180     if (!valobj->CanProvideValue())
181         return false;
182     ProcessSP process_sp;
183     TargetSP target_sp;
184     void* valobj_key = (process_sp = valobj->GetProcessSP()).get();
185     if (!valobj_key)
186         valobj_key = (target_sp = valobj->GetTargetSP()).get();
187     else
188         target_sp = process_sp->GetTarget().shared_from_this();
189     if (!valobj_key)
190         return false;
191     auto iter = m_types.find(valobj_key),
192     end = m_types.end();
193     CompilerType valobj_enum_type;
194     if (iter == end)
195     {
196         // probably a redundant check
197         if (!target_sp)
198             return false;
199         const ModuleList& images(target_sp->GetImages());
200         SymbolContext sc;
201         TypeList types;
202         images.FindTypes(sc, m_enum_type, false, UINT32_MAX, types);
203         if (types.GetSize() == 0)
204             return false;
205         for (lldb::TypeSP type_sp : types.Types())
206         {
207             if (!type_sp)
208                 continue;
209             if ( (type_sp->GetForwardCompilerType().GetTypeInfo() & eTypeIsEnumeration) == eTypeIsEnumeration)
210             {
211                 valobj_enum_type = type_sp->GetFullCompilerType ();
212                 m_types.emplace(valobj_key,valobj_enum_type);
213                 break;
214             }
215         }
216     }
217     else
218         valobj_enum_type = iter->second;
219     if (valobj_enum_type.IsValid() == false)
220         return false;
221     DataExtractor data;
222     Error error;
223     valobj->GetData(data, error);
224     if (error.Fail())
225         return false;
226     ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
227     StreamString sstr;
228     valobj_enum_type.DumpTypeValue(&sstr,
229                                    lldb::eFormatEnum,
230                                    data,
231                                    0,
232                                    data.GetByteSize(),
233                                    0,
234                                    0,
235                                    exe_ctx.GetBestExecutionContextScope());
236     if (!sstr.GetString().empty())
237         dest.swap(sstr.GetString());
238     return !dest.empty();
239 }
240
241 std::string
242 TypeFormatImpl_EnumType::GetDescription()
243 {
244     StreamString sstr;
245     sstr.Printf ("as type %s%s%s%s",
246                  m_enum_type.AsCString("<invalid type>"),
247                  Cascades() ? "" : " (not cascading)",
248                  SkipsPointers() ? " (skip pointers)" : "",
249                  SkipsReferences() ? " (skip references)" : "");
250     return sstr.GetString();
251 }