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