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