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