1 //===-- Type.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 <stdio.h>
11
12 #include "lldb/Core/Module.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/Scalar.h"
16 #include "lldb/Utility/StreamString.h"
17
18 #include "lldb/Symbol/CompilerType.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Symbol/SymbolContextScope.h"
21 #include "lldb/Symbol/SymbolFile.h"
22 #include "lldb/Symbol/SymbolVendor.h"
23 #include "lldb/Symbol/Type.h"
24 #include "lldb/Symbol/TypeList.h"
25 #include "lldb/Symbol/TypeSystem.h"
26
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Target.h"
30
31 #include "llvm/ADT/StringRef.h"
32
33 #include "clang/AST/Decl.h"
34 #include "clang/AST/DeclObjC.h"
35
36 using namespace lldb;
37 using namespace lldb_private;
38
Dump() const39 void CompilerContext::Dump() const {
40 switch (type) {
41 case CompilerContextKind::Invalid:
42 printf("Invalid");
43 break;
44 case CompilerContextKind::TranslationUnit:
45 printf("TranslationUnit");
46 break;
47 case CompilerContextKind::Module:
48 printf("Module");
49 break;
50 case CompilerContextKind::Namespace:
51 printf("Namespace");
52 break;
53 case CompilerContextKind::Class:
54 printf("Class");
55 break;
56 case CompilerContextKind::Structure:
57 printf("Structure");
58 break;
59 case CompilerContextKind::Union:
60 printf("Union");
61 break;
62 case CompilerContextKind::Function:
63 printf("Function");
64 break;
65 case CompilerContextKind::Variable:
66 printf("Variable");
67 break;
68 case CompilerContextKind::Enumeration:
69 printf("Enumeration");
70 break;
71 case CompilerContextKind::Typedef:
72 printf("Typedef");
73 break;
74 }
75 printf("(\"%s\")\n", name.GetCString());
76 }
77
78 class TypeAppendVisitor {
79 public:
TypeAppendVisitor(TypeListImpl & type_list)80 TypeAppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}
81
operator ()(const lldb::TypeSP & type)82 bool operator()(const lldb::TypeSP &type) {
83 m_type_list.Append(TypeImplSP(new TypeImpl(type)));
84 return true;
85 }
86
87 private:
88 TypeListImpl &m_type_list;
89 };
90
Append(const lldb_private::TypeList & type_list)91 void TypeListImpl::Append(const lldb_private::TypeList &type_list) {
92 TypeAppendVisitor cb(*this);
93 type_list.ForEach(cb);
94 }
95
SymbolFileType(SymbolFile & symbol_file,const lldb::TypeSP & type_sp)96 SymbolFileType::SymbolFileType(SymbolFile &symbol_file,
97 const lldb::TypeSP &type_sp)
98 : UserID(type_sp ? type_sp->GetID() : LLDB_INVALID_UID),
99 m_symbol_file(symbol_file), m_type_sp(type_sp) {}
100
GetType()101 Type *SymbolFileType::GetType() {
102 if (!m_type_sp) {
103 Type *resolved_type = m_symbol_file.ResolveTypeUID(GetID());
104 if (resolved_type)
105 m_type_sp = resolved_type->shared_from_this();
106 }
107 return m_type_sp.get();
108 }
109
Type(lldb::user_id_t uid,SymbolFile * symbol_file,const ConstString & name,uint64_t byte_size,SymbolContextScope * context,user_id_t encoding_uid,EncodingDataType encoding_uid_type,const Declaration & decl,const CompilerType & compiler_type,ResolveState compiler_type_resolve_state)110 Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file,
111 const ConstString &name, uint64_t byte_size,
112 SymbolContextScope *context, user_id_t encoding_uid,
113 EncodingDataType encoding_uid_type, const Declaration &decl,
114 const CompilerType &compiler_type,
115 ResolveState compiler_type_resolve_state)
116 : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name),
117 m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr),
118 m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type),
119 m_byte_size(byte_size), m_decl(decl), m_compiler_type(compiler_type) {
120 m_flags.compiler_type_resolve_state =
121 (compiler_type ? compiler_type_resolve_state : eResolveStateUnresolved);
122 m_flags.is_complete_objc_class = false;
123 }
124
Type()125 Type::Type()
126 : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"),
127 m_symbol_file(nullptr), m_context(nullptr), m_encoding_type(nullptr),
128 m_encoding_uid(LLDB_INVALID_UID), m_encoding_uid_type(eEncodingInvalid),
129 m_byte_size(0), m_decl(), m_compiler_type() {
130 m_flags.compiler_type_resolve_state = eResolveStateUnresolved;
131 m_flags.is_complete_objc_class = false;
132 }
133
Type(const Type & rhs)134 Type::Type(const Type &rhs)
135 : std::enable_shared_from_this<Type>(rhs), UserID(rhs), m_name(rhs.m_name),
136 m_symbol_file(rhs.m_symbol_file), m_context(rhs.m_context),
137 m_encoding_type(rhs.m_encoding_type), m_encoding_uid(rhs.m_encoding_uid),
138 m_encoding_uid_type(rhs.m_encoding_uid_type),
139 m_byte_size(rhs.m_byte_size), m_decl(rhs.m_decl),
140 m_compiler_type(rhs.m_compiler_type), m_flags(rhs.m_flags) {}
141
operator =(const Type & rhs)142 const Type &Type::operator=(const Type &rhs) {
143 if (this != &rhs) {
144 }
145 return *this;
146 }
147
GetDescription(Stream * s,lldb::DescriptionLevel level,bool show_name)148 void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
149 bool show_name) {
150 *s << "id = " << (const UserID &)*this;
151
152 // Call the name accessor to make sure we resolve the type name
153 if (show_name) {
154 const ConstString &type_name = GetName();
155 if (type_name) {
156 *s << ", name = \"" << type_name << '"';
157 ConstString qualified_type_name(GetQualifiedName());
158 if (qualified_type_name != type_name) {
159 *s << ", qualified = \"" << qualified_type_name << '"';
160 }
161 }
162 }
163
164 // Call the get byte size accesor so we resolve our byte size
165 if (GetByteSize())
166 s->Printf(", byte-size = %" PRIu64, m_byte_size);
167 bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
168 m_decl.Dump(s, show_fullpaths);
169
170 if (m_compiler_type.IsValid()) {
171 *s << ", compiler_type = \"";
172 GetForwardCompilerType().DumpTypeDescription(s);
173 *s << '"';
174 } else if (m_encoding_uid != LLDB_INVALID_UID) {
175 s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
176 switch (m_encoding_uid_type) {
177 case eEncodingInvalid:
178 break;
179 case eEncodingIsUID:
180 s->PutCString(" (unresolved type)");
181 break;
182 case eEncodingIsConstUID:
183 s->PutCString(" (unresolved const type)");
184 break;
185 case eEncodingIsRestrictUID:
186 s->PutCString(" (unresolved restrict type)");
187 break;
188 case eEncodingIsVolatileUID:
189 s->PutCString(" (unresolved volatile type)");
190 break;
191 case eEncodingIsTypedefUID:
192 s->PutCString(" (unresolved typedef)");
193 break;
194 case eEncodingIsPointerUID:
195 s->PutCString(" (unresolved pointer)");
196 break;
197 case eEncodingIsLValueReferenceUID:
198 s->PutCString(" (unresolved L value reference)");
199 break;
200 case eEncodingIsRValueReferenceUID:
201 s->PutCString(" (unresolved R value reference)");
202 break;
203 case eEncodingIsSyntheticUID:
204 s->PutCString(" (synthetic type)");
205 break;
206 }
207 }
208 }
209
Dump(Stream * s,bool show_context)210 void Type::Dump(Stream *s, bool show_context) {
211 s->Printf("%p: ", static_cast<void *>(this));
212 s->Indent();
213 *s << "Type" << static_cast<const UserID &>(*this) << ' ';
214 if (m_name)
215 *s << ", name = \"" << m_name << "\"";
216
217 if (m_byte_size != 0)
218 s->Printf(", size = %" PRIu64, m_byte_size);
219
220 if (show_context && m_context != nullptr) {
221 s->PutCString(", context = ( ");
222 m_context->DumpSymbolContext(s);
223 s->PutCString(" )");
224 }
225
226 bool show_fullpaths = false;
227 m_decl.Dump(s, show_fullpaths);
228
229 if (m_compiler_type.IsValid()) {
230 *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' ';
231 GetForwardCompilerType().DumpTypeDescription(s);
232 } else if (m_encoding_uid != LLDB_INVALID_UID) {
233 *s << ", type_data = " << (uint64_t)m_encoding_uid;
234 switch (m_encoding_uid_type) {
235 case eEncodingInvalid:
236 break;
237 case eEncodingIsUID:
238 s->PutCString(" (unresolved type)");
239 break;
240 case eEncodingIsConstUID:
241 s->PutCString(" (unresolved const type)");
242 break;
243 case eEncodingIsRestrictUID:
244 s->PutCString(" (unresolved restrict type)");
245 break;
246 case eEncodingIsVolatileUID:
247 s->PutCString(" (unresolved volatile type)");
248 break;
249 case eEncodingIsTypedefUID:
250 s->PutCString(" (unresolved typedef)");
251 break;
252 case eEncodingIsPointerUID:
253 s->PutCString(" (unresolved pointer)");
254 break;
255 case eEncodingIsLValueReferenceUID:
256 s->PutCString(" (unresolved L value reference)");
257 break;
258 case eEncodingIsRValueReferenceUID:
259 s->PutCString(" (unresolved R value reference)");
260 break;
261 case eEncodingIsSyntheticUID:
262 s->PutCString(" (synthetic type)");
263 break;
264 }
265 }
266
267 //
268 // if (m_access)
269 // s->Printf(", access = %u", m_access);
270 s->EOL();
271 }
272
GetName()273 const ConstString &Type::GetName() {
274 if (!m_name)
275 m_name = GetForwardCompilerType().GetConstTypeName();
276 return m_name;
277 }
278
DumpTypeName(Stream * s)279 void Type::DumpTypeName(Stream *s) { GetName().Dump(s, "<invalid-type-name>"); }
280
DumpValue(ExecutionContext * exe_ctx,Stream * s,const DataExtractor & data,uint32_t data_byte_offset,bool show_types,bool show_summary,bool verbose,lldb::Format format)281 void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s,
282 const DataExtractor &data, uint32_t data_byte_offset,
283 bool show_types, bool show_summary, bool verbose,
284 lldb::Format format) {
285 if (ResolveClangType(eResolveStateForward)) {
286 if (show_types) {
287 s->PutChar('(');
288 if (verbose)
289 s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
290 DumpTypeName(s);
291 s->PutCString(") ");
292 }
293
294 GetForwardCompilerType().DumpValue(
295 exe_ctx, s, format == lldb::eFormatDefault ? GetFormat() : format, data,
296 data_byte_offset, GetByteSize(),
297 0, // Bitfield bit size
298 0, // Bitfield bit offset
299 show_types, show_summary, verbose, 0);
300 }
301 }
302
GetEncodingType()303 Type *Type::GetEncodingType() {
304 if (m_encoding_type == nullptr && m_encoding_uid != LLDB_INVALID_UID)
305 m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
306 return m_encoding_type;
307 }
308
GetByteSize()309 uint64_t Type::GetByteSize() {
310 if (m_byte_size == 0) {
311 switch (m_encoding_uid_type) {
312 case eEncodingInvalid:
313 case eEncodingIsSyntheticUID:
314 break;
315 case eEncodingIsUID:
316 case eEncodingIsConstUID:
317 case eEncodingIsRestrictUID:
318 case eEncodingIsVolatileUID:
319 case eEncodingIsTypedefUID: {
320 Type *encoding_type = GetEncodingType();
321 if (encoding_type)
322 m_byte_size = encoding_type->GetByteSize();
323 if (m_byte_size == 0)
324 if (llvm::Optional<uint64_t> size =
325 GetLayoutCompilerType().GetByteSize(nullptr))
326 m_byte_size = *size;
327 } break;
328
329 // If we are a pointer or reference, then this is just a pointer size;
330 case eEncodingIsPointerUID:
331 case eEncodingIsLValueReferenceUID:
332 case eEncodingIsRValueReferenceUID: {
333 if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture())
334 m_byte_size = arch.GetAddressByteSize();
335 } break;
336 }
337 }
338 return m_byte_size;
339 }
340
GetNumChildren(bool omit_empty_base_classes)341 uint32_t Type::GetNumChildren(bool omit_empty_base_classes) {
342 return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes, nullptr);
343 }
344
IsAggregateType()345 bool Type::IsAggregateType() {
346 return GetForwardCompilerType().IsAggregateType();
347 }
348
GetTypedefType()349 lldb::TypeSP Type::GetTypedefType() {
350 lldb::TypeSP type_sp;
351 if (IsTypedef()) {
352 Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
353 if (typedef_type)
354 type_sp = typedef_type->shared_from_this();
355 }
356 return type_sp;
357 }
358
GetFormat()359 lldb::Format Type::GetFormat() { return GetForwardCompilerType().GetFormat(); }
360
GetEncoding(uint64_t & count)361 lldb::Encoding Type::GetEncoding(uint64_t &count) {
362 // Make sure we resolve our type if it already hasn't been.
363 return GetForwardCompilerType().GetEncoding(count);
364 }
365
DumpValueInMemory(ExecutionContext * exe_ctx,Stream * s,lldb::addr_t address,AddressType address_type,bool show_types,bool show_summary,bool verbose)366 bool Type::DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s,
367 lldb::addr_t address, AddressType address_type,
368 bool show_types, bool show_summary, bool verbose) {
369 if (address != LLDB_INVALID_ADDRESS) {
370 DataExtractor data;
371 Target *target = nullptr;
372 if (exe_ctx)
373 target = exe_ctx->GetTargetPtr();
374 if (target)
375 data.SetByteOrder(target->GetArchitecture().GetByteOrder());
376 if (ReadFromMemory(exe_ctx, address, address_type, data)) {
377 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
378 return true;
379 }
380 }
381 return false;
382 }
383
ReadFromMemory(ExecutionContext * exe_ctx,lldb::addr_t addr,AddressType address_type,DataExtractor & data)384 bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
385 AddressType address_type, DataExtractor &data) {
386 if (address_type == eAddressTypeFile) {
387 // Can't convert a file address to anything valid without more context
388 // (which Module it came from)
389 return false;
390 }
391
392 const uint64_t byte_size = GetByteSize();
393 if (data.GetByteSize() < byte_size) {
394 lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0'));
395 data.SetData(data_sp);
396 }
397
398 uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
399 if (dst != nullptr) {
400 if (address_type == eAddressTypeHost) {
401 // The address is an address in this process, so just copy it
402 if (addr == 0)
403 return false;
404 memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size);
405 return true;
406 } else {
407 if (exe_ctx) {
408 Process *process = exe_ctx->GetProcessPtr();
409 if (process) {
410 Status error;
411 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size,
412 error) == byte_size;
413 }
414 }
415 }
416 }
417 return false;
418 }
419
WriteToMemory(ExecutionContext * exe_ctx,lldb::addr_t addr,AddressType address_type,DataExtractor & data)420 bool Type::WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
421 AddressType address_type, DataExtractor &data) {
422 return false;
423 }
424
GetTypeList()425 TypeList *Type::GetTypeList() { return GetSymbolFile()->GetTypeList(); }
426
GetDeclaration() const427 const Declaration &Type::GetDeclaration() const { return m_decl; }
428
ResolveClangType(ResolveState compiler_type_resolve_state)429 bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) {
430 // TODO: This needs to consider the correct type system to use.
431 Type *encoding_type = nullptr;
432 if (!m_compiler_type.IsValid()) {
433 encoding_type = GetEncodingType();
434 if (encoding_type) {
435 switch (m_encoding_uid_type) {
436 case eEncodingIsUID: {
437 CompilerType encoding_compiler_type =
438 encoding_type->GetForwardCompilerType();
439 if (encoding_compiler_type.IsValid()) {
440 m_compiler_type = encoding_compiler_type;
441 m_flags.compiler_type_resolve_state =
442 encoding_type->m_flags.compiler_type_resolve_state;
443 }
444 } break;
445
446 case eEncodingIsConstUID:
447 m_compiler_type =
448 encoding_type->GetForwardCompilerType().AddConstModifier();
449 break;
450
451 case eEncodingIsRestrictUID:
452 m_compiler_type =
453 encoding_type->GetForwardCompilerType().AddRestrictModifier();
454 break;
455
456 case eEncodingIsVolatileUID:
457 m_compiler_type =
458 encoding_type->GetForwardCompilerType().AddVolatileModifier();
459 break;
460
461 case eEncodingIsTypedefUID:
462 m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef(
463 m_name.AsCString("__lldb_invalid_typedef_name"),
464 GetSymbolFile()->GetDeclContextContainingUID(GetID()));
465 m_name.Clear();
466 break;
467
468 case eEncodingIsPointerUID:
469 m_compiler_type =
470 encoding_type->GetForwardCompilerType().GetPointerType();
471 break;
472
473 case eEncodingIsLValueReferenceUID:
474 m_compiler_type =
475 encoding_type->GetForwardCompilerType().GetLValueReferenceType();
476 break;
477
478 case eEncodingIsRValueReferenceUID:
479 m_compiler_type =
480 encoding_type->GetForwardCompilerType().GetRValueReferenceType();
481 break;
482
483 default:
484 llvm_unreachable("Unhandled encoding_data_type.");
485 }
486 } else {
487 // We have no encoding type, return void?
488 TypeSystem *type_system =
489 m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC);
490 CompilerType void_compiler_type =
491 type_system->GetBasicTypeFromAST(eBasicTypeVoid);
492 switch (m_encoding_uid_type) {
493 case eEncodingIsUID:
494 m_compiler_type = void_compiler_type;
495 break;
496
497 case eEncodingIsConstUID:
498 m_compiler_type = void_compiler_type.AddConstModifier();
499 break;
500
501 case eEncodingIsRestrictUID:
502 m_compiler_type = void_compiler_type.AddRestrictModifier();
503 break;
504
505 case eEncodingIsVolatileUID:
506 m_compiler_type = void_compiler_type.AddVolatileModifier();
507 break;
508
509 case eEncodingIsTypedefUID:
510 m_compiler_type = void_compiler_type.CreateTypedef(
511 m_name.AsCString("__lldb_invalid_typedef_name"),
512 GetSymbolFile()->GetDeclContextContainingUID(GetID()));
513 break;
514
515 case eEncodingIsPointerUID:
516 m_compiler_type = void_compiler_type.GetPointerType();
517 break;
518
519 case eEncodingIsLValueReferenceUID:
520 m_compiler_type = void_compiler_type.GetLValueReferenceType();
521 break;
522
523 case eEncodingIsRValueReferenceUID:
524 m_compiler_type = void_compiler_type.GetRValueReferenceType();
525 break;
526
527 default:
528 llvm_unreachable("Unhandled encoding_data_type.");
529 }
530 }
531
532 // When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is
533 // set to eResolveStateUnresolved so we need to update it to say that we
534 // now have a forward declaration since that is what we created above.
535 if (m_compiler_type.IsValid())
536 m_flags.compiler_type_resolve_state = eResolveStateForward;
537 }
538
539 // Check if we have a forward reference to a class/struct/union/enum?
540 if (compiler_type_resolve_state == eResolveStateLayout ||
541 compiler_type_resolve_state == eResolveStateFull) {
542 // Check if we have a forward reference to a class/struct/union/enum?
543 if (m_compiler_type.IsValid() &&
544 m_flags.compiler_type_resolve_state < compiler_type_resolve_state) {
545 m_flags.compiler_type_resolve_state = eResolveStateFull;
546 if (!m_compiler_type.IsDefined()) {
547 // We have a forward declaration, we need to resolve it to a complete
548 // definition.
549 m_symbol_file->CompleteType(m_compiler_type);
550 }
551 }
552 }
553
554 // If we have an encoding type, then we need to make sure it is resolved
555 // appropriately.
556 if (m_encoding_uid != LLDB_INVALID_UID) {
557 if (encoding_type == nullptr)
558 encoding_type = GetEncodingType();
559 if (encoding_type) {
560 ResolveState encoding_compiler_type_resolve_state =
561 compiler_type_resolve_state;
562
563 if (compiler_type_resolve_state == eResolveStateLayout) {
564 switch (m_encoding_uid_type) {
565 case eEncodingIsPointerUID:
566 case eEncodingIsLValueReferenceUID:
567 case eEncodingIsRValueReferenceUID:
568 encoding_compiler_type_resolve_state = eResolveStateForward;
569 break;
570 default:
571 break;
572 }
573 }
574 encoding_type->ResolveClangType(encoding_compiler_type_resolve_state);
575 }
576 }
577 return m_compiler_type.IsValid();
578 }
GetEncodingMask()579 uint32_t Type::GetEncodingMask() {
580 uint32_t encoding_mask = 1u << m_encoding_uid_type;
581 Type *encoding_type = GetEncodingType();
582 assert(encoding_type != this);
583 if (encoding_type)
584 encoding_mask |= encoding_type->GetEncodingMask();
585 return encoding_mask;
586 }
587
GetFullCompilerType()588 CompilerType Type::GetFullCompilerType() {
589 ResolveClangType(eResolveStateFull);
590 return m_compiler_type;
591 }
592
GetLayoutCompilerType()593 CompilerType Type::GetLayoutCompilerType() {
594 ResolveClangType(eResolveStateLayout);
595 return m_compiler_type;
596 }
597
GetForwardCompilerType()598 CompilerType Type::GetForwardCompilerType() {
599 ResolveClangType(eResolveStateForward);
600 return m_compiler_type;
601 }
602
Compare(const Type & a,const Type & b)603 int Type::Compare(const Type &a, const Type &b) {
604 // Just compare the UID values for now...
605 lldb::user_id_t a_uid = a.GetID();
606 lldb::user_id_t b_uid = b.GetID();
607 if (a_uid < b_uid)
608 return -1;
609 if (a_uid > b_uid)
610 return 1;
611 return 0;
612 }
613
GetQualifiedName()614 ConstString Type::GetQualifiedName() {
615 return GetForwardCompilerType().GetConstTypeName();
616 }
617
GetTypeScopeAndBasename(const llvm::StringRef & name,llvm::StringRef & scope,llvm::StringRef & basename,TypeClass & type_class)618 bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name,
619 llvm::StringRef &scope,
620 llvm::StringRef &basename,
621 TypeClass &type_class) {
622 type_class = eTypeClassAny;
623
624 if (name.empty())
625 return false;
626
627 basename = name;
628 if (basename.consume_front("struct "))
629 type_class = eTypeClassStruct;
630 else if (basename.consume_front("class "))
631 type_class = eTypeClassClass;
632 else if (basename.consume_front("union "))
633 type_class = eTypeClassUnion;
634 else if (basename.consume_front("enum "))
635 type_class = eTypeClassEnumeration;
636 else if (basename.consume_front("typedef "))
637 type_class = eTypeClassTypedef;
638
639 size_t namespace_separator = basename.find("::");
640 if (namespace_separator == llvm::StringRef::npos)
641 return false;
642
643 size_t template_begin = basename.find('<');
644 while (namespace_separator != llvm::StringRef::npos) {
645 if (template_begin != llvm::StringRef::npos &&
646 namespace_separator > template_begin) {
647 size_t template_depth = 1;
648 llvm::StringRef template_arg =
649 basename.drop_front(template_begin + 1);
650 while (template_depth > 0 && !template_arg.empty()) {
651 if (template_arg.front() == '<')
652 template_depth++;
653 else if (template_arg.front() == '>')
654 template_depth--;
655 template_arg = template_arg.drop_front(1);
656 }
657 if (template_depth != 0)
658 return false; // We have an invalid type name. Bail out.
659 if (template_arg.empty())
660 break; // The template ends at the end of the full name.
661 basename = template_arg;
662 } else {
663 basename = basename.drop_front(namespace_separator + 2);
664 }
665 template_begin = basename.find('<');
666 namespace_separator = basename.find("::");
667 }
668 if (basename.size() < name.size()) {
669 scope = name.take_front(name.size() - basename.size());
670 return true;
671 }
672 return false;
673 }
674
GetModule()675 ModuleSP Type::GetModule() {
676 if (m_symbol_file)
677 return m_symbol_file->GetObjectFile()->GetModule();
678 return ModuleSP();
679 }
680
TypeAndOrName()681 TypeAndOrName::TypeAndOrName() : m_type_pair(), m_type_name() {}
682
TypeAndOrName(TypeSP & in_type_sp)683 TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) : m_type_pair(in_type_sp) {
684 if (in_type_sp)
685 m_type_name = in_type_sp->GetName();
686 }
687
TypeAndOrName(const char * in_type_str)688 TypeAndOrName::TypeAndOrName(const char *in_type_str)
689 : m_type_name(in_type_str) {}
690
TypeAndOrName(const TypeAndOrName & rhs)691 TypeAndOrName::TypeAndOrName(const TypeAndOrName &rhs)
692 : m_type_pair(rhs.m_type_pair), m_type_name(rhs.m_type_name) {}
693
TypeAndOrName(ConstString & in_type_const_string)694 TypeAndOrName::TypeAndOrName(ConstString &in_type_const_string)
695 : m_type_name(in_type_const_string) {}
696
operator =(const TypeAndOrName & rhs)697 TypeAndOrName &TypeAndOrName::operator=(const TypeAndOrName &rhs) {
698 if (this != &rhs) {
699 m_type_name = rhs.m_type_name;
700 m_type_pair = rhs.m_type_pair;
701 }
702 return *this;
703 }
704
operator ==(const TypeAndOrName & other) const705 bool TypeAndOrName::operator==(const TypeAndOrName &other) const {
706 if (m_type_pair != other.m_type_pair)
707 return false;
708 if (m_type_name != other.m_type_name)
709 return false;
710 return true;
711 }
712
operator !=(const TypeAndOrName & other) const713 bool TypeAndOrName::operator!=(const TypeAndOrName &other) const {
714 return !(*this == other);
715 }
716
GetName() const717 ConstString TypeAndOrName::GetName() const {
718 if (m_type_name)
719 return m_type_name;
720 if (m_type_pair)
721 return m_type_pair.GetName();
722 return ConstString("<invalid>");
723 }
724
SetName(const ConstString & type_name)725 void TypeAndOrName::SetName(const ConstString &type_name) {
726 m_type_name = type_name;
727 }
728
SetName(const char * type_name_cstr)729 void TypeAndOrName::SetName(const char *type_name_cstr) {
730 m_type_name.SetCString(type_name_cstr);
731 }
732
SetTypeSP(lldb::TypeSP type_sp)733 void TypeAndOrName::SetTypeSP(lldb::TypeSP type_sp) {
734 m_type_pair.SetType(type_sp);
735 if (m_type_pair)
736 m_type_name = m_type_pair.GetName();
737 }
738
SetCompilerType(CompilerType compiler_type)739 void TypeAndOrName::SetCompilerType(CompilerType compiler_type) {
740 m_type_pair.SetType(compiler_type);
741 if (m_type_pair)
742 m_type_name = m_type_pair.GetName();
743 }
744
IsEmpty() const745 bool TypeAndOrName::IsEmpty() const {
746 return !((bool)m_type_name || (bool)m_type_pair);
747 }
748
Clear()749 void TypeAndOrName::Clear() {
750 m_type_name.Clear();
751 m_type_pair.Clear();
752 }
753
HasName() const754 bool TypeAndOrName::HasName() const { return (bool)m_type_name; }
755
HasTypeSP() const756 bool TypeAndOrName::HasTypeSP() const {
757 return m_type_pair.GetTypeSP().get() != nullptr;
758 }
759
HasCompilerType() const760 bool TypeAndOrName::HasCompilerType() const {
761 return m_type_pair.GetCompilerType().IsValid();
762 }
763
TypeImpl()764 TypeImpl::TypeImpl() : m_module_wp(), m_static_type(), m_dynamic_type() {}
765
TypeImpl(const TypeImpl & rhs)766 TypeImpl::TypeImpl(const TypeImpl &rhs)
767 : m_module_wp(rhs.m_module_wp), m_static_type(rhs.m_static_type),
768 m_dynamic_type(rhs.m_dynamic_type) {}
769
TypeImpl(const lldb::TypeSP & type_sp)770 TypeImpl::TypeImpl(const lldb::TypeSP &type_sp)
771 : m_module_wp(), m_static_type(), m_dynamic_type() {
772 SetType(type_sp);
773 }
774
TypeImpl(const CompilerType & compiler_type)775 TypeImpl::TypeImpl(const CompilerType &compiler_type)
776 : m_module_wp(), m_static_type(), m_dynamic_type() {
777 SetType(compiler_type);
778 }
779
TypeImpl(const lldb::TypeSP & type_sp,const CompilerType & dynamic)780 TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic)
781 : m_module_wp(), m_static_type(type_sp), m_dynamic_type(dynamic) {
782 SetType(type_sp, dynamic);
783 }
784
TypeImpl(const CompilerType & static_type,const CompilerType & dynamic_type)785 TypeImpl::TypeImpl(const CompilerType &static_type,
786 const CompilerType &dynamic_type)
787 : m_module_wp(), m_static_type(), m_dynamic_type() {
788 SetType(static_type, dynamic_type);
789 }
790
TypeImpl(const TypePair & pair,const CompilerType & dynamic)791 TypeImpl::TypeImpl(const TypePair &pair, const CompilerType &dynamic)
792 : m_module_wp(), m_static_type(), m_dynamic_type() {
793 SetType(pair, dynamic);
794 }
795
SetType(const lldb::TypeSP & type_sp)796 void TypeImpl::SetType(const lldb::TypeSP &type_sp) {
797 m_static_type.SetType(type_sp);
798 if (type_sp)
799 m_module_wp = type_sp->GetModule();
800 else
801 m_module_wp = lldb::ModuleWP();
802 }
803
SetType(const CompilerType & compiler_type)804 void TypeImpl::SetType(const CompilerType &compiler_type) {
805 m_module_wp = lldb::ModuleWP();
806 m_static_type.SetType(compiler_type);
807 }
808
SetType(const lldb::TypeSP & type_sp,const CompilerType & dynamic)809 void TypeImpl::SetType(const lldb::TypeSP &type_sp,
810 const CompilerType &dynamic) {
811 SetType(type_sp);
812 m_dynamic_type = dynamic;
813 }
814
SetType(const CompilerType & compiler_type,const CompilerType & dynamic)815 void TypeImpl::SetType(const CompilerType &compiler_type,
816 const CompilerType &dynamic) {
817 m_module_wp = lldb::ModuleWP();
818 m_static_type.SetType(compiler_type);
819 m_dynamic_type = dynamic;
820 }
821
SetType(const TypePair & pair,const CompilerType & dynamic)822 void TypeImpl::SetType(const TypePair &pair, const CompilerType &dynamic) {
823 m_module_wp = pair.GetModule();
824 m_static_type = pair;
825 m_dynamic_type = dynamic;
826 }
827
operator =(const TypeImpl & rhs)828 TypeImpl &TypeImpl::operator=(const TypeImpl &rhs) {
829 if (rhs != *this) {
830 m_module_wp = rhs.m_module_wp;
831 m_static_type = rhs.m_static_type;
832 m_dynamic_type = rhs.m_dynamic_type;
833 }
834 return *this;
835 }
836
CheckModule(lldb::ModuleSP & module_sp) const837 bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {
838 // Check if we have a module for this type. If we do and the shared pointer
839 // is can be successfully initialized with m_module_wp, return true. Else
840 // return false if we didn't have a module, or if we had a module and it has
841 // been deleted. Any functions doing anything with a TypeSP in this TypeImpl
842 // class should call this function and only do anything with the ivars if
843 // this function returns true. If we have a module, the "module_sp" will be
844 // filled in with a strong reference to the module so that the module will at
845 // least stay around long enough for the type query to succeed.
846 module_sp = m_module_wp.lock();
847 if (!module_sp) {
848 lldb::ModuleWP empty_module_wp;
849 // If either call to "std::weak_ptr::owner_before(...) value returns true,
850 // this indicates that m_module_wp once contained (possibly still does) a
851 // reference to a valid shared pointer. This helps us know if we had a
852 // valid reference to a section which is now invalid because the module it
853 // was in was deleted
854 if (empty_module_wp.owner_before(m_module_wp) ||
855 m_module_wp.owner_before(empty_module_wp)) {
856 // m_module_wp had a valid reference to a module, but all strong
857 // references have been released and the module has been deleted
858 return false;
859 }
860 }
861 // We either successfully locked the module, or didn't have one to begin with
862 return true;
863 }
864
operator ==(const TypeImpl & rhs) const865 bool TypeImpl::operator==(const TypeImpl &rhs) const {
866 return m_static_type == rhs.m_static_type &&
867 m_dynamic_type == rhs.m_dynamic_type;
868 }
869
operator !=(const TypeImpl & rhs) const870 bool TypeImpl::operator!=(const TypeImpl &rhs) const {
871 return !(*this == rhs);
872 }
873
IsValid() const874 bool TypeImpl::IsValid() const {
875 // just a name is not valid
876 ModuleSP module_sp;
877 if (CheckModule(module_sp))
878 return m_static_type.IsValid() || m_dynamic_type.IsValid();
879 return false;
880 }
881
operator bool() const882 TypeImpl::operator bool() const { return IsValid(); }
883
Clear()884 void TypeImpl::Clear() {
885 m_module_wp = lldb::ModuleWP();
886 m_static_type.Clear();
887 m_dynamic_type.Clear();
888 }
889
GetName() const890 ConstString TypeImpl::GetName() const {
891 ModuleSP module_sp;
892 if (CheckModule(module_sp)) {
893 if (m_dynamic_type)
894 return m_dynamic_type.GetTypeName();
895 return m_static_type.GetName();
896 }
897 return ConstString();
898 }
899
GetDisplayTypeName() const900 ConstString TypeImpl::GetDisplayTypeName() const {
901 ModuleSP module_sp;
902 if (CheckModule(module_sp)) {
903 if (m_dynamic_type)
904 return m_dynamic_type.GetDisplayTypeName();
905 return m_static_type.GetDisplayTypeName();
906 }
907 return ConstString();
908 }
909
GetPointerType() const910 TypeImpl TypeImpl::GetPointerType() const {
911 ModuleSP module_sp;
912 if (CheckModule(module_sp)) {
913 if (m_dynamic_type.IsValid()) {
914 return TypeImpl(m_static_type.GetPointerType(),
915 m_dynamic_type.GetPointerType());
916 }
917 return TypeImpl(m_static_type.GetPointerType());
918 }
919 return TypeImpl();
920 }
921
GetPointeeType() const922 TypeImpl TypeImpl::GetPointeeType() const {
923 ModuleSP module_sp;
924 if (CheckModule(module_sp)) {
925 if (m_dynamic_type.IsValid()) {
926 return TypeImpl(m_static_type.GetPointeeType(),
927 m_dynamic_type.GetPointeeType());
928 }
929 return TypeImpl(m_static_type.GetPointeeType());
930 }
931 return TypeImpl();
932 }
933
GetReferenceType() const934 TypeImpl TypeImpl::GetReferenceType() const {
935 ModuleSP module_sp;
936 if (CheckModule(module_sp)) {
937 if (m_dynamic_type.IsValid()) {
938 return TypeImpl(m_static_type.GetReferenceType(),
939 m_dynamic_type.GetLValueReferenceType());
940 }
941 return TypeImpl(m_static_type.GetReferenceType());
942 }
943 return TypeImpl();
944 }
945
GetTypedefedType() const946 TypeImpl TypeImpl::GetTypedefedType() const {
947 ModuleSP module_sp;
948 if (CheckModule(module_sp)) {
949 if (m_dynamic_type.IsValid()) {
950 return TypeImpl(m_static_type.GetTypedefedType(),
951 m_dynamic_type.GetTypedefedType());
952 }
953 return TypeImpl(m_static_type.GetTypedefedType());
954 }
955 return TypeImpl();
956 }
957
GetDereferencedType() const958 TypeImpl TypeImpl::GetDereferencedType() const {
959 ModuleSP module_sp;
960 if (CheckModule(module_sp)) {
961 if (m_dynamic_type.IsValid()) {
962 return TypeImpl(m_static_type.GetDereferencedType(),
963 m_dynamic_type.GetNonReferenceType());
964 }
965 return TypeImpl(m_static_type.GetDereferencedType());
966 }
967 return TypeImpl();
968 }
969
GetUnqualifiedType() const970 TypeImpl TypeImpl::GetUnqualifiedType() const {
971 ModuleSP module_sp;
972 if (CheckModule(module_sp)) {
973 if (m_dynamic_type.IsValid()) {
974 return TypeImpl(m_static_type.GetUnqualifiedType(),
975 m_dynamic_type.GetFullyUnqualifiedType());
976 }
977 return TypeImpl(m_static_type.GetUnqualifiedType());
978 }
979 return TypeImpl();
980 }
981
GetCanonicalType() const982 TypeImpl TypeImpl::GetCanonicalType() const {
983 ModuleSP module_sp;
984 if (CheckModule(module_sp)) {
985 if (m_dynamic_type.IsValid()) {
986 return TypeImpl(m_static_type.GetCanonicalType(),
987 m_dynamic_type.GetCanonicalType());
988 }
989 return TypeImpl(m_static_type.GetCanonicalType());
990 }
991 return TypeImpl();
992 }
993
GetCompilerType(bool prefer_dynamic)994 CompilerType TypeImpl::GetCompilerType(bool prefer_dynamic) {
995 ModuleSP module_sp;
996 if (CheckModule(module_sp)) {
997 if (prefer_dynamic) {
998 if (m_dynamic_type.IsValid())
999 return m_dynamic_type;
1000 }
1001 return m_static_type.GetCompilerType();
1002 }
1003 return CompilerType();
1004 }
1005
GetTypeSystem(bool prefer_dynamic)1006 TypeSystem *TypeImpl::GetTypeSystem(bool prefer_dynamic) {
1007 ModuleSP module_sp;
1008 if (CheckModule(module_sp)) {
1009 if (prefer_dynamic) {
1010 if (m_dynamic_type.IsValid())
1011 return m_dynamic_type.GetTypeSystem();
1012 }
1013 return m_static_type.GetCompilerType().GetTypeSystem();
1014 }
1015 return NULL;
1016 }
1017
GetDescription(lldb_private::Stream & strm,lldb::DescriptionLevel description_level)1018 bool TypeImpl::GetDescription(lldb_private::Stream &strm,
1019 lldb::DescriptionLevel description_level) {
1020 ModuleSP module_sp;
1021 if (CheckModule(module_sp)) {
1022 if (m_dynamic_type.IsValid()) {
1023 strm.Printf("Dynamic:\n");
1024 m_dynamic_type.DumpTypeDescription(&strm);
1025 strm.Printf("\nStatic:\n");
1026 }
1027 m_static_type.GetCompilerType().DumpTypeDescription(&strm);
1028 } else {
1029 strm.PutCString("Invalid TypeImpl module for type has been deleted\n");
1030 }
1031 return true;
1032 }
1033
IsValid()1034 bool TypeMemberFunctionImpl::IsValid() {
1035 return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;
1036 }
1037
GetName() const1038 ConstString TypeMemberFunctionImpl::GetName() const { return m_name; }
1039
GetMangledName() const1040 ConstString TypeMemberFunctionImpl::GetMangledName() const {
1041 return m_decl.GetMangledName();
1042 }
1043
GetType() const1044 CompilerType TypeMemberFunctionImpl::GetType() const { return m_type; }
1045
GetKind() const1046 lldb::MemberFunctionKind TypeMemberFunctionImpl::GetKind() const {
1047 return m_kind;
1048 }
1049
GetDescription(Stream & stream)1050 bool TypeMemberFunctionImpl::GetDescription(Stream &stream) {
1051 switch (m_kind) {
1052 case lldb::eMemberFunctionKindUnknown:
1053 return false;
1054 case lldb::eMemberFunctionKindConstructor:
1055 stream.Printf("constructor for %s",
1056 m_type.GetTypeName().AsCString("<unknown>"));
1057 break;
1058 case lldb::eMemberFunctionKindDestructor:
1059 stream.Printf("destructor for %s",
1060 m_type.GetTypeName().AsCString("<unknown>"));
1061 break;
1062 case lldb::eMemberFunctionKindInstanceMethod:
1063 stream.Printf("instance method %s of type %s", m_name.AsCString(),
1064 m_decl.GetDeclContext().GetName().AsCString());
1065 break;
1066 case lldb::eMemberFunctionKindStaticMethod:
1067 stream.Printf("static method %s of type %s", m_name.AsCString(),
1068 m_decl.GetDeclContext().GetName().AsCString());
1069 break;
1070 }
1071 return true;
1072 }
1073
GetReturnType() const1074 CompilerType TypeMemberFunctionImpl::GetReturnType() const {
1075 if (m_type)
1076 return m_type.GetFunctionReturnType();
1077 return m_decl.GetFunctionReturnType();
1078 }
1079
GetNumArguments() const1080 size_t TypeMemberFunctionImpl::GetNumArguments() const {
1081 if (m_type)
1082 return m_type.GetNumberOfFunctionArguments();
1083 else
1084 return m_decl.GetNumFunctionArguments();
1085 }
1086
GetArgumentAtIndex(size_t idx) const1087 CompilerType TypeMemberFunctionImpl::GetArgumentAtIndex(size_t idx) const {
1088 if (m_type)
1089 return m_type.GetFunctionArgumentAtIndex(idx);
1090 else
1091 return m_decl.GetFunctionArgumentType(idx);
1092 }
1093
TypeEnumMemberImpl(const lldb::TypeImplSP & integer_type_sp,const ConstString & name,const llvm::APSInt & value)1094 TypeEnumMemberImpl::TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp,
1095 const ConstString &name,
1096 const llvm::APSInt &value)
1097 : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value),
1098 m_valid((bool)name && (bool)integer_type_sp)
1099
1100 {}
1101