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