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