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