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