//===-- Type.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <stdio.h>

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"

#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeSystem.h"

#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

#include "llvm/ADT/StringRef.h"

#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"

using namespace lldb;
using namespace lldb_private;

void CompilerContext::Dump() const {
  switch (type) {
  case CompilerContextKind::Invalid:
    printf("Invalid");
    break;
  case CompilerContextKind::TranslationUnit:
    printf("TranslationUnit");
    break;
  case CompilerContextKind::Module:
    printf("Module");
    break;
  case CompilerContextKind::Namespace:
    printf("Namespace");
    break;
  case CompilerContextKind::Class:
    printf("Class");
    break;
  case CompilerContextKind::Structure:
    printf("Structure");
    break;
  case CompilerContextKind::Union:
    printf("Union");
    break;
  case CompilerContextKind::Function:
    printf("Function");
    break;
  case CompilerContextKind::Variable:
    printf("Variable");
    break;
  case CompilerContextKind::Enumeration:
    printf("Enumeration");
    break;
  case CompilerContextKind::Typedef:
    printf("Typedef");
    break;
  }
  printf("(\"%s\")\n", name.GetCString());
}

class TypeAppendVisitor {
public:
  TypeAppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}

  bool operator()(const lldb::TypeSP &type) {
    m_type_list.Append(TypeImplSP(new TypeImpl(type)));
    return true;
  }

private:
  TypeListImpl &m_type_list;
};

void TypeListImpl::Append(const lldb_private::TypeList &type_list) {
  TypeAppendVisitor cb(*this);
  type_list.ForEach(cb);
}

SymbolFileType::SymbolFileType(SymbolFile &symbol_file,
                               const lldb::TypeSP &type_sp)
    : UserID(type_sp ? type_sp->GetID() : LLDB_INVALID_UID),
      m_symbol_file(symbol_file), m_type_sp(type_sp) {}

Type *SymbolFileType::GetType() {
  if (!m_type_sp) {
    Type *resolved_type = m_symbol_file.ResolveTypeUID(GetID());
    if (resolved_type)
      m_type_sp = resolved_type->shared_from_this();
  }
  return m_type_sp.get();
}

Type::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)
    : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name),
      m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr),
      m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type),
      m_byte_size(byte_size), m_decl(decl), m_compiler_type(compiler_type) {
  m_flags.compiler_type_resolve_state =
      (compiler_type ? compiler_type_resolve_state : eResolveStateUnresolved);
  m_flags.is_complete_objc_class = false;
}

Type::Type()
    : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"),
      m_symbol_file(nullptr), m_context(nullptr), m_encoding_type(nullptr),
      m_encoding_uid(LLDB_INVALID_UID), m_encoding_uid_type(eEncodingInvalid),
      m_byte_size(0), m_decl(), m_compiler_type() {
  m_flags.compiler_type_resolve_state = eResolveStateUnresolved;
  m_flags.is_complete_objc_class = false;
}

Type::Type(const Type &rhs)
    : std::enable_shared_from_this<Type>(rhs), UserID(rhs), m_name(rhs.m_name),
      m_symbol_file(rhs.m_symbol_file), m_context(rhs.m_context),
      m_encoding_type(rhs.m_encoding_type), m_encoding_uid(rhs.m_encoding_uid),
      m_encoding_uid_type(rhs.m_encoding_uid_type),
      m_byte_size(rhs.m_byte_size), m_decl(rhs.m_decl),
      m_compiler_type(rhs.m_compiler_type), m_flags(rhs.m_flags) {}

const Type &Type::operator=(const Type &rhs) {
  if (this != &rhs) {
  }
  return *this;
}

void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
                          bool show_name) {
  *s << "id = " << (const UserID &)*this;

  // Call the name accessor to make sure we resolve the type name
  if (show_name) {
    const ConstString &type_name = GetName();
    if (type_name) {
      *s << ", name = \"" << type_name << '"';
      ConstString qualified_type_name(GetQualifiedName());
      if (qualified_type_name != type_name) {
        *s << ", qualified = \"" << qualified_type_name << '"';
      }
    }
  }

  // Call the get byte size accesor so we resolve our byte size
  if (GetByteSize())
    s->Printf(", byte-size = %" PRIu64, m_byte_size);
  bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
  m_decl.Dump(s, show_fullpaths);

  if (m_compiler_type.IsValid()) {
    *s << ", compiler_type = \"";
    GetForwardCompilerType().DumpTypeDescription(s);
    *s << '"';
  } else if (m_encoding_uid != LLDB_INVALID_UID) {
    s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
    switch (m_encoding_uid_type) {
    case eEncodingInvalid:
      break;
    case eEncodingIsUID:
      s->PutCString(" (unresolved type)");
      break;
    case eEncodingIsConstUID:
      s->PutCString(" (unresolved const type)");
      break;
    case eEncodingIsRestrictUID:
      s->PutCString(" (unresolved restrict type)");
      break;
    case eEncodingIsVolatileUID:
      s->PutCString(" (unresolved volatile type)");
      break;
    case eEncodingIsTypedefUID:
      s->PutCString(" (unresolved typedef)");
      break;
    case eEncodingIsPointerUID:
      s->PutCString(" (unresolved pointer)");
      break;
    case eEncodingIsLValueReferenceUID:
      s->PutCString(" (unresolved L value reference)");
      break;
    case eEncodingIsRValueReferenceUID:
      s->PutCString(" (unresolved R value reference)");
      break;
    case eEncodingIsSyntheticUID:
      s->PutCString(" (synthetic type)");
      break;
    }
  }
}

void Type::Dump(Stream *s, bool show_context) {
  s->Printf("%p: ", static_cast<void *>(this));
  s->Indent();
  *s << "Type" << static_cast<const UserID &>(*this) << ' ';
  if (m_name)
    *s << ", name = \"" << m_name << "\"";

  if (m_byte_size != 0)
    s->Printf(", size = %" PRIu64, m_byte_size);

  if (show_context && m_context != nullptr) {
    s->PutCString(", context = ( ");
    m_context->DumpSymbolContext(s);
    s->PutCString(" )");
  }

  bool show_fullpaths = false;
  m_decl.Dump(s, show_fullpaths);

  if (m_compiler_type.IsValid()) {
    *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' ';
    GetForwardCompilerType().DumpTypeDescription(s);
  } else if (m_encoding_uid != LLDB_INVALID_UID) {
    *s << ", type_data = " << (uint64_t)m_encoding_uid;
    switch (m_encoding_uid_type) {
    case eEncodingInvalid:
      break;
    case eEncodingIsUID:
      s->PutCString(" (unresolved type)");
      break;
    case eEncodingIsConstUID:
      s->PutCString(" (unresolved const type)");
      break;
    case eEncodingIsRestrictUID:
      s->PutCString(" (unresolved restrict type)");
      break;
    case eEncodingIsVolatileUID:
      s->PutCString(" (unresolved volatile type)");
      break;
    case eEncodingIsTypedefUID:
      s->PutCString(" (unresolved typedef)");
      break;
    case eEncodingIsPointerUID:
      s->PutCString(" (unresolved pointer)");
      break;
    case eEncodingIsLValueReferenceUID:
      s->PutCString(" (unresolved L value reference)");
      break;
    case eEncodingIsRValueReferenceUID:
      s->PutCString(" (unresolved R value reference)");
      break;
    case eEncodingIsSyntheticUID:
      s->PutCString(" (synthetic type)");
      break;
    }
  }

  //
  //  if (m_access)
  //      s->Printf(", access = %u", m_access);
  s->EOL();
}

const ConstString &Type::GetName() {
  if (!m_name)
    m_name = GetForwardCompilerType().GetConstTypeName();
  return m_name;
}

void Type::DumpTypeName(Stream *s) { GetName().Dump(s, "<invalid-type-name>"); }

void Type::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) {
  if (ResolveClangType(eResolveStateForward)) {
    if (show_types) {
      s->PutChar('(');
      if (verbose)
        s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
      DumpTypeName(s);
      s->PutCString(") ");
    }

    GetForwardCompilerType().DumpValue(
        exe_ctx, s, format == lldb::eFormatDefault ? GetFormat() : format, data,
        data_byte_offset, GetByteSize(),
        0, // Bitfield bit size
        0, // Bitfield bit offset
        show_types, show_summary, verbose, 0);
  }
}

Type *Type::GetEncodingType() {
  if (m_encoding_type == nullptr && m_encoding_uid != LLDB_INVALID_UID)
    m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
  return m_encoding_type;
}

uint64_t Type::GetByteSize() {
  if (m_byte_size == 0) {
    switch (m_encoding_uid_type) {
    case eEncodingInvalid:
    case eEncodingIsSyntheticUID:
      break;
    case eEncodingIsUID:
    case eEncodingIsConstUID:
    case eEncodingIsRestrictUID:
    case eEncodingIsVolatileUID:
    case eEncodingIsTypedefUID: {
      Type *encoding_type = GetEncodingType();
      if (encoding_type)
        m_byte_size = encoding_type->GetByteSize();
      if (m_byte_size == 0)
        m_byte_size = GetLayoutCompilerType().GetByteSize(nullptr);
    } break;

    // If we are a pointer or reference, then this is just a pointer size;
    case eEncodingIsPointerUID:
    case eEncodingIsLValueReferenceUID:
    case eEncodingIsRValueReferenceUID: {
      ArchSpec arch;
      if (m_symbol_file->GetObjectFile()->GetArchitecture(arch))
        m_byte_size = arch.GetAddressByteSize();
    } break;
    }
  }
  return m_byte_size;
}

uint32_t Type::GetNumChildren(bool omit_empty_base_classes) {
  return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes);
}

bool Type::IsAggregateType() {
  return GetForwardCompilerType().IsAggregateType();
}

lldb::TypeSP Type::GetTypedefType() {
  lldb::TypeSP type_sp;
  if (IsTypedef()) {
    Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
    if (typedef_type)
      type_sp = typedef_type->shared_from_this();
  }
  return type_sp;
}

lldb::Format Type::GetFormat() { return GetForwardCompilerType().GetFormat(); }

lldb::Encoding Type::GetEncoding(uint64_t &count) {
  // Make sure we resolve our type if it already hasn't been.
  return GetForwardCompilerType().GetEncoding(count);
}

bool Type::DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s,
                             lldb::addr_t address, AddressType address_type,
                             bool show_types, bool show_summary, bool verbose) {
  if (address != LLDB_INVALID_ADDRESS) {
    DataExtractor data;
    Target *target = nullptr;
    if (exe_ctx)
      target = exe_ctx->GetTargetPtr();
    if (target)
      data.SetByteOrder(target->GetArchitecture().GetByteOrder());
    if (ReadFromMemory(exe_ctx, address, address_type, data)) {
      DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
      return true;
    }
  }
  return false;
}

bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
                          AddressType address_type, DataExtractor &data) {
  if (address_type == eAddressTypeFile) {
    // Can't convert a file address to anything valid without more context
    // (which Module it came from)
    return false;
  }

  const uint64_t byte_size = GetByteSize();
  if (data.GetByteSize() < byte_size) {
    lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0'));
    data.SetData(data_sp);
  }

  uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
  if (dst != nullptr) {
    if (address_type == eAddressTypeHost) {
      // The address is an address in this process, so just copy it
      if (addr == 0)
        return false;
      memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size);
      return true;
    } else {
      if (exe_ctx) {
        Process *process = exe_ctx->GetProcessPtr();
        if (process) {
          Status error;
          return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size,
                                                      error) == byte_size;
        }
      }
    }
  }
  return false;
}

bool Type::WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
                         AddressType address_type, DataExtractor &data) {
  return false;
}

TypeList *Type::GetTypeList() { return GetSymbolFile()->GetTypeList(); }

const Declaration &Type::GetDeclaration() const { return m_decl; }

bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) {
  // TODO: This needs to consider the correct type system to use.
  Type *encoding_type = nullptr;
  if (!m_compiler_type.IsValid()) {
    encoding_type = GetEncodingType();
    if (encoding_type) {
      switch (m_encoding_uid_type) {
      case eEncodingIsUID: {
        CompilerType encoding_compiler_type =
            encoding_type->GetForwardCompilerType();
        if (encoding_compiler_type.IsValid()) {
          m_compiler_type = encoding_compiler_type;
          m_flags.compiler_type_resolve_state =
              encoding_type->m_flags.compiler_type_resolve_state;
        }
      } break;

      case eEncodingIsConstUID:
        m_compiler_type =
            encoding_type->GetForwardCompilerType().AddConstModifier();
        break;

      case eEncodingIsRestrictUID:
        m_compiler_type =
            encoding_type->GetForwardCompilerType().AddRestrictModifier();
        break;

      case eEncodingIsVolatileUID:
        m_compiler_type =
            encoding_type->GetForwardCompilerType().AddVolatileModifier();
        break;

      case eEncodingIsTypedefUID:
        m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef(
            m_name.AsCString("__lldb_invalid_typedef_name"),
            GetSymbolFile()->GetDeclContextContainingUID(GetID()));
        m_name.Clear();
        break;

      case eEncodingIsPointerUID:
        m_compiler_type =
            encoding_type->GetForwardCompilerType().GetPointerType();
        break;

      case eEncodingIsLValueReferenceUID:
        m_compiler_type =
            encoding_type->GetForwardCompilerType().GetLValueReferenceType();
        break;

      case eEncodingIsRValueReferenceUID:
        m_compiler_type =
            encoding_type->GetForwardCompilerType().GetRValueReferenceType();
        break;

      default:
        llvm_unreachable("Unhandled encoding_data_type.");
      }
    } else {
      // We have no encoding type, return void?
      TypeSystem *type_system =
          m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC);
      CompilerType void_compiler_type =
          type_system->GetBasicTypeFromAST(eBasicTypeVoid);
      switch (m_encoding_uid_type) {
      case eEncodingIsUID:
        m_compiler_type = void_compiler_type;
        break;

      case eEncodingIsConstUID:
        m_compiler_type = void_compiler_type.AddConstModifier();
        break;

      case eEncodingIsRestrictUID:
        m_compiler_type = void_compiler_type.AddRestrictModifier();
        break;

      case eEncodingIsVolatileUID:
        m_compiler_type = void_compiler_type.AddVolatileModifier();
        break;

      case eEncodingIsTypedefUID:
        m_compiler_type = void_compiler_type.CreateTypedef(
            m_name.AsCString("__lldb_invalid_typedef_name"),
            GetSymbolFile()->GetDeclContextContainingUID(GetID()));
        break;

      case eEncodingIsPointerUID:
        m_compiler_type = void_compiler_type.GetPointerType();
        break;

      case eEncodingIsLValueReferenceUID:
        m_compiler_type = void_compiler_type.GetLValueReferenceType();
        break;

      case eEncodingIsRValueReferenceUID:
        m_compiler_type = void_compiler_type.GetRValueReferenceType();
        break;

      default:
        llvm_unreachable("Unhandled encoding_data_type.");
      }
    }

    // When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is
    // set to eResolveStateUnresolved so we need to update it to say that we
    // now have a forward declaration since that is what we created above.
    if (m_compiler_type.IsValid())
      m_flags.compiler_type_resolve_state = eResolveStateForward;
  }

  // Check if we have a forward reference to a class/struct/union/enum?
  if (compiler_type_resolve_state == eResolveStateLayout ||
      compiler_type_resolve_state == eResolveStateFull) {
    // Check if we have a forward reference to a class/struct/union/enum?
    if (m_compiler_type.IsValid() &&
        m_flags.compiler_type_resolve_state < compiler_type_resolve_state) {
      m_flags.compiler_type_resolve_state = eResolveStateFull;
      if (!m_compiler_type.IsDefined()) {
        // We have a forward declaration, we need to resolve it to a complete
        // definition.
        m_symbol_file->CompleteType(m_compiler_type);
      }
    }
  }

  // If we have an encoding type, then we need to make sure it is resolved
  // appropriately.
  if (m_encoding_uid != LLDB_INVALID_UID) {
    if (encoding_type == nullptr)
      encoding_type = GetEncodingType();
    if (encoding_type) {
      ResolveState encoding_compiler_type_resolve_state =
          compiler_type_resolve_state;

      if (compiler_type_resolve_state == eResolveStateLayout) {
        switch (m_encoding_uid_type) {
        case eEncodingIsPointerUID:
        case eEncodingIsLValueReferenceUID:
        case eEncodingIsRValueReferenceUID:
          encoding_compiler_type_resolve_state = eResolveStateForward;
          break;
        default:
          break;
        }
      }
      encoding_type->ResolveClangType(encoding_compiler_type_resolve_state);
    }
  }
  return m_compiler_type.IsValid();
}
uint32_t Type::GetEncodingMask() {
  uint32_t encoding_mask = 1u << m_encoding_uid_type;
  Type *encoding_type = GetEncodingType();
  assert(encoding_type != this);
  if (encoding_type)
    encoding_mask |= encoding_type->GetEncodingMask();
  return encoding_mask;
}

CompilerType Type::GetFullCompilerType() {
  ResolveClangType(eResolveStateFull);
  return m_compiler_type;
}

CompilerType Type::GetLayoutCompilerType() {
  ResolveClangType(eResolveStateLayout);
  return m_compiler_type;
}

CompilerType Type::GetForwardCompilerType() {
  ResolveClangType(eResolveStateForward);
  return m_compiler_type;
}

int Type::Compare(const Type &a, const Type &b) {
  // Just compare the UID values for now...
  lldb::user_id_t a_uid = a.GetID();
  lldb::user_id_t b_uid = b.GetID();
  if (a_uid < b_uid)
    return -1;
  if (a_uid > b_uid)
    return 1;
  return 0;
}

ConstString Type::GetQualifiedName() {
  return GetForwardCompilerType().GetConstTypeName();
}

bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name,
                                   llvm::StringRef &scope,
                                   llvm::StringRef &basename,
                                   TypeClass &type_class) {
  type_class = eTypeClassAny;

  if (name.empty())
    return false;

  basename = name;
  if (basename.consume_front("struct "))
    type_class = eTypeClassStruct;
  else if (basename.consume_front("class "))
    type_class = eTypeClassClass;
  else if (basename.consume_front("union "))
    type_class = eTypeClassUnion;
  else if (basename.consume_front("enum "))
    type_class = eTypeClassEnumeration;
  else if (basename.consume_front("typedef "))
    type_class = eTypeClassTypedef;

  size_t namespace_separator = basename.find("::");
  if (namespace_separator == llvm::StringRef::npos)
    return false;

  size_t template_begin = basename.find('<');
  while (namespace_separator != llvm::StringRef::npos) {
    if (template_begin != llvm::StringRef::npos &&
        namespace_separator > template_begin) {
      size_t template_depth = 1;
      llvm::StringRef template_arg =
          basename.drop_front(template_begin + 1);
      while (template_depth > 0 && !template_arg.empty()) {
        if (template_arg.front() == '<')
          template_depth++;
        else if (template_arg.front() == '>')
          template_depth--;
        template_arg = template_arg.drop_front(1);
      }
      if (template_depth != 0)
        return false; // We have an invalid type name. Bail out.
      if (template_arg.empty())
        break; // The template ends at the end of the full name.
      basename = template_arg;
    } else {
      basename = basename.drop_front(namespace_separator + 2);
    }
    template_begin = basename.find('<');
    namespace_separator = basename.find("::");
  }
  if (basename.size() < name.size()) {
    scope = name.take_front(name.size() - basename.size());
    return true;
  }
  return false;
}

ModuleSP Type::GetModule() {
  if (m_symbol_file)
    return m_symbol_file->GetObjectFile()->GetModule();
  return ModuleSP();
}

TypeAndOrName::TypeAndOrName() : m_type_pair(), m_type_name() {}

TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) : m_type_pair(in_type_sp) {
  if (in_type_sp)
    m_type_name = in_type_sp->GetName();
}

TypeAndOrName::TypeAndOrName(const char *in_type_str)
    : m_type_name(in_type_str) {}

TypeAndOrName::TypeAndOrName(const TypeAndOrName &rhs)
    : m_type_pair(rhs.m_type_pair), m_type_name(rhs.m_type_name) {}

TypeAndOrName::TypeAndOrName(ConstString &in_type_const_string)
    : m_type_name(in_type_const_string) {}

TypeAndOrName &TypeAndOrName::operator=(const TypeAndOrName &rhs) {
  if (this != &rhs) {
    m_type_name = rhs.m_type_name;
    m_type_pair = rhs.m_type_pair;
  }
  return *this;
}

bool TypeAndOrName::operator==(const TypeAndOrName &other) const {
  if (m_type_pair != other.m_type_pair)
    return false;
  if (m_type_name != other.m_type_name)
    return false;
  return true;
}

bool TypeAndOrName::operator!=(const TypeAndOrName &other) const {
  if (m_type_pair != other.m_type_pair)
    return true;
  if (m_type_name != other.m_type_name)
    return true;
  return false;
}

ConstString TypeAndOrName::GetName() const {
  if (m_type_name)
    return m_type_name;
  if (m_type_pair)
    return m_type_pair.GetName();
  return ConstString("<invalid>");
}

void TypeAndOrName::SetName(const ConstString &type_name) {
  m_type_name = type_name;
}

void TypeAndOrName::SetName(const char *type_name_cstr) {
  m_type_name.SetCString(type_name_cstr);
}

void TypeAndOrName::SetTypeSP(lldb::TypeSP type_sp) {
  m_type_pair.SetType(type_sp);
  if (m_type_pair)
    m_type_name = m_type_pair.GetName();
}

void TypeAndOrName::SetCompilerType(CompilerType compiler_type) {
  m_type_pair.SetType(compiler_type);
  if (m_type_pair)
    m_type_name = m_type_pair.GetName();
}

bool TypeAndOrName::IsEmpty() const {
  if ((bool)m_type_name || (bool)m_type_pair)
    return false;
  else
    return true;
}

void TypeAndOrName::Clear() {
  m_type_name.Clear();
  m_type_pair.Clear();
}

bool TypeAndOrName::HasName() const { return (bool)m_type_name; }

bool TypeAndOrName::HasTypeSP() const {
  return m_type_pair.GetTypeSP().get() != nullptr;
}

bool TypeAndOrName::HasCompilerType() const {
  return m_type_pair.GetCompilerType().IsValid();
}

TypeImpl::TypeImpl() : m_module_wp(), m_static_type(), m_dynamic_type() {}

TypeImpl::TypeImpl(const TypeImpl &rhs)
    : m_module_wp(rhs.m_module_wp), m_static_type(rhs.m_static_type),
      m_dynamic_type(rhs.m_dynamic_type) {}

TypeImpl::TypeImpl(const lldb::TypeSP &type_sp)
    : m_module_wp(), m_static_type(), m_dynamic_type() {
  SetType(type_sp);
}

TypeImpl::TypeImpl(const CompilerType &compiler_type)
    : m_module_wp(), m_static_type(), m_dynamic_type() {
  SetType(compiler_type);
}

TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic)
    : m_module_wp(), m_static_type(type_sp), m_dynamic_type(dynamic) {
  SetType(type_sp, dynamic);
}

TypeImpl::TypeImpl(const CompilerType &static_type,
                   const CompilerType &dynamic_type)
    : m_module_wp(), m_static_type(), m_dynamic_type() {
  SetType(static_type, dynamic_type);
}

TypeImpl::TypeImpl(const TypePair &pair, const CompilerType &dynamic)
    : m_module_wp(), m_static_type(), m_dynamic_type() {
  SetType(pair, dynamic);
}

void TypeImpl::SetType(const lldb::TypeSP &type_sp) {
  m_static_type.SetType(type_sp);
  if (type_sp)
    m_module_wp = type_sp->GetModule();
  else
    m_module_wp = lldb::ModuleWP();
}

void TypeImpl::SetType(const CompilerType &compiler_type) {
  m_module_wp = lldb::ModuleWP();
  m_static_type.SetType(compiler_type);
}

void TypeImpl::SetType(const lldb::TypeSP &type_sp,
                       const CompilerType &dynamic) {
  SetType(type_sp);
  m_dynamic_type = dynamic;
}

void TypeImpl::SetType(const CompilerType &compiler_type,
                       const CompilerType &dynamic) {
  m_module_wp = lldb::ModuleWP();
  m_static_type.SetType(compiler_type);
  m_dynamic_type = dynamic;
}

void TypeImpl::SetType(const TypePair &pair, const CompilerType &dynamic) {
  m_module_wp = pair.GetModule();
  m_static_type = pair;
  m_dynamic_type = dynamic;
}

TypeImpl &TypeImpl::operator=(const TypeImpl &rhs) {
  if (rhs != *this) {
    m_module_wp = rhs.m_module_wp;
    m_static_type = rhs.m_static_type;
    m_dynamic_type = rhs.m_dynamic_type;
  }
  return *this;
}

bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {
  // Check if we have a module for this type. If we do and the shared pointer
  // is can be successfully initialized with m_module_wp, return true. Else
  // return false if we didn't have a module, or if we had a module and it has
  // been deleted. Any functions doing anything with a TypeSP in this TypeImpl
  // class should call this function and only do anything with the ivars if
  // this function returns true. If we have a module, the "module_sp" will be
  // filled in with a strong reference to the module so that the module will at
  // least stay around long enough for the type query to succeed.
  module_sp = m_module_wp.lock();
  if (!module_sp) {
    lldb::ModuleWP empty_module_wp;
    // If either call to "std::weak_ptr::owner_before(...) value returns true,
    // this indicates that m_module_wp once contained (possibly still does) a
    // reference to a valid shared pointer. This helps us know if we had a
    // valid reference to a section which is now invalid because the module it
    // was in was deleted
    if (empty_module_wp.owner_before(m_module_wp) ||
        m_module_wp.owner_before(empty_module_wp)) {
      // m_module_wp had a valid reference to a module, but all strong
      // references have been released and the module has been deleted
      return false;
    }
  }
  // We either successfully locked the module, or didn't have one to begin with
  return true;
}

bool TypeImpl::operator==(const TypeImpl &rhs) const {
  return m_static_type == rhs.m_static_type &&
         m_dynamic_type == rhs.m_dynamic_type;
}

bool TypeImpl::operator!=(const TypeImpl &rhs) const {
  return m_static_type != rhs.m_static_type ||
         m_dynamic_type != rhs.m_dynamic_type;
}

bool TypeImpl::IsValid() const {
  // just a name is not valid
  ModuleSP module_sp;
  if (CheckModule(module_sp))
    return m_static_type.IsValid() || m_dynamic_type.IsValid();
  return false;
}

TypeImpl::operator bool() const { return IsValid(); }

void TypeImpl::Clear() {
  m_module_wp = lldb::ModuleWP();
  m_static_type.Clear();
  m_dynamic_type.Clear();
}

ConstString TypeImpl::GetName() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type)
      return m_dynamic_type.GetTypeName();
    return m_static_type.GetName();
  }
  return ConstString();
}

ConstString TypeImpl::GetDisplayTypeName() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type)
      return m_dynamic_type.GetDisplayTypeName();
    return m_static_type.GetDisplayTypeName();
  }
  return ConstString();
}

TypeImpl TypeImpl::GetPointerType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetPointerType(),
                      m_dynamic_type.GetPointerType());
    }
    return TypeImpl(m_static_type.GetPointerType());
  }
  return TypeImpl();
}

TypeImpl TypeImpl::GetPointeeType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetPointeeType(),
                      m_dynamic_type.GetPointeeType());
    }
    return TypeImpl(m_static_type.GetPointeeType());
  }
  return TypeImpl();
}

TypeImpl TypeImpl::GetReferenceType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetReferenceType(),
                      m_dynamic_type.GetLValueReferenceType());
    }
    return TypeImpl(m_static_type.GetReferenceType());
  }
  return TypeImpl();
}

TypeImpl TypeImpl::GetTypedefedType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetTypedefedType(),
                      m_dynamic_type.GetTypedefedType());
    }
    return TypeImpl(m_static_type.GetTypedefedType());
  }
  return TypeImpl();
}

TypeImpl TypeImpl::GetDereferencedType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetDereferencedType(),
                      m_dynamic_type.GetNonReferenceType());
    }
    return TypeImpl(m_static_type.GetDereferencedType());
  }
  return TypeImpl();
}

TypeImpl TypeImpl::GetUnqualifiedType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetUnqualifiedType(),
                      m_dynamic_type.GetFullyUnqualifiedType());
    }
    return TypeImpl(m_static_type.GetUnqualifiedType());
  }
  return TypeImpl();
}

TypeImpl TypeImpl::GetCanonicalType() const {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      return TypeImpl(m_static_type.GetCanonicalType(),
                      m_dynamic_type.GetCanonicalType());
    }
    return TypeImpl(m_static_type.GetCanonicalType());
  }
  return TypeImpl();
}

CompilerType TypeImpl::GetCompilerType(bool prefer_dynamic) {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (prefer_dynamic) {
      if (m_dynamic_type.IsValid())
        return m_dynamic_type;
    }
    return m_static_type.GetCompilerType();
  }
  return CompilerType();
}

TypeSystem *TypeImpl::GetTypeSystem(bool prefer_dynamic) {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (prefer_dynamic) {
      if (m_dynamic_type.IsValid())
        return m_dynamic_type.GetTypeSystem();
    }
    return m_static_type.GetCompilerType().GetTypeSystem();
  }
  return NULL;
}

bool TypeImpl::GetDescription(lldb_private::Stream &strm,
                              lldb::DescriptionLevel description_level) {
  ModuleSP module_sp;
  if (CheckModule(module_sp)) {
    if (m_dynamic_type.IsValid()) {
      strm.Printf("Dynamic:\n");
      m_dynamic_type.DumpTypeDescription(&strm);
      strm.Printf("\nStatic:\n");
    }
    m_static_type.GetCompilerType().DumpTypeDescription(&strm);
  } else {
    strm.PutCString("Invalid TypeImpl module for type has been deleted\n");
  }
  return true;
}

bool TypeMemberFunctionImpl::IsValid() {
  return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;
}

ConstString TypeMemberFunctionImpl::GetName() const { return m_name; }

ConstString TypeMemberFunctionImpl::GetMangledName() const {
  return m_decl.GetMangledName();
}

CompilerType TypeMemberFunctionImpl::GetType() const { return m_type; }

lldb::MemberFunctionKind TypeMemberFunctionImpl::GetKind() const {
  return m_kind;
}

bool TypeMemberFunctionImpl::GetDescription(Stream &stream) {
  switch (m_kind) {
  case lldb::eMemberFunctionKindUnknown:
    return false;
  case lldb::eMemberFunctionKindConstructor:
    stream.Printf("constructor for %s",
                  m_type.GetTypeName().AsCString("<unknown>"));
    break;
  case lldb::eMemberFunctionKindDestructor:
    stream.Printf("destructor for %s",
                  m_type.GetTypeName().AsCString("<unknown>"));
    break;
  case lldb::eMemberFunctionKindInstanceMethod:
    stream.Printf("instance method %s of type %s", m_name.AsCString(),
                  m_decl.GetDeclContext().GetName().AsCString());
    break;
  case lldb::eMemberFunctionKindStaticMethod:
    stream.Printf("static method %s of type %s", m_name.AsCString(),
                  m_decl.GetDeclContext().GetName().AsCString());
    break;
  }
  return true;
}

CompilerType TypeMemberFunctionImpl::GetReturnType() const {
  if (m_type)
    return m_type.GetFunctionReturnType();
  return m_decl.GetFunctionReturnType();
}

size_t TypeMemberFunctionImpl::GetNumArguments() const {
  if (m_type)
    return m_type.GetNumberOfFunctionArguments();
  else
    return m_decl.GetNumFunctionArguments();
}

CompilerType TypeMemberFunctionImpl::GetArgumentAtIndex(size_t idx) const {
  if (m_type)
    return m_type.GetFunctionArgumentAtIndex(idx);
  else
    return m_decl.GetFunctionArgumentType(idx);
}

TypeEnumMemberImpl::TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp,
                                       const ConstString &name,
                                       const llvm::APSInt &value)
    : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value),
      m_valid((bool)name && (bool)integer_type_sp)

{}
