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

#include "lldb/Symbol/ClangASTContext.h"

#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"

// C Includes
// C++ Includes
#include <mutex>
#include <string>
#include <vector>

// Other libraries and framework includes

// Clang headers like to use NDEBUG inside of them to enable/disable debug
// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
// or another. This is bad because it means that if clang was built in release
// mode, it assumes that you are building in release mode which is not always
// the case. You can end up with functions that are defined as empty in header
// files when NDEBUG is not defined, and this can cause link errors with the
// clang .a files that you have since you might be missing functions in the .a
// file. So we have to define NDEBUG when including clang headers to avoid any
// mismatches. This is covered by rdar://problem/8691220

#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
#define LLDB_DEFINED_NDEBUG_FOR_CLANG
#define NDEBUG
// Need to include assert.h so it is as clang would expect it to be (disabled)
#include <assert.h>
#endif

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTImporter.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"

#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
#undef NDEBUG
#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
#include <assert.h>
#endif

#include "llvm/Support/Signals.h"
#include "llvm/Support/Threading.h"

#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Flags.h"

#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VerifyDecl.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Scalar.h"

#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/PDB/PDBASTParser.h"

#include <stdio.h>

#include <mutex>

using namespace lldb;
using namespace lldb_private;
using namespace llvm;
using namespace clang;

namespace {
static inline bool
ClangASTContextSupportsLanguage(lldb::LanguageType language) {
  return language == eLanguageTypeUnknown || // Clang is the default type system
         Language::LanguageIsC(language) ||
         Language::LanguageIsCPlusPlus(language) ||
         Language::LanguageIsObjC(language) ||
         Language::LanguageIsPascal(language) ||
         // Use Clang for Rust until there is a proper language plugin for it
         language == eLanguageTypeRust ||
         language == eLanguageTypeExtRenderScript ||
         // Use Clang for D until there is a proper language plugin for it
         language == eLanguageTypeD;
}

// Checks whether m1 is an overload of m2 (as opposed to an override). This is
// called by addOverridesForMethod to distinguish overrides (which share a
// vtable entry) from overloads (which require distinct entries).
bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
  // FIXME: This should detect covariant return types, but currently doesn't.
  lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
             "Methods should have the same AST context");
  clang::ASTContext &context = m1->getASTContext();

  const auto *m1Type = llvm::cast<clang::FunctionProtoType>(
      context.getCanonicalType(m1->getType()));

  const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
      context.getCanonicalType(m2->getType()));

  auto compareArgTypes = [&context](const clang::QualType &m1p,
                                    const clang::QualType &m2p) {
    return context.hasSameType(m1p.getUnqualifiedType(),
                               m2p.getUnqualifiedType());
  };

  // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
  //        as a fourth parameter to std::equal().
  return (m1->getNumParams() != m2->getNumParams()) ||
         !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
                     m2Type->param_type_begin(), compareArgTypes);
}

// If decl is a virtual method, walk the base classes looking for methods that
// decl overrides. This table of overridden methods is used by IRGen to
// determine the vtable layout for decl's parent class.
void addOverridesForMethod(clang::CXXMethodDecl *decl) {
  if (!decl->isVirtual())
    return;

  clang::CXXBasePaths paths;

  auto find_overridden_methods =
      [decl](const clang::CXXBaseSpecifier *specifier,
             clang::CXXBasePath &path) {
        if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
                specifier->getType()->getAs<clang::RecordType>()->getDecl())) {

          clang::DeclarationName name = decl->getDeclName();

          // If this is a destructor, check whether the base class destructor is
          // virtual.
          if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
            if (auto *baseDtorDecl = base_record->getDestructor()) {
              if (baseDtorDecl->isVirtual()) {
                path.Decls = baseDtorDecl;
                return true;
              } else
                return false;
            }

          // Otherwise, search for name in the base class.
          for (path.Decls = base_record->lookup(name); !path.Decls.empty();
               path.Decls = path.Decls.slice(1)) {
            if (auto *method_decl =
                    llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
              if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
                path.Decls = method_decl;
                return true;
              }
          }
        }

        return false;
      };

  if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
    for (auto *overridden_decl : paths.found_decls())
      decl->addOverriddenMethod(
          llvm::cast<clang::CXXMethodDecl>(overridden_decl));
  }
}
}

typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext *>
    ClangASTMap;

static ClangASTMap &GetASTMap() {
  static ClangASTMap *g_map_ptr = nullptr;
  static llvm::once_flag g_once_flag;
  llvm::call_once(g_once_flag, []() {
    g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
  });
  return *g_map_ptr;
}

bool ClangASTContext::IsOperator(const char *name,
                                 clang::OverloadedOperatorKind &op_kind) {
  if (name == nullptr || name[0] == '\0')
    return false;

#define OPERATOR_PREFIX "operator"
#define OPERATOR_PREFIX_LENGTH (sizeof(OPERATOR_PREFIX) - 1)

  const char *post_op_name = nullptr;

  bool no_space = true;

  if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
    return false;

  post_op_name = name + OPERATOR_PREFIX_LENGTH;

  if (post_op_name[0] == ' ') {
    post_op_name++;
    no_space = false;
  }

#undef OPERATOR_PREFIX
#undef OPERATOR_PREFIX_LENGTH

  // This is an operator, set the overloaded operator kind to invalid in case
  // this is a conversion operator...
  op_kind = clang::NUM_OVERLOADED_OPERATORS;

  switch (post_op_name[0]) {
  default:
    if (no_space)
      return false;
    break;
  case 'n':
    if (no_space)
      return false;
    if (strcmp(post_op_name, "new") == 0)
      op_kind = clang::OO_New;
    else if (strcmp(post_op_name, "new[]") == 0)
      op_kind = clang::OO_Array_New;
    break;

  case 'd':
    if (no_space)
      return false;
    if (strcmp(post_op_name, "delete") == 0)
      op_kind = clang::OO_Delete;
    else if (strcmp(post_op_name, "delete[]") == 0)
      op_kind = clang::OO_Array_Delete;
    break;

  case '+':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Plus;
    else if (post_op_name[2] == '\0') {
      if (post_op_name[1] == '=')
        op_kind = clang::OO_PlusEqual;
      else if (post_op_name[1] == '+')
        op_kind = clang::OO_PlusPlus;
    }
    break;

  case '-':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Minus;
    else if (post_op_name[2] == '\0') {
      switch (post_op_name[1]) {
      case '=':
        op_kind = clang::OO_MinusEqual;
        break;
      case '-':
        op_kind = clang::OO_MinusMinus;
        break;
      case '>':
        op_kind = clang::OO_Arrow;
        break;
      }
    } else if (post_op_name[3] == '\0') {
      if (post_op_name[2] == '*')
        op_kind = clang::OO_ArrowStar;
      break;
    }
    break;

  case '*':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Star;
    else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
      op_kind = clang::OO_StarEqual;
    break;

  case '/':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Slash;
    else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
      op_kind = clang::OO_SlashEqual;
    break;

  case '%':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Percent;
    else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
      op_kind = clang::OO_PercentEqual;
    break;

  case '^':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Caret;
    else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
      op_kind = clang::OO_CaretEqual;
    break;

  case '&':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Amp;
    else if (post_op_name[2] == '\0') {
      switch (post_op_name[1]) {
      case '=':
        op_kind = clang::OO_AmpEqual;
        break;
      case '&':
        op_kind = clang::OO_AmpAmp;
        break;
      }
    }
    break;

  case '|':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Pipe;
    else if (post_op_name[2] == '\0') {
      switch (post_op_name[1]) {
      case '=':
        op_kind = clang::OO_PipeEqual;
        break;
      case '|':
        op_kind = clang::OO_PipePipe;
        break;
      }
    }
    break;

  case '~':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Tilde;
    break;

  case '!':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Exclaim;
    else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
      op_kind = clang::OO_ExclaimEqual;
    break;

  case '=':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Equal;
    else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
      op_kind = clang::OO_EqualEqual;
    break;

  case '<':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Less;
    else if (post_op_name[2] == '\0') {
      switch (post_op_name[1]) {
      case '<':
        op_kind = clang::OO_LessLess;
        break;
      case '=':
        op_kind = clang::OO_LessEqual;
        break;
      }
    } else if (post_op_name[3] == '\0') {
      if (post_op_name[2] == '=')
        op_kind = clang::OO_LessLessEqual;
    }
    break;

  case '>':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Greater;
    else if (post_op_name[2] == '\0') {
      switch (post_op_name[1]) {
      case '>':
        op_kind = clang::OO_GreaterGreater;
        break;
      case '=':
        op_kind = clang::OO_GreaterEqual;
        break;
      }
    } else if (post_op_name[1] == '>' && post_op_name[2] == '=' &&
               post_op_name[3] == '\0') {
      op_kind = clang::OO_GreaterGreaterEqual;
    }
    break;

  case ',':
    if (post_op_name[1] == '\0')
      op_kind = clang::OO_Comma;
    break;

  case '(':
    if (post_op_name[1] == ')' && post_op_name[2] == '\0')
      op_kind = clang::OO_Call;
    break;

  case '[':
    if (post_op_name[1] == ']' && post_op_name[2] == '\0')
      op_kind = clang::OO_Subscript;
    break;
  }

  return true;
}

clang::AccessSpecifier
ClangASTContext::ConvertAccessTypeToAccessSpecifier(AccessType access) {
  switch (access) {
  default:
    break;
  case eAccessNone:
    return AS_none;
  case eAccessPublic:
    return AS_public;
  case eAccessPrivate:
    return AS_private;
  case eAccessProtected:
    return AS_protected;
  }
  return AS_none;
}

static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
  // FIXME: Cleanup per-file based stuff.

  // Set some properties which depend solely on the input kind; it would be
  // nice to move these to the language standard, and have the driver resolve
  // the input kind + language standard.
  if (IK.getLanguage() == InputKind::Asm) {
    Opts.AsmPreprocessor = 1;
  } else if (IK.isObjectiveC()) {
    Opts.ObjC1 = Opts.ObjC2 = 1;
  }

  LangStandard::Kind LangStd = LangStandard::lang_unspecified;

  if (LangStd == LangStandard::lang_unspecified) {
    // Based on the base language, pick one.
    switch (IK.getLanguage()) {
    case InputKind::Unknown:
    case InputKind::LLVM_IR:
    case InputKind::RenderScript:
      llvm_unreachable("Invalid input kind!");
    case InputKind::OpenCL:
      LangStd = LangStandard::lang_opencl10;
      break;
    case InputKind::CUDA:
      LangStd = LangStandard::lang_cuda;
      break;
    case InputKind::Asm:
    case InputKind::C:
    case InputKind::ObjC:
      LangStd = LangStandard::lang_gnu99;
      break;
    case InputKind::CXX:
    case InputKind::ObjCXX:
      LangStd = LangStandard::lang_gnucxx98;
      break;
    case InputKind::HIP:
      LangStd = LangStandard::lang_hip;
      break;
    }
  }

  const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
  Opts.LineComment = Std.hasLineComments();
  Opts.C99 = Std.isC99();
  Opts.CPlusPlus = Std.isCPlusPlus();
  Opts.CPlusPlus11 = Std.isCPlusPlus11();
  Opts.Digraphs = Std.hasDigraphs();
  Opts.GNUMode = Std.isGNUMode();
  Opts.GNUInline = !Std.isC99();
  Opts.HexFloats = Std.hasHexFloats();
  Opts.ImplicitInt = Std.hasImplicitInt();

  Opts.WChar = true;

  // OpenCL has some additional defaults.
  if (LangStd == LangStandard::lang_opencl10) {
    Opts.OpenCL = 1;
    Opts.AltiVec = 1;
    Opts.CXXOperatorNames = 1;
    Opts.LaxVectorConversions = 1;
  }

  // OpenCL and C++ both have bool, true, false keywords.
  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;

  Opts.setValueVisibilityMode(DefaultVisibility);

  // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
  // specified, or -std is set to a conforming mode.
  Opts.Trigraphs = !Opts.GNUMode;
  Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
  Opts.OptimizeSize = 0;

  // FIXME: Eliminate this dependency.
  //    unsigned Opt =
  //    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
  //    Opts.Optimize = Opt != 0;
  unsigned Opt = 0;

  // This is the __NO_INLINE__ define, which just depends on things like the
  // optimization level and -fno-inline, not actually whether the backend has
  // inlining enabled.
  //
  // FIXME: This is affected by other options (-fno-inline).
  Opts.NoInlineDefine = !Opt;
}

ClangASTContext::ClangASTContext(const char *target_triple)
    : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_ap(),
      m_language_options_ap(), m_source_manager_ap(), m_diagnostics_engine_ap(),
      m_target_options_rp(), m_target_info_ap(), m_identifier_table_ap(),
      m_selector_table_ap(), m_builtins_ap(), m_callback_tag_decl(nullptr),
      m_callback_objc_decl(nullptr), m_callback_baton(nullptr),
      m_pointer_byte_size(0), m_ast_owned(false) {
  if (target_triple && target_triple[0])
    SetTargetTriple(target_triple);
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ClangASTContext::~ClangASTContext() { Finalize(); }

ConstString ClangASTContext::GetPluginNameStatic() {
  return ConstString("clang");
}

ConstString ClangASTContext::GetPluginName() {
  return ClangASTContext::GetPluginNameStatic();
}

uint32_t ClangASTContext::GetPluginVersion() { return 1; }

lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
                                                   lldb_private::Module *module,
                                                   Target *target) {
  if (ClangASTContextSupportsLanguage(language)) {
    ArchSpec arch;
    if (module)
      arch = module->GetArchitecture();
    else if (target)
      arch = target->GetArchitecture();

    if (arch.IsValid()) {
      ArchSpec fixed_arch = arch;
      // LLVM wants this to be set to iOS or MacOSX; if we're working on
      // a bare-boards type image, change the triple for llvm's benefit.
      if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
          fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) {
        if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
            fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
            fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) {
          fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
        } else {
          fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
        }
      }

      if (module) {
        std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
        if (ast_sp) {
          ast_sp->SetArchitecture(fixed_arch);
        }
        return ast_sp;
      } else if (target && target->IsValid()) {
        std::shared_ptr<ClangASTContextForExpressions> ast_sp(
            new ClangASTContextForExpressions(*target));
        if (ast_sp) {
          ast_sp->SetArchitecture(fixed_arch);
          ast_sp->m_scratch_ast_source_ap.reset(
              new ClangASTSource(target->shared_from_this()));
          lldbassert(ast_sp->getFileManager());
          ast_sp->m_scratch_ast_source_ap->InstallASTContext(
              *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
          llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
              ast_sp->m_scratch_ast_source_ap->CreateProxy());
          ast_sp->SetExternalSource(proxy_ast_source);
          return ast_sp;
        }
      }
    }
  }
  return lldb::TypeSystemSP();
}

void ClangASTContext::EnumerateSupportedLanguages(
    std::set<lldb::LanguageType> &languages_for_types,
    std::set<lldb::LanguageType> &languages_for_expressions) {
  static std::vector<lldb::LanguageType> s_supported_languages_for_types(
      {lldb::eLanguageTypeC89, lldb::eLanguageTypeC, lldb::eLanguageTypeC11,
       lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeC99,
       lldb::eLanguageTypeObjC, lldb::eLanguageTypeObjC_plus_plus,
       lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
       lldb::eLanguageTypeC11, lldb::eLanguageTypeC_plus_plus_14});

  static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
      {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC_plus_plus,
       lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
       lldb::eLanguageTypeC_plus_plus_14});

  languages_for_types.insert(s_supported_languages_for_types.begin(),
                             s_supported_languages_for_types.end());
  languages_for_expressions.insert(
      s_supported_languages_for_expressions.begin(),
      s_supported_languages_for_expressions.end());
}

void ClangASTContext::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                "clang base AST context plug-in",
                                CreateInstance, EnumerateSupportedLanguages);
}

void ClangASTContext::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

void ClangASTContext::Finalize() {
  if (m_ast_ap.get()) {
    GetASTMap().Erase(m_ast_ap.get());
    if (!m_ast_owned)
      m_ast_ap.release();
  }

  m_builtins_ap.reset();
  m_selector_table_ap.reset();
  m_identifier_table_ap.reset();
  m_target_info_ap.reset();
  m_target_options_rp.reset();
  m_diagnostics_engine_ap.reset();
  m_source_manager_ap.reset();
  m_language_options_ap.reset();
  m_ast_ap.reset();
  m_scratch_ast_source_ap.reset();
}

void ClangASTContext::Clear() {
  m_ast_ap.reset();
  m_language_options_ap.reset();
  m_source_manager_ap.reset();
  m_diagnostics_engine_ap.reset();
  m_target_options_rp.reset();
  m_target_info_ap.reset();
  m_identifier_table_ap.reset();
  m_selector_table_ap.reset();
  m_builtins_ap.reset();
  m_pointer_byte_size = 0;
}

const char *ClangASTContext::GetTargetTriple() {
  return m_target_triple.c_str();
}

void ClangASTContext::SetTargetTriple(const char *target_triple) {
  Clear();
  m_target_triple.assign(target_triple);
}

void ClangASTContext::SetArchitecture(const ArchSpec &arch) {
  SetTargetTriple(arch.GetTriple().str().c_str());
}

bool ClangASTContext::HasExternalSource() {
  ASTContext *ast = getASTContext();
  if (ast)
    return ast->getExternalSource() != nullptr;
  return false;
}

void ClangASTContext::SetExternalSource(
    llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_ap) {
  ASTContext *ast = getASTContext();
  if (ast) {
    ast->setExternalSource(ast_source_ap);
    ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
  }
}

void ClangASTContext::RemoveExternalSource() {
  ASTContext *ast = getASTContext();

  if (ast) {
    llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_ap;
    ast->setExternalSource(empty_ast_source_ap);
    ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
  }
}

void ClangASTContext::setASTContext(clang::ASTContext *ast_ctx) {
  if (!m_ast_owned) {
    m_ast_ap.release();
  }
  m_ast_owned = false;
  m_ast_ap.reset(ast_ctx);
  GetASTMap().Insert(ast_ctx, this);
}

ASTContext *ClangASTContext::getASTContext() {
  if (m_ast_ap.get() == nullptr) {
    m_ast_owned = true;
    m_ast_ap.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
                                  *getIdentifierTable(), *getSelectorTable(),
                                  *getBuiltinContext()));

    m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);

    // This can be NULL if we don't know anything about the architecture or if
    // the target for an architecture isn't enabled in the llvm/clang that we
    // built
    TargetInfo *target_info = getTargetInfo();
    if (target_info)
      m_ast_ap->InitBuiltinTypes(*target_info);

    if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
      m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
      // m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
    }

    GetASTMap().Insert(m_ast_ap.get(), this);

    llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap(
        new ClangExternalASTSourceCallbacks(
            ClangASTContext::CompleteTagDecl,
            ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
            ClangASTContext::LayoutRecordType, this));
    SetExternalSource(ast_source_ap);
  }
  return m_ast_ap.get();
}

ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) {
  ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
  return clang_ast;
}

Builtin::Context *ClangASTContext::getBuiltinContext() {
  if (m_builtins_ap.get() == nullptr)
    m_builtins_ap.reset(new Builtin::Context());
  return m_builtins_ap.get();
}

IdentifierTable *ClangASTContext::getIdentifierTable() {
  if (m_identifier_table_ap.get() == nullptr)
    m_identifier_table_ap.reset(
        new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr));
  return m_identifier_table_ap.get();
}

LangOptions *ClangASTContext::getLanguageOptions() {
  if (m_language_options_ap.get() == nullptr) {
    m_language_options_ap.reset(new LangOptions());
    ParseLangArgs(*m_language_options_ap, InputKind::ObjCXX, GetTargetTriple());
    //        InitializeLangOptions(*m_language_options_ap, InputKind::ObjCXX);
  }
  return m_language_options_ap.get();
}

SelectorTable *ClangASTContext::getSelectorTable() {
  if (m_selector_table_ap.get() == nullptr)
    m_selector_table_ap.reset(new SelectorTable());
  return m_selector_table_ap.get();
}

clang::FileManager *ClangASTContext::getFileManager() {
  if (m_file_manager_ap.get() == nullptr) {
    clang::FileSystemOptions file_system_options;
    m_file_manager_ap.reset(new clang::FileManager(file_system_options));
  }
  return m_file_manager_ap.get();
}

clang::SourceManager *ClangASTContext::getSourceManager() {
  if (m_source_manager_ap.get() == nullptr)
    m_source_manager_ap.reset(
        new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
  return m_source_manager_ap.get();
}

clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() {
  if (m_diagnostics_engine_ap.get() == nullptr) {
    llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
    m_diagnostics_engine_ap.reset(
        new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
  }
  return m_diagnostics_engine_ap.get();
}

clang::MangleContext *ClangASTContext::getMangleContext() {
  if (m_mangle_ctx_ap.get() == nullptr)
    m_mangle_ctx_ap.reset(getASTContext()->createMangleContext());
  return m_mangle_ctx_ap.get();
}

class NullDiagnosticConsumer : public DiagnosticConsumer {
public:
  NullDiagnosticConsumer() {
    m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
  }

  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                        const clang::Diagnostic &info) {
    if (m_log) {
      llvm::SmallVector<char, 32> diag_str(10);
      info.FormatDiagnostic(diag_str);
      diag_str.push_back('\0');
      m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
    }
  }

  DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
    return new NullDiagnosticConsumer();
  }

private:
  Log *m_log;
};

DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() {
  if (m_diagnostic_consumer_ap.get() == nullptr)
    m_diagnostic_consumer_ap.reset(new NullDiagnosticConsumer);

  return m_diagnostic_consumer_ap.get();
}

std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() {
  if (m_target_options_rp.get() == nullptr && !m_target_triple.empty()) {
    m_target_options_rp = std::make_shared<clang::TargetOptions>();
    if (m_target_options_rp.get() != nullptr)
      m_target_options_rp->Triple = m_target_triple;
  }
  return m_target_options_rp;
}

TargetInfo *ClangASTContext::getTargetInfo() {
  // target_triple should be something like "x86_64-apple-macosx"
  if (m_target_info_ap.get() == nullptr && !m_target_triple.empty())
    m_target_info_ap.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(),
                                                        getTargetOptions()));
  return m_target_info_ap.get();
}

#pragma mark Basic Types

static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
                                          ASTContext *ast, QualType qual_type) {
  uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
  if (qual_type_bit_size == bit_size)
    return true;
  return false;
}

CompilerType
ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
                                                     size_t bit_size) {
  return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
      getASTContext(), encoding, bit_size);
}

CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
    ASTContext *ast, Encoding encoding, uint32_t bit_size) {
  if (!ast)
    return CompilerType();
  switch (encoding) {
  case eEncodingInvalid:
    if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
      return CompilerType(ast, ast->VoidPtrTy);
    break;

  case eEncodingUint:
    if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
      return CompilerType(ast, ast->UnsignedCharTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
      return CompilerType(ast, ast->UnsignedShortTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
      return CompilerType(ast, ast->UnsignedIntTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
      return CompilerType(ast, ast->UnsignedLongTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
      return CompilerType(ast, ast->UnsignedLongLongTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
      return CompilerType(ast, ast->UnsignedInt128Ty);
    break;

  case eEncodingSint:
    if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
      return CompilerType(ast, ast->SignedCharTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
      return CompilerType(ast, ast->ShortTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
      return CompilerType(ast, ast->IntTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
      return CompilerType(ast, ast->LongTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
      return CompilerType(ast, ast->LongLongTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
      return CompilerType(ast, ast->Int128Ty);
    break;

  case eEncodingIEEE754:
    if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
      return CompilerType(ast, ast->FloatTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
      return CompilerType(ast, ast->DoubleTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
      return CompilerType(ast, ast->LongDoubleTy);
    if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
      return CompilerType(ast, ast->HalfTy);
    break;

  case eEncodingVector:
    // Sanity check that bit_size is a multiple of 8's.
    if (bit_size && !(bit_size & 0x7u))
      return CompilerType(
          ast, ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8));
    break;
  }

  return CompilerType();
}

lldb::BasicType
ClangASTContext::GetBasicTypeEnumeration(const ConstString &name) {
  if (name) {
    typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
    static TypeNameToBasicTypeMap g_type_map;
    static llvm::once_flag g_once_flag;
    llvm::call_once(g_once_flag, []() {
      // "void"
      g_type_map.Append(ConstString("void"), eBasicTypeVoid);

      // "char"
      g_type_map.Append(ConstString("char"), eBasicTypeChar);
      g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar);
      g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar);
      g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar);
      g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar);
      g_type_map.Append(ConstString("unsigned wchar_t"),
                        eBasicTypeUnsignedWChar);
      // "short"
      g_type_map.Append(ConstString("short"), eBasicTypeShort);
      g_type_map.Append(ConstString("short int"), eBasicTypeShort);
      g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort);
      g_type_map.Append(ConstString("unsigned short int"),
                        eBasicTypeUnsignedShort);

      // "int"
      g_type_map.Append(ConstString("int"), eBasicTypeInt);
      g_type_map.Append(ConstString("signed int"), eBasicTypeInt);
      g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt);
      g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt);

      // "long"
      g_type_map.Append(ConstString("long"), eBasicTypeLong);
      g_type_map.Append(ConstString("long int"), eBasicTypeLong);
      g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong);
      g_type_map.Append(ConstString("unsigned long int"),
                        eBasicTypeUnsignedLong);

      // "long long"
      g_type_map.Append(ConstString("long long"), eBasicTypeLongLong);
      g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong);
      g_type_map.Append(ConstString("unsigned long long"),
                        eBasicTypeUnsignedLongLong);
      g_type_map.Append(ConstString("unsigned long long int"),
                        eBasicTypeUnsignedLongLong);

      // "int128"
      g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128);
      g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128);

      // Miscellaneous
      g_type_map.Append(ConstString("bool"), eBasicTypeBool);
      g_type_map.Append(ConstString("float"), eBasicTypeFloat);
      g_type_map.Append(ConstString("double"), eBasicTypeDouble);
      g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble);
      g_type_map.Append(ConstString("id"), eBasicTypeObjCID);
      g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel);
      g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr);
      g_type_map.Sort();
    });

    return g_type_map.Find(name, eBasicTypeInvalid);
  }
  return eBasicTypeInvalid;
}

CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
                                           const ConstString &name) {
  if (ast) {
    lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name);
    return ClangASTContext::GetBasicType(ast, basic_type);
  }
  return CompilerType();
}

uint32_t ClangASTContext::GetPointerByteSize() {
  if (m_pointer_byte_size == 0)
    m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid)
                              .GetPointerType()
                              .GetByteSize(nullptr);
  return m_pointer_byte_size;
}

CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) {
  return GetBasicType(getASTContext(), basic_type);
}

CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
                                           lldb::BasicType basic_type) {
  if (!ast)
    return CompilerType();
  lldb::opaque_compiler_type_t clang_type =
      GetOpaqueCompilerType(ast, basic_type);

  if (clang_type)
    return CompilerType(GetASTContext(ast), clang_type);
  return CompilerType();
}

CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
    const char *type_name, uint32_t dw_ate, uint32_t bit_size) {
  ASTContext *ast = getASTContext();

#define streq(a, b) strcmp(a, b) == 0
  assert(ast != nullptr);
  if (ast) {
    switch (dw_ate) {
    default:
      break;

    case DW_ATE_address:
      if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
        return CompilerType(ast, ast->VoidPtrTy);
      break;

    case DW_ATE_boolean:
      if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy))
        return CompilerType(ast, ast->BoolTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
        return CompilerType(ast, ast->UnsignedCharTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
        return CompilerType(ast, ast->UnsignedShortTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
        return CompilerType(ast, ast->UnsignedIntTy);
      break;

    case DW_ATE_lo_user:
      // This has been seen to mean DW_AT_complex_integer
      if (type_name) {
        if (::strstr(type_name, "complex")) {
          CompilerType complex_int_clang_type =
              GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
                                                       bit_size / 2);
          return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
                                       complex_int_clang_type)));
        }
      }
      break;

    case DW_ATE_complex_float:
      if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy))
        return CompilerType(ast, ast->FloatComplexTy);
      else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy))
        return CompilerType(ast, ast->DoubleComplexTy);
      else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy))
        return CompilerType(ast, ast->LongDoubleComplexTy);
      else {
        CompilerType complex_float_clang_type =
            GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
                                                     bit_size / 2);
        return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
                                     complex_float_clang_type)));
      }
      break;

    case DW_ATE_float:
      if (streq(type_name, "float") &&
          QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
        return CompilerType(ast, ast->FloatTy);
      if (streq(type_name, "double") &&
          QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
        return CompilerType(ast, ast->DoubleTy);
      if (streq(type_name, "long double") &&
          QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
        return CompilerType(ast, ast->LongDoubleTy);
      // Fall back to not requiring a name match
      if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
        return CompilerType(ast, ast->FloatTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
        return CompilerType(ast, ast->DoubleTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
        return CompilerType(ast, ast->LongDoubleTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
        return CompilerType(ast, ast->HalfTy);
      break;

    case DW_ATE_signed:
      if (type_name) {
        if (streq(type_name, "wchar_t") &&
            QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) &&
            (getTargetInfo() &&
             TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
          return CompilerType(ast, ast->WCharTy);
        if (streq(type_name, "void") &&
            QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy))
          return CompilerType(ast, ast->VoidTy);
        if (strstr(type_name, "long long") &&
            QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
          return CompilerType(ast, ast->LongLongTy);
        if (strstr(type_name, "long") &&
            QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
          return CompilerType(ast, ast->LongTy);
        if (strstr(type_name, "short") &&
            QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
          return CompilerType(ast, ast->ShortTy);
        if (strstr(type_name, "char")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
            return CompilerType(ast, ast->CharTy);
          if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
            return CompilerType(ast, ast->SignedCharTy);
        }
        if (strstr(type_name, "int")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
            return CompilerType(ast, ast->IntTy);
          if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
            return CompilerType(ast, ast->Int128Ty);
        }
      }
      // We weren't able to match up a type name, just search by size
      if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
        return CompilerType(ast, ast->CharTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
        return CompilerType(ast, ast->ShortTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
        return CompilerType(ast, ast->IntTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
        return CompilerType(ast, ast->LongTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
        return CompilerType(ast, ast->LongLongTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
        return CompilerType(ast, ast->Int128Ty);
      break;

    case DW_ATE_signed_char:
      if (ast->getLangOpts().CharIsSigned && type_name &&
          streq(type_name, "char")) {
        if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
          return CompilerType(ast, ast->CharTy);
      }
      if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
        return CompilerType(ast, ast->SignedCharTy);
      break;

    case DW_ATE_unsigned:
      if (type_name) {
        if (streq(type_name, "wchar_t")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) {
            if (!(getTargetInfo() &&
                  TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
              return CompilerType(ast, ast->WCharTy);
          }
        }
        if (strstr(type_name, "long long")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
            return CompilerType(ast, ast->UnsignedLongLongTy);
        } else if (strstr(type_name, "long")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
            return CompilerType(ast, ast->UnsignedLongTy);
        } else if (strstr(type_name, "short")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
            return CompilerType(ast, ast->UnsignedShortTy);
        } else if (strstr(type_name, "char")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
            return CompilerType(ast, ast->UnsignedCharTy);
        } else if (strstr(type_name, "int")) {
          if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
            return CompilerType(ast, ast->UnsignedIntTy);
          if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
            return CompilerType(ast, ast->UnsignedInt128Ty);
        }
      }
      // We weren't able to match up a type name, just search by size
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
        return CompilerType(ast, ast->UnsignedCharTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
        return CompilerType(ast, ast->UnsignedShortTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
        return CompilerType(ast, ast->UnsignedIntTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
        return CompilerType(ast, ast->UnsignedLongTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
        return CompilerType(ast, ast->UnsignedLongLongTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
        return CompilerType(ast, ast->UnsignedInt128Ty);
      break;

    case DW_ATE_unsigned_char:
      if (!ast->getLangOpts().CharIsSigned && type_name &&
          streq(type_name, "char")) {
        if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
          return CompilerType(ast, ast->CharTy);
      }
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
        return CompilerType(ast, ast->UnsignedCharTy);
      if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
        return CompilerType(ast, ast->UnsignedShortTy);
      break;

    case DW_ATE_imaginary_float:
      break;

    case DW_ATE_UTF:
      if (type_name) {
        if (streq(type_name, "char16_t")) {
          return CompilerType(ast, ast->Char16Ty);
        } else if (streq(type_name, "char32_t")) {
          return CompilerType(ast, ast->Char32Ty);
        }
      }
      break;
    }
  }
  // This assert should fire for anything that we don't catch above so we know
  // to fix any issues we run into.
  if (type_name) {
    Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
                                           "DW_TAG_base_type '%s' encoded with "
                                           "DW_ATE = 0x%x, bit_size = %u\n",
                    type_name, dw_ate, bit_size);
  } else {
    Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
                                           "DW_TAG_base_type encoded with "
                                           "DW_ATE = 0x%x, bit_size = %u\n",
                    dw_ate, bit_size);
  }
  return CompilerType();
}

CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) {
  if (ast)
    return CompilerType(ast, ast->UnknownAnyTy);
  return CompilerType();
}

CompilerType ClangASTContext::GetCStringType(bool is_const) {
  ASTContext *ast = getASTContext();
  QualType char_type(ast->CharTy);

  if (is_const)
    char_type.addConst();

  return CompilerType(ast, ast->getPointerType(char_type));
}

clang::DeclContext *
ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) {
  return ast->getTranslationUnitDecl();
}

clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast,
                                       clang::Decl *source_decl) {
  FileSystemOptions file_system_options;
  FileManager file_manager(file_system_options);
  ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false);

  return importer.Import(source_decl);
}

bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2,
                                   bool ignore_qualifiers) {
  ClangASTContext *ast =
      llvm::dyn_cast_or_null<ClangASTContext>(type1.GetTypeSystem());
  if (!ast || ast != type2.GetTypeSystem())
    return false;

  if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
    return true;

  QualType type1_qual = ClangUtil::GetQualType(type1);
  QualType type2_qual = ClangUtil::GetQualType(type2);

  if (ignore_qualifiers) {
    type1_qual = type1_qual.getUnqualifiedType();
    type2_qual = type2_qual.getUnqualifiedType();
  }

  return ast->getASTContext()->hasSameType(type1_qual, type2_qual);
}

CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
  if (clang::ObjCInterfaceDecl *interface_decl =
          llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
    return GetTypeForDecl(interface_decl);
  if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
    return GetTypeForDecl(tag_decl);
  return CompilerType();
}

CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
  // No need to call the getASTContext() accessor (which can create the AST if
  // it isn't created yet, because we can't have created a decl in this
  // AST if our AST didn't already exist...
  ASTContext *ast = &decl->getASTContext();
  if (ast)
    return CompilerType(ast, ast->getTagDeclType(decl));
  return CompilerType();
}

CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
  // No need to call the getASTContext() accessor (which can create the AST if
  // it isn't created yet, because we can't have created a decl in this
  // AST if our AST didn't already exist...
  ASTContext *ast = &decl->getASTContext();
  if (ast)
    return CompilerType(ast, ast->getObjCInterfaceType(decl));
  return CompilerType();
}

#pragma mark Structure, Unions, Classes

CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
                                               AccessType access_type,
                                               const char *name, int kind,
                                               LanguageType language,
                                               ClangASTMetadata *metadata) {
  ASTContext *ast = getASTContext();
  assert(ast != nullptr);

  if (decl_ctx == nullptr)
    decl_ctx = ast->getTranslationUnitDecl();

  if (language == eLanguageTypeObjC ||
      language == eLanguageTypeObjC_plus_plus) {
    bool isForwardDecl = true;
    bool isInternal = false;
    return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
  }

  // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
  // we will need to update this code. I was told to currently always use the
  // CXXRecordDecl class since we often don't know from debug information if
  // something is struct or a class, so we default to always use the more
  // complete definition just in case.

  bool is_anonymous = (!name) || (!name[0]);

  CXXRecordDecl *decl = CXXRecordDecl::Create(
      *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
      SourceLocation(), is_anonymous ? nullptr : &ast->Idents.get(name));

  if (is_anonymous)
    decl->setAnonymousStructOrUnion(true);

  if (decl) {
    if (metadata)
      SetMetadata(ast, decl, *metadata);

    if (access_type != eAccessNone)
      decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));

    if (decl_ctx)
      decl_ctx->addDecl(decl);

    return CompilerType(ast, ast->getTagDeclType(decl));
  }
  return CompilerType();
}

namespace {
  bool IsValueParam(const clang::TemplateArgument &argument) {
    return argument.getKind() == TemplateArgument::Integral;
  }
}

static TemplateParameterList *CreateTemplateParameterList(
    ASTContext *ast,
    const ClangASTContext::TemplateParameterInfos &template_param_infos,
    llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
  const bool parameter_pack = false;
  const bool is_typename = false;
  const unsigned depth = 0;
  const size_t num_template_params = template_param_infos.args.size();
  DeclContext *const decl_context =
      ast->getTranslationUnitDecl(); // Is this the right decl context?,
  for (size_t i = 0; i < num_template_params; ++i) {
    const char *name = template_param_infos.names[i];

    IdentifierInfo *identifier_info = nullptr;
    if (name && name[0])
      identifier_info = &ast->Idents.get(name);
    if (IsValueParam(template_param_infos.args[i])) {
      template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
          *ast, decl_context,
          SourceLocation(), SourceLocation(), depth, i, identifier_info,
          template_param_infos.args[i].getIntegralType(), parameter_pack,
          nullptr));

    } else {
      template_param_decls.push_back(TemplateTypeParmDecl::Create(
          *ast, decl_context,
          SourceLocation(), SourceLocation(), depth, i, identifier_info,
          is_typename, parameter_pack));
    }
  }

  if (template_param_infos.packed_args &&
      template_param_infos.packed_args->args.size()) {
    IdentifierInfo *identifier_info = nullptr;
    if (template_param_infos.pack_name && template_param_infos.pack_name[0])
      identifier_info = &ast->Idents.get(template_param_infos.pack_name);
    const bool parameter_pack_true = true;
    if (IsValueParam(template_param_infos.packed_args->args[0])) {
      template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
          *ast, decl_context,
          SourceLocation(), SourceLocation(), depth, num_template_params,
          identifier_info,
          template_param_infos.packed_args->args[0].getIntegralType(),
          parameter_pack_true, nullptr));
    } else {
      template_param_decls.push_back(TemplateTypeParmDecl::Create(
          *ast, decl_context,
          SourceLocation(), SourceLocation(), depth, num_template_params,
          identifier_info,
          is_typename, parameter_pack_true));
    }
  }
  clang::Expr *const requires_clause = nullptr; // TODO: Concepts
  TemplateParameterList *template_param_list = TemplateParameterList::Create(
      *ast, SourceLocation(), SourceLocation(), template_param_decls,
      SourceLocation(), requires_clause);
  return template_param_list;
}

clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl(
    clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
    const char *name, const TemplateParameterInfos &template_param_infos) {
  //    /// Create a function template node.
  ASTContext *ast = getASTContext();

  llvm::SmallVector<NamedDecl *, 8> template_param_decls;

  TemplateParameterList *template_param_list = CreateTemplateParameterList(
      ast, template_param_infos, template_param_decls);
  FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create(
      *ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(),
      template_param_list, func_decl);

  for (size_t i = 0, template_param_decl_count = template_param_decls.size();
       i < template_param_decl_count; ++i) {
    // TODO: verify which decl context we should put template_param_decls into..
    template_param_decls[i]->setDeclContext(func_decl);
  }

  return func_tmpl_decl;
}

void ClangASTContext::CreateFunctionTemplateSpecializationInfo(
    FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
    const TemplateParameterInfos &infos) {
  TemplateArgumentList template_args(TemplateArgumentList::OnStack, infos.args);

  func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, &template_args,
                                               nullptr);
}

ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(
    DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
    int kind, const TemplateParameterInfos &template_param_infos) {
  ASTContext *ast = getASTContext();

  ClassTemplateDecl *class_template_decl = nullptr;
  if (decl_ctx == nullptr)
    decl_ctx = ast->getTranslationUnitDecl();

  IdentifierInfo &identifier_info = ast->Idents.get(class_name);
  DeclarationName decl_name(&identifier_info);

  clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);

  for (NamedDecl *decl : result) {
    class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
    if (class_template_decl)
      return class_template_decl;
  }

  llvm::SmallVector<NamedDecl *, 8> template_param_decls;

  TemplateParameterList *template_param_list = CreateTemplateParameterList(
      ast, template_param_infos, template_param_decls);

  CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
      *ast, (TagDecl::TagKind)kind,
      decl_ctx, // What decl context do we use here? TU? The actual decl
                // context?
      SourceLocation(), SourceLocation(), &identifier_info);

  for (size_t i = 0, template_param_decl_count = template_param_decls.size();
       i < template_param_decl_count; ++i) {
    template_param_decls[i]->setDeclContext(template_cxx_decl);
  }

  // With templated classes, we say that a class is templated with
  // specializations, but that the bare class has no functions.
  // template_cxx_decl->startDefinition();
  // template_cxx_decl->completeDefinition();

  class_template_decl = ClassTemplateDecl::Create(
      *ast,
      decl_ctx, // What decl context do we use here? TU? The actual decl
                // context?
      SourceLocation(), decl_name, template_param_list, template_cxx_decl);

  if (class_template_decl) {
    if (access_type != eAccessNone)
      class_template_decl->setAccess(
          ConvertAccessTypeToAccessSpecifier(access_type));

    // if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
    //    CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));

    decl_ctx->addDecl(class_template_decl);

#ifdef LLDB_CONFIGURATION_DEBUG
    VerifyDecl(class_template_decl);
#endif
  }

  return class_template_decl;
}

TemplateTemplateParmDecl *
ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) {
  ASTContext *ast = getASTContext();

  auto *decl_ctx = ast->getTranslationUnitDecl();

  IdentifierInfo &identifier_info = ast->Idents.get(template_name);
  llvm::SmallVector<NamedDecl *, 8> template_param_decls;

  ClangASTContext::TemplateParameterInfos template_param_infos;
  TemplateParameterList *template_param_list = CreateTemplateParameterList(
      ast, template_param_infos, template_param_decls);

  // LLDB needs to create those decls only to be able to display a
  // type that includes a template template argument. Only the name matters for
  // this purpose, so we use dummy values for the other characterisitcs of the
  // type.
  return TemplateTemplateParmDecl::Create(
      *ast, decl_ctx, SourceLocation(),
      /*Depth*/ 0, /*Position*/ 0,
      /*IsParameterPack*/ false, &identifier_info, template_param_list);
}

ClassTemplateSpecializationDecl *
ClangASTContext::CreateClassTemplateSpecializationDecl(
    DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
    const TemplateParameterInfos &template_param_infos) {
  ASTContext *ast = getASTContext();
  llvm::SmallVector<clang::TemplateArgument, 2> args(
      template_param_infos.args.size() +
      (template_param_infos.packed_args ? 1 : 0));
  std::copy(template_param_infos.args.begin(), template_param_infos.args.end(),
            args.begin());
  if (template_param_infos.packed_args) {
    args[args.size() - 1] = TemplateArgument::CreatePackCopy(
        *ast, template_param_infos.packed_args->args);
  }
  ClassTemplateSpecializationDecl *class_template_specialization_decl =
      ClassTemplateSpecializationDecl::Create(
          *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
          SourceLocation(), class_template_decl, args,
          nullptr);

  class_template_specialization_decl->setSpecializationKind(
      TSK_ExplicitSpecialization);

  return class_template_specialization_decl;
}

CompilerType ClangASTContext::CreateClassTemplateSpecializationType(
    ClassTemplateSpecializationDecl *class_template_specialization_decl) {
  if (class_template_specialization_decl) {
    ASTContext *ast = getASTContext();
    if (ast)
      return CompilerType(
          ast, ast->getTagDeclType(class_template_specialization_decl));
  }
  return CompilerType();
}

static inline bool check_op_param(bool is_method,
                                  clang::OverloadedOperatorKind op_kind,
                                  bool unary, bool binary,
                                  uint32_t num_params) {
  // Special-case call since it can take any number of operands
  if (op_kind == OO_Call)
    return true;

  // The parameter count doesn't include "this"
  if (is_method)
    ++num_params;
  if (num_params == 1)
    return unary;
  if (num_params == 2)
    return binary;
  else
    return false;
}

bool ClangASTContext::CheckOverloadedOperatorKindParameterCount(
    bool is_method, clang::OverloadedOperatorKind op_kind,
    uint32_t num_params) {
  switch (op_kind) {
  default:
    break;
  // C++ standard allows any number of arguments to new/delete
  case OO_New:
  case OO_Array_New:
  case OO_Delete:
  case OO_Array_Delete:
    return true;
  }

#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly)  \
  case OO_##Name:                                                              \
    return check_op_param(is_method, op_kind, Unary, Binary, num_params);
  switch (op_kind) {
#include "clang/Basic/OperatorKinds.def"
  default:
    break;
  }
  return false;
}

clang::AccessSpecifier
ClangASTContext::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
                                       clang::AccessSpecifier rhs) {
  // Make the access equal to the stricter of the field and the nested field's
  // access
  if (lhs == AS_none || rhs == AS_none)
    return AS_none;
  if (lhs == AS_private || rhs == AS_private)
    return AS_private;
  if (lhs == AS_protected || rhs == AS_protected)
    return AS_protected;
  return AS_public;
}

bool ClangASTContext::FieldIsBitfield(FieldDecl *field,
                                      uint32_t &bitfield_bit_size) {
  return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
}

bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field,
                                      uint32_t &bitfield_bit_size) {
  if (ast == nullptr || field == nullptr)
    return false;

  if (field->isBitField()) {
    Expr *bit_width_expr = field->getBitWidth();
    if (bit_width_expr) {
      llvm::APSInt bit_width_apsint;
      if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) {
        bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
        return true;
      }
    }
  }
  return false;
}

bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) {
  if (record_decl == nullptr)
    return false;

  if (!record_decl->field_empty())
    return true;

  // No fields, lets check this is a CXX record and check the base classes
  const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
  if (cxx_record_decl) {
    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
    for (base_class = cxx_record_decl->bases_begin(),
        base_class_end = cxx_record_decl->bases_end();
         base_class != base_class_end; ++base_class) {
      const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
          base_class->getType()->getAs<RecordType>()->getDecl());
      if (RecordHasFields(base_class_decl))
        return true;
    }
  }
  return false;
}

#pragma mark Objective-C Classes

CompilerType ClangASTContext::CreateObjCClass(const char *name,
                                              DeclContext *decl_ctx,
                                              bool isForwardDecl,
                                              bool isInternal,
                                              ClangASTMetadata *metadata) {
  ASTContext *ast = getASTContext();
  assert(ast != nullptr);
  assert(name && name[0]);
  if (decl_ctx == nullptr)
    decl_ctx = ast->getTranslationUnitDecl();

  ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create(
      *ast, decl_ctx, SourceLocation(), &ast->Idents.get(name), nullptr,
      nullptr, SourceLocation(),
      /*isForwardDecl,*/
      isInternal);

  if (decl && metadata)
    SetMetadata(ast, decl, *metadata);

  return CompilerType(ast, ast->getObjCInterfaceType(decl));
}

static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
  return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) ==
         false;
}

uint32_t
ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
                                   bool omit_empty_base_classes) {
  uint32_t num_bases = 0;
  if (cxx_record_decl) {
    if (omit_empty_base_classes) {
      CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
      for (base_class = cxx_record_decl->bases_begin(),
          base_class_end = cxx_record_decl->bases_end();
           base_class != base_class_end; ++base_class) {
        // Skip empty base classes
        if (omit_empty_base_classes) {
          if (BaseSpecifierIsEmpty(base_class))
            continue;
        }
        ++num_bases;
      }
    } else
      num_bases = cxx_record_decl->getNumBases();
  }
  return num_bases;
}

#pragma mark Namespace Declarations

NamespaceDecl *
ClangASTContext::GetUniqueNamespaceDeclaration(const char *name,
                                               DeclContext *decl_ctx) {
  NamespaceDecl *namespace_decl = nullptr;
  ASTContext *ast = getASTContext();
  TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl();
  if (decl_ctx == nullptr)
    decl_ctx = translation_unit_decl;

  if (name) {
    IdentifierInfo &identifier_info = ast->Idents.get(name);
    DeclarationName decl_name(&identifier_info);
    clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
    for (NamedDecl *decl : result) {
      namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
      if (namespace_decl)
        return namespace_decl;
    }

    namespace_decl =
        NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
                              SourceLocation(), &identifier_info, nullptr);

    decl_ctx->addDecl(namespace_decl);
  } else {
    if (decl_ctx == translation_unit_decl) {
      namespace_decl = translation_unit_decl->getAnonymousNamespace();
      if (namespace_decl)
        return namespace_decl;

      namespace_decl =
          NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
                                SourceLocation(), nullptr, nullptr);
      translation_unit_decl->setAnonymousNamespace(namespace_decl);
      translation_unit_decl->addDecl(namespace_decl);
      assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
    } else {
      NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
      if (parent_namespace_decl) {
        namespace_decl = parent_namespace_decl->getAnonymousNamespace();
        if (namespace_decl)
          return namespace_decl;
        namespace_decl =
            NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
                                  SourceLocation(), nullptr, nullptr);
        parent_namespace_decl->setAnonymousNamespace(namespace_decl);
        parent_namespace_decl->addDecl(namespace_decl);
        assert(namespace_decl ==
               parent_namespace_decl->getAnonymousNamespace());
      } else {
        // BAD!!!
      }
    }
  }
#ifdef LLDB_CONFIGURATION_DEBUG
  VerifyDecl(namespace_decl);
#endif
  return namespace_decl;
}

NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
    clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx) {
  ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
  if (ast_ctx == nullptr)
    return nullptr;

  return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx);
}

clang::BlockDecl *
ClangASTContext::CreateBlockDeclaration(clang::DeclContext *ctx) {
  if (ctx != nullptr) {
    clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx,
                                                      clang::SourceLocation());
    ctx->addDecl(decl);
    return decl;
  }
  return nullptr;
}

clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
                                        clang::DeclContext *right,
                                        clang::DeclContext *root) {
  if (root == nullptr)
    return nullptr;

  std::set<clang::DeclContext *> path_left;
  for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
    path_left.insert(d);

  for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
    if (path_left.find(d) != path_left.end())
      return d;

  return nullptr;
}

clang::UsingDirectiveDecl *ClangASTContext::CreateUsingDirectiveDeclaration(
    clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
  if (decl_ctx != nullptr && ns_decl != nullptr) {
    clang::TranslationUnitDecl *translation_unit =
        (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
    clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
        *getASTContext(), decl_ctx, clang::SourceLocation(),
        clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
        clang::SourceLocation(), ns_decl,
        FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
    decl_ctx->addDecl(using_decl);
    return using_decl;
  }
  return nullptr;
}

clang::UsingDecl *
ClangASTContext::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
                                        clang::NamedDecl *target) {
  if (current_decl_ctx != nullptr && target != nullptr) {
    clang::UsingDecl *using_decl = clang::UsingDecl::Create(
        *getASTContext(), current_decl_ctx, clang::SourceLocation(),
        clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
    clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
        *getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
        target);
    using_decl->addShadowDecl(shadow_decl);
    current_decl_ctx->addDecl(using_decl);
    return using_decl;
  }
  return nullptr;
}

clang::VarDecl *ClangASTContext::CreateVariableDeclaration(
    clang::DeclContext *decl_context, const char *name, clang::QualType type) {
  if (decl_context != nullptr) {
    clang::VarDecl *var_decl = clang::VarDecl::Create(
        *getASTContext(), decl_context, clang::SourceLocation(),
        clang::SourceLocation(),
        name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, type,
        nullptr, clang::SC_None);
    var_decl->setAccess(clang::AS_public);
    decl_context->addDecl(var_decl);
    return var_decl;
  }
  return nullptr;
}

lldb::opaque_compiler_type_t
ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast,
                                       lldb::BasicType basic_type) {
  switch (basic_type) {
  case eBasicTypeVoid:
    return ast->VoidTy.getAsOpaquePtr();
  case eBasicTypeChar:
    return ast->CharTy.getAsOpaquePtr();
  case eBasicTypeSignedChar:
    return ast->SignedCharTy.getAsOpaquePtr();
  case eBasicTypeUnsignedChar:
    return ast->UnsignedCharTy.getAsOpaquePtr();
  case eBasicTypeWChar:
    return ast->getWCharType().getAsOpaquePtr();
  case eBasicTypeSignedWChar:
    return ast->getSignedWCharType().getAsOpaquePtr();
  case eBasicTypeUnsignedWChar:
    return ast->getUnsignedWCharType().getAsOpaquePtr();
  case eBasicTypeChar16:
    return ast->Char16Ty.getAsOpaquePtr();
  case eBasicTypeChar32:
    return ast->Char32Ty.getAsOpaquePtr();
  case eBasicTypeShort:
    return ast->ShortTy.getAsOpaquePtr();
  case eBasicTypeUnsignedShort:
    return ast->UnsignedShortTy.getAsOpaquePtr();
  case eBasicTypeInt:
    return ast->IntTy.getAsOpaquePtr();
  case eBasicTypeUnsignedInt:
    return ast->UnsignedIntTy.getAsOpaquePtr();
  case eBasicTypeLong:
    return ast->LongTy.getAsOpaquePtr();
  case eBasicTypeUnsignedLong:
    return ast->UnsignedLongTy.getAsOpaquePtr();
  case eBasicTypeLongLong:
    return ast->LongLongTy.getAsOpaquePtr();
  case eBasicTypeUnsignedLongLong:
    return ast->UnsignedLongLongTy.getAsOpaquePtr();
  case eBasicTypeInt128:
    return ast->Int128Ty.getAsOpaquePtr();
  case eBasicTypeUnsignedInt128:
    return ast->UnsignedInt128Ty.getAsOpaquePtr();
  case eBasicTypeBool:
    return ast->BoolTy.getAsOpaquePtr();
  case eBasicTypeHalf:
    return ast->HalfTy.getAsOpaquePtr();
  case eBasicTypeFloat:
    return ast->FloatTy.getAsOpaquePtr();
  case eBasicTypeDouble:
    return ast->DoubleTy.getAsOpaquePtr();
  case eBasicTypeLongDouble:
    return ast->LongDoubleTy.getAsOpaquePtr();
  case eBasicTypeFloatComplex:
    return ast->FloatComplexTy.getAsOpaquePtr();
  case eBasicTypeDoubleComplex:
    return ast->DoubleComplexTy.getAsOpaquePtr();
  case eBasicTypeLongDoubleComplex:
    return ast->LongDoubleComplexTy.getAsOpaquePtr();
  case eBasicTypeObjCID:
    return ast->getObjCIdType().getAsOpaquePtr();
  case eBasicTypeObjCClass:
    return ast->getObjCClassType().getAsOpaquePtr();
  case eBasicTypeObjCSel:
    return ast->getObjCSelType().getAsOpaquePtr();
  case eBasicTypeNullPtr:
    return ast->NullPtrTy.getAsOpaquePtr();
  default:
    return nullptr;
  }
}

#pragma mark Function Types

clang::DeclarationName
ClangASTContext::GetDeclarationName(const char *name,
                                    const CompilerType &function_clang_type) {
  if (!name || !name[0])
    return clang::DeclarationName();

  clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
  if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
    return DeclarationName(&getASTContext()->Idents.get(
        name)); // Not operator, but a regular function.

  // Check the number of operator parameters. Sometimes we have seen bad DWARF
  // that doesn't correctly describe operators and if we try to create a method
  // and add it to the class, clang will assert and crash, so we need to make
  // sure things are acceptable.
  clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
  const clang::FunctionProtoType *function_type =
      llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
  if (function_type == nullptr)
    return clang::DeclarationName();

  const bool is_method = false;
  const unsigned int num_params = function_type->getNumParams();
  if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
          is_method, op_kind, num_params))
    return clang::DeclarationName();

  return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind);
}

FunctionDecl *ClangASTContext::CreateFunctionDeclaration(
    DeclContext *decl_ctx, const char *name,
    const CompilerType &function_clang_type, int storage, bool is_inline) {
  FunctionDecl *func_decl = nullptr;
  ASTContext *ast = getASTContext();
  if (decl_ctx == nullptr)
    decl_ctx = ast->getTranslationUnitDecl();

  const bool hasWrittenPrototype = true;
  const bool isConstexprSpecified = false;

  clang::DeclarationName declarationName =
      GetDeclarationName(name, function_clang_type);
  func_decl = FunctionDecl::Create(
      *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
      ClangUtil::GetQualType(function_clang_type), nullptr,
      (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
      isConstexprSpecified);
  if (func_decl)
    decl_ctx->addDecl(func_decl);

#ifdef LLDB_CONFIGURATION_DEBUG
  VerifyDecl(func_decl);
#endif

  return func_decl;
}

CompilerType ClangASTContext::CreateFunctionType(
    ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
    unsigned num_args, bool is_variadic, unsigned type_quals) {
  if (ast == nullptr)
    return CompilerType(); // invalid AST

  if (!result_type || !ClangUtil::IsClangType(result_type))
    return CompilerType(); // invalid return type

  std::vector<QualType> qual_type_args;
  if (num_args > 0 && args == nullptr)
    return CompilerType(); // invalid argument array passed in

  // Verify that all arguments are valid and the right type
  for (unsigned i = 0; i < num_args; ++i) {
    if (args[i]) {
      // Make sure we have a clang type in args[i] and not a type from another
      // language whose name might match
      const bool is_clang_type = ClangUtil::IsClangType(args[i]);
      lldbassert(is_clang_type);
      if (is_clang_type)
        qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
      else
        return CompilerType(); //  invalid argument type (must be a clang type)
    } else
      return CompilerType(); // invalid argument type (empty)
  }

  // TODO: Detect calling convention in DWARF?
  FunctionProtoType::ExtProtoInfo proto_info;
  proto_info.Variadic = is_variadic;
  proto_info.ExceptionSpec = EST_None;
  proto_info.TypeQuals = type_quals;
  proto_info.RefQualifier = RQ_None;

  return CompilerType(ast,
                      ast->getFunctionType(ClangUtil::GetQualType(result_type),
                                           qual_type_args, proto_info));
}

ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
    const char *name, const CompilerType &param_type, int storage) {
  ASTContext *ast = getASTContext();
  assert(ast != nullptr);
  return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(),
                             SourceLocation(), SourceLocation(),
                             name && name[0] ? &ast->Idents.get(name) : nullptr,
                             ClangUtil::GetQualType(param_type), nullptr,
                             (clang::StorageClass)storage, nullptr);
}

void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,
                                            ParmVarDecl **params,
                                            unsigned num_params) {
  if (function_decl)
    function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
}

CompilerType
ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) {
  QualType block_type = m_ast_ap->getBlockPointerType(
      clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));

  return CompilerType(this, block_type.getAsOpaquePtr());
}

#pragma mark Array Types

CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
                                              size_t element_count,
                                              bool is_vector) {
  if (element_type.IsValid()) {
    ASTContext *ast = getASTContext();
    assert(ast != nullptr);

    if (is_vector) {
      return CompilerType(
          ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
                                     element_count));
    } else {

      llvm::APInt ap_element_count(64, element_count);
      if (element_count == 0) {
        return CompilerType(ast, ast->getIncompleteArrayType(
                                     ClangUtil::GetQualType(element_type),
                                     clang::ArrayType::Normal, 0));
      } else {
        return CompilerType(
            ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
                                           ap_element_count,
                                           clang::ArrayType::Normal, 0));
      }
    }
  }
  return CompilerType();
}

CompilerType ClangASTContext::CreateStructForIdentifier(
    const ConstString &type_name,
    const std::initializer_list<std::pair<const char *, CompilerType>>
        &type_fields,
    bool packed) {
  CompilerType type;
  if (!type_name.IsEmpty() &&
      (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
          .IsValid()) {
    lldbassert(0 && "Trying to create a type for an existing name");
    return type;
  }

  type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
                          clang::TTK_Struct, lldb::eLanguageTypeC);
  StartTagDeclarationDefinition(type);
  for (const auto &field : type_fields)
    AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
                         0);
  if (packed)
    SetIsPacked(type);
  CompleteTagDeclarationDefinition(type);
  return type;
}

CompilerType ClangASTContext::GetOrCreateStructForIdentifier(
    const ConstString &type_name,
    const std::initializer_list<std::pair<const char *, CompilerType>>
        &type_fields,
    bool packed) {
  CompilerType type;
  if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
    return type;

  return CreateStructForIdentifier(type_name, type_fields, packed);
}

#pragma mark Enumeration Types

CompilerType
ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
                                       const Declaration &decl,
                                       const CompilerType &integer_clang_type,
                                       bool is_scoped) {
  // TODO: Do something intelligent with the Declaration object passed in
  // like maybe filling in the SourceLocation with it...
  ASTContext *ast = getASTContext();

  // TODO: ask about these...
  //    const bool IsFixed = false;

  EnumDecl *enum_decl = EnumDecl::Create(
      *ast, decl_ctx, SourceLocation(), SourceLocation(),
      name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
      is_scoped, // IsScoped
      is_scoped, // IsScopedUsingClassTag
      false);    // IsFixed

  if (enum_decl) {
    if (decl_ctx)
      decl_ctx->addDecl(enum_decl);

    // TODO: check if we should be setting the promotion type too?
    enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));

    enum_decl->setAccess(AS_public); // TODO respect what's in the debug info

    return CompilerType(ast, ast->getTagDeclType(enum_decl));
  }
  return CompilerType();
}

CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
                                                    size_t bit_size,
                                                    bool is_signed) {
  if (ast) {
    if (is_signed) {
      if (bit_size == ast->getTypeSize(ast->SignedCharTy))
        return CompilerType(ast, ast->SignedCharTy);

      if (bit_size == ast->getTypeSize(ast->ShortTy))
        return CompilerType(ast, ast->ShortTy);

      if (bit_size == ast->getTypeSize(ast->IntTy))
        return CompilerType(ast, ast->IntTy);

      if (bit_size == ast->getTypeSize(ast->LongTy))
        return CompilerType(ast, ast->LongTy);

      if (bit_size == ast->getTypeSize(ast->LongLongTy))
        return CompilerType(ast, ast->LongLongTy);

      if (bit_size == ast->getTypeSize(ast->Int128Ty))
        return CompilerType(ast, ast->Int128Ty);
    } else {
      if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
        return CompilerType(ast, ast->UnsignedCharTy);

      if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
        return CompilerType(ast, ast->UnsignedShortTy);

      if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
        return CompilerType(ast, ast->UnsignedIntTy);

      if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
        return CompilerType(ast, ast->UnsignedLongTy);

      if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
        return CompilerType(ast, ast->UnsignedLongLongTy);

      if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
        return CompilerType(ast, ast->UnsignedInt128Ty);
    }
  }
  return CompilerType();
}

CompilerType ClangASTContext::GetPointerSizedIntType(clang::ASTContext *ast,
                                                     bool is_signed) {
  if (ast)
    return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy),
                                 is_signed);
  return CompilerType();
}

void ClangASTContext::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
  if (decl_ctx) {
    DumpDeclContextHiearchy(decl_ctx->getParent());

    clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
    if (named_decl) {
      printf("%20s: %s\n", decl_ctx->getDeclKindName(),
             named_decl->getDeclName().getAsString().c_str());
    } else {
      printf("%20s\n", decl_ctx->getDeclKindName());
    }
  }
}

void ClangASTContext::DumpDeclHiearchy(clang::Decl *decl) {
  if (decl == nullptr)
    return;
  DumpDeclContextHiearchy(decl->getDeclContext());

  clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
  if (record_decl) {
    printf("%20s: %s%s\n", decl->getDeclKindName(),
           record_decl->getDeclName().getAsString().c_str(),
           record_decl->isInjectedClassName() ? " (injected class name)" : "");

  } else {
    clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
    if (named_decl) {
      printf("%20s: %s\n", decl->getDeclKindName(),
             named_decl->getDeclName().getAsString().c_str());
    } else {
      printf("%20s\n", decl->getDeclKindName());
    }
  }
}

bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
                                         clang::Decl *rhs_decl) {
  if (lhs_decl && rhs_decl) {
    //----------------------------------------------------------------------
    // Make sure the decl kinds match first
    //----------------------------------------------------------------------
    const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
    const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();

    if (lhs_decl_kind == rhs_decl_kind) {
      //------------------------------------------------------------------
      // Now check that the decl contexts kinds are all equivalent before we
      // have to check any names of the decl contexts...
      //------------------------------------------------------------------
      clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
      clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
      if (lhs_decl_ctx && rhs_decl_ctx) {
        while (1) {
          if (lhs_decl_ctx && rhs_decl_ctx) {
            const clang::Decl::Kind lhs_decl_ctx_kind =
                lhs_decl_ctx->getDeclKind();
            const clang::Decl::Kind rhs_decl_ctx_kind =
                rhs_decl_ctx->getDeclKind();
            if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
              lhs_decl_ctx = lhs_decl_ctx->getParent();
              rhs_decl_ctx = rhs_decl_ctx->getParent();

              if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
                break;
            } else
              return false;
          } else
            return false;
        }

        //--------------------------------------------------------------
        // Now make sure the name of the decls match
        //--------------------------------------------------------------
        clang::NamedDecl *lhs_named_decl =
            llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
        clang::NamedDecl *rhs_named_decl =
            llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
        if (lhs_named_decl && rhs_named_decl) {
          clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
          clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
          if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
            if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
              return false;
          } else
            return false;
        } else
          return false;

        //--------------------------------------------------------------
        // We know that the decl context kinds all match, so now we need to
        // make sure the names match as well
        //--------------------------------------------------------------
        lhs_decl_ctx = lhs_decl->getDeclContext();
        rhs_decl_ctx = rhs_decl->getDeclContext();
        while (1) {
          switch (lhs_decl_ctx->getDeclKind()) {
          case clang::Decl::TranslationUnit:
            // We don't care about the translation unit names
            return true;
          default: {
            clang::NamedDecl *lhs_named_decl =
                llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
            clang::NamedDecl *rhs_named_decl =
                llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
            if (lhs_named_decl && rhs_named_decl) {
              clang::DeclarationName lhs_decl_name =
                  lhs_named_decl->getDeclName();
              clang::DeclarationName rhs_decl_name =
                  rhs_named_decl->getDeclName();
              if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
                if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
                  return false;
              } else
                return false;
            } else
              return false;
          } break;
          }
          lhs_decl_ctx = lhs_decl_ctx->getParent();
          rhs_decl_ctx = rhs_decl_ctx->getParent();
        }
      }
    }
  }
  return false;
}
bool ClangASTContext::GetCompleteDecl(clang::ASTContext *ast,
                                      clang::Decl *decl) {
  if (!decl)
    return false;

  ExternalASTSource *ast_source = ast->getExternalSource();

  if (!ast_source)
    return false;

  if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
    if (tag_decl->isCompleteDefinition())
      return true;

    if (!tag_decl->hasExternalLexicalStorage())
      return false;

    ast_source->CompleteType(tag_decl);

    return !tag_decl->getTypeForDecl()->isIncompleteType();
  } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
                 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) {
    if (objc_interface_decl->getDefinition())
      return true;

    if (!objc_interface_decl->hasExternalLexicalStorage())
      return false;

    ast_source->CompleteType(objc_interface_decl);

    return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
  } else {
    return false;
  }
}

void ClangASTContext::SetMetadataAsUserID(const void *object,
                                          user_id_t user_id) {
  ClangASTMetadata meta_data;
  meta_data.SetUserID(user_id);
  SetMetadata(object, meta_data);
}

void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object,
                                  ClangASTMetadata &metadata) {
  ClangExternalASTSourceCommon *external_source =
      ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());

  if (external_source)
    external_source->SetMetadata(object, metadata);
}

ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast,
                                               const void *object) {
  ClangExternalASTSourceCommon *external_source =
      ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());

  if (external_source && external_source->HasMetadata(object))
    return external_source->GetMetadata(object);
  else
    return nullptr;
}

clang::DeclContext *
ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) {
  return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
}

clang::DeclContext *
ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) {
  return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
}

bool ClangASTContext::SetTagTypeKind(clang::QualType tag_qual_type,
                                     int kind) const {
  const clang::Type *clang_type = tag_qual_type.getTypePtr();
  if (clang_type) {
    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
    if (tag_type) {
      clang::TagDecl *tag_decl =
          llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
      if (tag_decl) {
        tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
        return true;
      }
    }
  }
  return false;
}

bool ClangASTContext::SetDefaultAccessForRecordFields(
    clang::RecordDecl *record_decl, int default_accessibility,
    int *assigned_accessibilities, size_t num_assigned_accessibilities) {
  if (record_decl) {
    uint32_t field_idx;
    clang::RecordDecl::field_iterator field, field_end;
    for (field = record_decl->field_begin(),
        field_end = record_decl->field_end(), field_idx = 0;
         field != field_end; ++field, ++field_idx) {
      // If no accessibility was assigned, assign the correct one
      if (field_idx < num_assigned_accessibilities &&
          assigned_accessibilities[field_idx] == clang::AS_none)
        field->setAccess((clang::AccessSpecifier)default_accessibility);
    }
    return true;
  }
  return false;
}

clang::DeclContext *
ClangASTContext::GetDeclContextForType(const CompilerType &type) {
  return GetDeclContextForType(ClangUtil::GetQualType(type));
}

clang::DeclContext *
ClangASTContext::GetDeclContextForType(clang::QualType type) {
  if (type.isNull())
    return nullptr;

  clang::QualType qual_type = type.getCanonicalType();
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::ObjCInterface:
    return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())
        ->getInterface();
  case clang::Type::ObjCObjectPointer:
    return GetDeclContextForType(
        llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
            ->getPointeeType());
  case clang::Type::Record:
    return llvm::cast<clang::RecordType>(qual_type)->getDecl();
  case clang::Type::Enum:
    return llvm::cast<clang::EnumType>(qual_type)->getDecl();
  case clang::Type::Typedef:
    return GetDeclContextForType(llvm::cast<clang::TypedefType>(qual_type)
                                     ->getDecl()
                                     ->getUnderlyingType());
  case clang::Type::Auto:
    return GetDeclContextForType(
        llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
  case clang::Type::Elaborated:
    return GetDeclContextForType(
        llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
  case clang::Type::Paren:
    return GetDeclContextForType(
        llvm::cast<clang::ParenType>(qual_type)->desugar());
  default:
    break;
  }
  // No DeclContext in this type...
  return nullptr;
}

static bool GetCompleteQualType(clang::ASTContext *ast,
                                clang::QualType qual_type,
                                bool allow_completion = true) {
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::ConstantArray:
  case clang::Type::IncompleteArray:
  case clang::Type::VariableArray: {
    const clang::ArrayType *array_type =
        llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());

    if (array_type)
      return GetCompleteQualType(ast, array_type->getElementType(),
                                 allow_completion);
  } break;
  case clang::Type::Record: {
    clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
    if (cxx_record_decl) {
      if (cxx_record_decl->hasExternalLexicalStorage()) {
        const bool is_complete = cxx_record_decl->isCompleteDefinition();
        const bool fields_loaded =
            cxx_record_decl->hasLoadedFieldsFromExternalStorage();
        if (is_complete && fields_loaded)
          return true;

        if (!allow_completion)
          return false;

        // Call the field_begin() accessor to for it to use the external source
        // to load the fields...
        clang::ExternalASTSource *external_ast_source =
            ast->getExternalSource();
        if (external_ast_source) {
          external_ast_source->CompleteType(cxx_record_decl);
          if (cxx_record_decl->isCompleteDefinition()) {
            cxx_record_decl->field_begin();
            cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
          }
        }
      }
    }
    const clang::TagType *tag_type =
        llvm::cast<clang::TagType>(qual_type.getTypePtr());
    return !tag_type->isIncompleteType();
  } break;

  case clang::Type::Enum: {
    const clang::TagType *tag_type =
        llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
    if (tag_type) {
      clang::TagDecl *tag_decl = tag_type->getDecl();
      if (tag_decl) {
        if (tag_decl->getDefinition())
          return true;

        if (!allow_completion)
          return false;

        if (tag_decl->hasExternalLexicalStorage()) {
          if (ast) {
            clang::ExternalASTSource *external_ast_source =
                ast->getExternalSource();
            if (external_ast_source) {
              external_ast_source->CompleteType(tag_decl);
              return !tag_type->isIncompleteType();
            }
          }
        }
        return false;
      }
    }

  } break;
  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface: {
    const clang::ObjCObjectType *objc_class_type =
        llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
    if (objc_class_type) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_class_type->getInterface();
      // We currently can't complete objective C types through the newly added
      // ASTContext because it only supports TagDecl objects right now...
      if (class_interface_decl) {
        if (class_interface_decl->getDefinition())
          return true;

        if (!allow_completion)
          return false;

        if (class_interface_decl->hasExternalLexicalStorage()) {
          if (ast) {
            clang::ExternalASTSource *external_ast_source =
                ast->getExternalSource();
            if (external_ast_source) {
              external_ast_source->CompleteType(class_interface_decl);
              return !objc_class_type->isIncompleteType();
            }
          }
        }
        return false;
      }
    }
  } break;

  case clang::Type::Typedef:
    return GetCompleteQualType(ast, llvm::cast<clang::TypedefType>(qual_type)
                                        ->getDecl()
                                        ->getUnderlyingType(),
                               allow_completion);

  case clang::Type::Auto:
    return GetCompleteQualType(
        ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(),
        allow_completion);

  case clang::Type::Elaborated:
    return GetCompleteQualType(
        ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(),
        allow_completion);

  case clang::Type::Paren:
    return GetCompleteQualType(
        ast, llvm::cast<clang::ParenType>(qual_type)->desugar(),
        allow_completion);

  case clang::Type::Attributed:
    return GetCompleteQualType(
        ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(),
        allow_completion);

  default:
    break;
  }

  return true;
}

static clang::ObjCIvarDecl::AccessControl
ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
  switch (access) {
  case eAccessNone:
    return clang::ObjCIvarDecl::None;
  case eAccessPublic:
    return clang::ObjCIvarDecl::Public;
  case eAccessPrivate:
    return clang::ObjCIvarDecl::Private;
  case eAccessProtected:
    return clang::ObjCIvarDecl::Protected;
  case eAccessPackage:
    return clang::ObjCIvarDecl::Package;
  }
  return clang::ObjCIvarDecl::None;
}

//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------

bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
  clang::QualType qual_type(GetCanonicalQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::IncompleteArray:
  case clang::Type::VariableArray:
  case clang::Type::ConstantArray:
  case clang::Type::ExtVector:
  case clang::Type::Vector:
  case clang::Type::Record:
  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface:
    return true;
  case clang::Type::Auto:
    return IsAggregateType(llvm::cast<clang::AutoType>(qual_type)
                               ->getDeducedType()
                               .getAsOpaquePtr());
  case clang::Type::Elaborated:
    return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)
                               ->getNamedType()
                               .getAsOpaquePtr());
  case clang::Type::Typedef:
    return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)
                               ->getDecl()
                               ->getUnderlyingType()
                               .getAsOpaquePtr());
  case clang::Type::Paren:
    return IsAggregateType(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
  default:
    break;
  }
  // The clang type does have a value
  return false;
}

bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) {
  clang::QualType qual_type(GetCanonicalQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record: {
    if (const clang::RecordType *record_type =
            llvm::dyn_cast_or_null<clang::RecordType>(
                qual_type.getTypePtrOrNull())) {
      if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
        return record_decl->isAnonymousStructOrUnion();
      }
    }
    break;
  }
  case clang::Type::Auto:
    return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type)
                               ->getDeducedType()
                               .getAsOpaquePtr());
  case clang::Type::Elaborated:
    return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)
                               ->getNamedType()
                               .getAsOpaquePtr());
  case clang::Type::Typedef:
    return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)
                               ->getDecl()
                               ->getUnderlyingType()
                               .getAsOpaquePtr());
  case clang::Type::Paren:
    return IsAnonymousType(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
  default:
    break;
  }
  // The clang type does have a value
  return false;
}

bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
                                  CompilerType *element_type_ptr,
                                  uint64_t *size, bool *is_incomplete) {
  clang::QualType qual_type(GetCanonicalQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  default:
    break;

  case clang::Type::ConstantArray:
    if (element_type_ptr)
      element_type_ptr->SetCompilerType(
          getASTContext(),
          llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
    if (size)
      *size = llvm::cast<clang::ConstantArrayType>(qual_type)
                  ->getSize()
                  .getLimitedValue(ULLONG_MAX);
    if (is_incomplete)
      *is_incomplete = false;
    return true;

  case clang::Type::IncompleteArray:
    if (element_type_ptr)
      element_type_ptr->SetCompilerType(
          getASTContext(),
          llvm::cast<clang::IncompleteArrayType>(qual_type)->getElementType());
    if (size)
      *size = 0;
    if (is_incomplete)
      *is_incomplete = true;
    return true;

  case clang::Type::VariableArray:
    if (element_type_ptr)
      element_type_ptr->SetCompilerType(
          getASTContext(),
          llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
    if (size)
      *size = 0;
    if (is_incomplete)
      *is_incomplete = false;
    return true;

  case clang::Type::DependentSizedArray:
    if (element_type_ptr)
      element_type_ptr->SetCompilerType(
          getASTContext(), llvm::cast<clang::DependentSizedArrayType>(qual_type)
                               ->getElementType());
    if (size)
      *size = 0;
    if (is_incomplete)
      *is_incomplete = false;
    return true;

  case clang::Type::Typedef:
    return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)
                           ->getDecl()
                           ->getUnderlyingType()
                           .getAsOpaquePtr(),
                       element_type_ptr, size, is_incomplete);
  case clang::Type::Auto:
    return IsArrayType(llvm::cast<clang::AutoType>(qual_type)
                           ->getDeducedType()
                           .getAsOpaquePtr(),
                       element_type_ptr, size, is_incomplete);
  case clang::Type::Elaborated:
    return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)
                           ->getNamedType()
                           .getAsOpaquePtr(),
                       element_type_ptr, size, is_incomplete);
  case clang::Type::Paren:
    return IsArrayType(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
        element_type_ptr, size, is_incomplete);
  }
  if (element_type_ptr)
    element_type_ptr->Clear();
  if (size)
    *size = 0;
  if (is_incomplete)
    *is_incomplete = false;
  return false;
}

bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
                                   CompilerType *element_type, uint64_t *size) {
  clang::QualType qual_type(GetCanonicalQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Vector: {
    const clang::VectorType *vector_type =
        qual_type->getAs<clang::VectorType>();
    if (vector_type) {
      if (size)
        *size = vector_type->getNumElements();
      if (element_type)
        *element_type =
            CompilerType(getASTContext(), vector_type->getElementType());
    }
    return true;
  } break;
  case clang::Type::ExtVector: {
    const clang::ExtVectorType *ext_vector_type =
        qual_type->getAs<clang::ExtVectorType>();
    if (ext_vector_type) {
      if (size)
        *size = ext_vector_type->getNumElements();
      if (element_type)
        *element_type =
            CompilerType(getASTContext(), ext_vector_type->getElementType());
    }
    return true;
  }
  default:
    break;
  }
  return false;
}

bool ClangASTContext::IsRuntimeGeneratedType(
    lldb::opaque_compiler_type_t type) {
  clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext())
                                     ->GetDeclContextForType(GetQualType(type));
  if (!decl_ctx)
    return false;

  if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
    return false;

  clang::ObjCInterfaceDecl *result_iface_decl =
      llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);

  ClangASTMetadata *ast_metadata =
      ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
  if (!ast_metadata)
    return false;
  return (ast_metadata->GetISAPtr() != 0);
}

bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
  return GetQualType(type).getUnqualifiedType()->isCharType();
}

bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
  const bool allow_completion = false;
  return GetCompleteQualType(getASTContext(), GetQualType(type),
                             allow_completion);
}

bool ClangASTContext::IsConst(lldb::opaque_compiler_type_t type) {
  return GetQualType(type).isConstQualified();
}

bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
                                    uint32_t &length) {
  CompilerType pointee_or_element_clang_type;
  length = 0;
  Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type));

  if (!pointee_or_element_clang_type.IsValid())
    return false;

  if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
    if (pointee_or_element_clang_type.IsCharType()) {
      if (type_flags.Test(eTypeIsArray)) {
        // We know the size of the array and it could be a C string since it is
        // an array of characters
        length = llvm::cast<clang::ConstantArrayType>(
                     GetCanonicalQualType(type).getTypePtr())
                     ->getSize()
                     .getLimitedValue();
      }
      return true;
    }
  }
  return false;
}

bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
                                     bool *is_variadic_ptr) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));

    if (qual_type->isFunctionType()) {
      if (is_variadic_ptr) {
        const clang::FunctionProtoType *function_proto_type =
            llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
        if (function_proto_type)
          *is_variadic_ptr = function_proto_type->isVariadic();
        else
          *is_variadic_ptr = false;
      }
      return true;
    }

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    default:
      break;
    case clang::Type::Typedef:
      return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)
                                ->getDecl()
                                ->getUnderlyingType()
                                .getAsOpaquePtr(),
                            nullptr);
    case clang::Type::Auto:
      return IsFunctionType(llvm::cast<clang::AutoType>(qual_type)
                                ->getDeducedType()
                                .getAsOpaquePtr(),
                            nullptr);
    case clang::Type::Elaborated:
      return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)
                                ->getNamedType()
                                .getAsOpaquePtr(),
                            nullptr);
    case clang::Type::Paren:
      return IsFunctionType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          nullptr);
    case clang::Type::LValueReference:
    case clang::Type::RValueReference: {
      const clang::ReferenceType *reference_type =
          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
      if (reference_type)
        return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
                              nullptr);
    } break;
    }
  }
  return false;
}

// Used to detect "Homogeneous Floating-point Aggregates"
uint32_t
ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
                                        CompilerType *base_type_ptr) {
  if (!type)
    return 0;

  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl) {
        if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
          return 0;
      }
      const clang::RecordType *record_type =
          llvm::cast<clang::RecordType>(qual_type.getTypePtr());
      if (record_type) {
        const clang::RecordDecl *record_decl = record_type->getDecl();
        if (record_decl) {
          // We are looking for a structure that contains only floating point
          // types
          clang::RecordDecl::field_iterator field_pos,
              field_end = record_decl->field_end();
          uint32_t num_fields = 0;
          bool is_hva = false;
          bool is_hfa = false;
          clang::QualType base_qual_type;
          uint64_t base_bitwidth = 0;
          for (field_pos = record_decl->field_begin(); field_pos != field_end;
               ++field_pos) {
            clang::QualType field_qual_type = field_pos->getType();
            uint64_t field_bitwidth = getASTContext()->getTypeSize(qual_type);
            if (field_qual_type->isFloatingType()) {
              if (field_qual_type->isComplexType())
                return 0;
              else {
                if (num_fields == 0)
                  base_qual_type = field_qual_type;
                else {
                  if (is_hva)
                    return 0;
                  is_hfa = true;
                  if (field_qual_type.getTypePtr() !=
                      base_qual_type.getTypePtr())
                    return 0;
                }
              }
            } else if (field_qual_type->isVectorType() ||
                       field_qual_type->isExtVectorType()) {
              if (num_fields == 0) {
                base_qual_type = field_qual_type;
                base_bitwidth = field_bitwidth;
              } else {
                if (is_hfa)
                  return 0;
                is_hva = true;
                if (base_bitwidth != field_bitwidth)
                  return 0;
                if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
                  return 0;
              }
            } else
              return 0;
            ++num_fields;
          }
          if (base_type_ptr)
            *base_type_ptr = CompilerType(getASTContext(), base_qual_type);
          return num_fields;
        }
      }
    }
    break;

  case clang::Type::Typedef:
    return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)
                                      ->getDecl()
                                      ->getUnderlyingType()
                                      .getAsOpaquePtr(),
                                  base_type_ptr);

  case clang::Type::Auto:
    return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type)
                                      ->getDeducedType()
                                      .getAsOpaquePtr(),
                                  base_type_ptr);

  case clang::Type::Elaborated:
    return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)
                                      ->getNamedType()
                                      .getAsOpaquePtr(),
                                  base_type_ptr);
  default:
    break;
  }
  return 0;
}

size_t ClangASTContext::GetNumberOfFunctionArguments(
    lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::FunctionProtoType *func =
        llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
    if (func)
      return func->getNumParams();
  }
  return 0;
}

CompilerType
ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
                                            const size_t index) {
  if (type) {
    clang::QualType qual_type(GetQualType(type));
    const clang::FunctionProtoType *func =
        llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
    if (func) {
      if (index < func->getNumParams())
        return CompilerType(getASTContext(), func->getParamType(index));
    }
  }
  return CompilerType();
}

bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));

    if (qual_type->isFunctionPointerType())
      return true;

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    default:
      break;
    case clang::Type::Typedef:
      return IsFunctionPointerType(llvm::cast<clang::TypedefType>(qual_type)
                                       ->getDecl()
                                       ->getUnderlyingType()
                                       .getAsOpaquePtr());
    case clang::Type::Auto:
      return IsFunctionPointerType(llvm::cast<clang::AutoType>(qual_type)
                                       ->getDeducedType()
                                       .getAsOpaquePtr());
    case clang::Type::Elaborated:
      return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
                                       ->getNamedType()
                                       .getAsOpaquePtr());
    case clang::Type::Paren:
      return IsFunctionPointerType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());

    case clang::Type::LValueReference:
    case clang::Type::RValueReference: {
      const clang::ReferenceType *reference_type =
          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
      if (reference_type)
        return IsFunctionPointerType(
            reference_type->getPointeeType().getAsOpaquePtr());
    } break;
    }
  }
  return false;
}

bool ClangASTContext::IsBlockPointerType(
    lldb::opaque_compiler_type_t type,
    CompilerType *function_pointer_type_ptr) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));

    if (qual_type->isBlockPointerType()) {
      if (function_pointer_type_ptr) {
        const clang::BlockPointerType *block_pointer_type =
            qual_type->getAs<clang::BlockPointerType>();
        QualType pointee_type = block_pointer_type->getPointeeType();
        QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type);
        *function_pointer_type_ptr =
            CompilerType(getASTContext(), function_pointer_type);
      }
      return true;
    }

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    default:
      break;
    case clang::Type::Typedef:
      return IsBlockPointerType(llvm::cast<clang::TypedefType>(qual_type)
                                    ->getDecl()
                                    ->getUnderlyingType()
                                    .getAsOpaquePtr(),
                                function_pointer_type_ptr);
    case clang::Type::Auto:
      return IsBlockPointerType(llvm::cast<clang::AutoType>(qual_type)
                                    ->getDeducedType()
                                    .getAsOpaquePtr(),
                                function_pointer_type_ptr);
    case clang::Type::Elaborated:
      return IsBlockPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
                                    ->getNamedType()
                                    .getAsOpaquePtr(),
                                function_pointer_type_ptr);
    case clang::Type::Paren:
      return IsBlockPointerType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          function_pointer_type_ptr);

    case clang::Type::LValueReference:
    case clang::Type::RValueReference: {
      const clang::ReferenceType *reference_type =
          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
      if (reference_type)
        return IsBlockPointerType(
            reference_type->getPointeeType().getAsOpaquePtr(),
            function_pointer_type_ptr);
    } break;
    }
  }
  return false;
}

bool ClangASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
                                    bool &is_signed) {
  if (!type)
    return false;

  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::BuiltinType *builtin_type =
      llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());

  if (builtin_type) {
    if (builtin_type->isInteger()) {
      is_signed = builtin_type->isSignedInteger();
      return true;
    }
  }

  return false;
}

bool ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type,
                                        bool &is_signed) {
  if (type) {
    const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
        GetCanonicalQualType(type)->getCanonicalTypeInternal());

    if (enum_type) {
      IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
                    is_signed);
      return true;
    }
  }

  return false;
}

bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
                                    CompilerType *pointee_type) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Builtin:
      switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
      default:
        break;
      case clang::BuiltinType::ObjCId:
      case clang::BuiltinType::ObjCClass:
        return true;
      }
      return false;
    case clang::Type::ObjCObjectPointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
                                 ->getPointeeType());
      return true;
    case clang::Type::BlockPointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
      return true;
    case clang::Type::Pointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
      return true;
    case clang::Type::MemberPointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
      return true;
    case clang::Type::Typedef:
      return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)
                               ->getDecl()
                               ->getUnderlyingType()
                               .getAsOpaquePtr(),
                           pointee_type);
    case clang::Type::Auto:
      return IsPointerType(llvm::cast<clang::AutoType>(qual_type)
                               ->getDeducedType()
                               .getAsOpaquePtr(),
                           pointee_type);
    case clang::Type::Elaborated:
      return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
                               ->getNamedType()
                               .getAsOpaquePtr(),
                           pointee_type);
    case clang::Type::Paren:
      return IsPointerType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          pointee_type);
    default:
      break;
    }
  }
  if (pointee_type)
    pointee_type->Clear();
  return false;
}

bool ClangASTContext::IsPointerOrReferenceType(
    lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Builtin:
      switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
      default:
        break;
      case clang::BuiltinType::ObjCId:
      case clang::BuiltinType::ObjCClass:
        return true;
      }
      return false;
    case clang::Type::ObjCObjectPointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
                                 ->getPointeeType());
      return true;
    case clang::Type::BlockPointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
      return true;
    case clang::Type::Pointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
      return true;
    case clang::Type::MemberPointer:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
      return true;
    case clang::Type::LValueReference:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
      return true;
    case clang::Type::RValueReference:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
      return true;
    case clang::Type::Typedef:
      return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)
                                          ->getDecl()
                                          ->getUnderlyingType()
                                          .getAsOpaquePtr(),
                                      pointee_type);
    case clang::Type::Auto:
      return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type)
                                          ->getDeducedType()
                                          .getAsOpaquePtr(),
                                      pointee_type);
    case clang::Type::Elaborated:
      return IsPointerOrReferenceType(
          llvm::cast<clang::ElaboratedType>(qual_type)
              ->getNamedType()
              .getAsOpaquePtr(),
          pointee_type);
    case clang::Type::Paren:
      return IsPointerOrReferenceType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          pointee_type);
    default:
      break;
    }
  }
  if (pointee_type)
    pointee_type->Clear();
  return false;
}

bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
                                      CompilerType *pointee_type,
                                      bool *is_rvalue) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();

    switch (type_class) {
    case clang::Type::LValueReference:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
      if (is_rvalue)
        *is_rvalue = false;
      return true;
    case clang::Type::RValueReference:
      if (pointee_type)
        pointee_type->SetCompilerType(
            getASTContext(),
            llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
      if (is_rvalue)
        *is_rvalue = true;
      return true;
    case clang::Type::Typedef:
      return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type)
                                 ->getDecl()
                                 ->getUnderlyingType()
                                 .getAsOpaquePtr(),
                             pointee_type, is_rvalue);
    case clang::Type::Auto:
      return IsReferenceType(llvm::cast<clang::AutoType>(qual_type)
                                 ->getDeducedType()
                                 .getAsOpaquePtr(),
                             pointee_type, is_rvalue);
    case clang::Type::Elaborated:
      return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)
                                 ->getNamedType()
                                 .getAsOpaquePtr(),
                             pointee_type, is_rvalue);
    case clang::Type::Paren:
      return IsReferenceType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          pointee_type, is_rvalue);

    default:
      break;
    }
  }
  if (pointee_type)
    pointee_type->Clear();
  return false;
}

bool ClangASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
                                          uint32_t &count, bool &is_complex) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));

    if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
            qual_type->getCanonicalTypeInternal())) {
      clang::BuiltinType::Kind kind = BT->getKind();
      if (kind >= clang::BuiltinType::Float &&
          kind <= clang::BuiltinType::LongDouble) {
        count = 1;
        is_complex = false;
        return true;
      }
    } else if (const clang::ComplexType *CT =
                   llvm::dyn_cast<clang::ComplexType>(
                       qual_type->getCanonicalTypeInternal())) {
      if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count,
                              is_complex)) {
        count = 2;
        is_complex = true;
        return true;
      }
    } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
                   qual_type->getCanonicalTypeInternal())) {
      if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count,
                              is_complex)) {
        count = VT->getNumElements();
        is_complex = false;
        return true;
      }
    }
  }
  count = 0;
  is_complex = false;
  return false;
}

bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;

  clang::QualType qual_type(GetQualType(type));
  const clang::TagType *tag_type =
      llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
  if (tag_type) {
    clang::TagDecl *tag_decl = tag_type->getDecl();
    if (tag_decl)
      return tag_decl->isCompleteDefinition();
    return false;
  } else {
    const clang::ObjCObjectType *objc_class_type =
        llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
    if (objc_class_type) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_class_type->getInterface();
      if (class_interface_decl)
        return class_interface_decl->getDefinition() != nullptr;
      return false;
    }
  }
  return true;
}

bool ClangASTContext::IsObjCClassType(const CompilerType &type) {
  if (type) {
    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));

    const clang::ObjCObjectPointerType *obj_pointer_type =
        llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);

    if (obj_pointer_type)
      return obj_pointer_type->isObjCClassType();
  }
  return false;
}

bool ClangASTContext::IsObjCObjectOrInterfaceType(const CompilerType &type) {
  if (ClangUtil::IsClangType(type))
    return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
  return false;
}

bool ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  return (type_class == clang::Type::Record);
}

bool ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  return (type_class == clang::Type::Enum);
}

bool ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Record:
      if (GetCompleteType(type)) {
        const clang::RecordType *record_type =
            llvm::cast<clang::RecordType>(qual_type.getTypePtr());
        const clang::RecordDecl *record_decl = record_type->getDecl();
        if (record_decl) {
          const clang::CXXRecordDecl *cxx_record_decl =
              llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
          if (cxx_record_decl)
            return cxx_record_decl->isPolymorphic();
        }
      }
      break;

    default:
      break;
    }
  }
  return false;
}

bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
                                            CompilerType *dynamic_pointee_type,
                                            bool check_cplusplus,
                                            bool check_objc) {
  clang::QualType pointee_qual_type;
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    bool success = false;
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Builtin:
      if (check_objc &&
          llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
              clang::BuiltinType::ObjCId) {
        if (dynamic_pointee_type)
          dynamic_pointee_type->SetCompilerType(this, type);
        return true;
      }
      break;

    case clang::Type::ObjCObjectPointer:
      if (check_objc) {
        if (auto objc_pointee_type =
                qual_type->getPointeeType().getTypePtrOrNull()) {
          if (auto objc_object_type =
                  llvm::dyn_cast_or_null<clang::ObjCObjectType>(
                      objc_pointee_type)) {
            if (objc_object_type->isObjCClass())
              return false;
          }
        }
        if (dynamic_pointee_type)
          dynamic_pointee_type->SetCompilerType(
              getASTContext(),
              llvm::cast<clang::ObjCObjectPointerType>(qual_type)
                  ->getPointeeType());
        return true;
      }
      break;

    case clang::Type::Pointer:
      pointee_qual_type =
          llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
      success = true;
      break;

    case clang::Type::LValueReference:
    case clang::Type::RValueReference:
      pointee_qual_type =
          llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
      success = true;
      break;

    case clang::Type::Typedef:
      return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type)
                                       ->getDecl()
                                       ->getUnderlyingType()
                                       .getAsOpaquePtr(),
                                   dynamic_pointee_type, check_cplusplus,
                                   check_objc);

    case clang::Type::Auto:
      return IsPossibleDynamicType(llvm::cast<clang::AutoType>(qual_type)
                                       ->getDeducedType()
                                       .getAsOpaquePtr(),
                                   dynamic_pointee_type, check_cplusplus,
                                   check_objc);

    case clang::Type::Elaborated:
      return IsPossibleDynamicType(llvm::cast<clang::ElaboratedType>(qual_type)
                                       ->getNamedType()
                                       .getAsOpaquePtr(),
                                   dynamic_pointee_type, check_cplusplus,
                                   check_objc);

    case clang::Type::Paren:
      return IsPossibleDynamicType(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          dynamic_pointee_type, check_cplusplus, check_objc);
    default:
      break;
    }

    if (success) {
      // Check to make sure what we are pointing too is a possible dynamic C++
      // type We currently accept any "void *" (in case we have a class that
      // has been watered down to an opaque pointer) and virtual C++ classes.
      const clang::Type::TypeClass pointee_type_class =
          pointee_qual_type.getCanonicalType()->getTypeClass();
      switch (pointee_type_class) {
      case clang::Type::Builtin:
        switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) {
        case clang::BuiltinType::UnknownAny:
        case clang::BuiltinType::Void:
          if (dynamic_pointee_type)
            dynamic_pointee_type->SetCompilerType(getASTContext(),
                                                  pointee_qual_type);
          return true;
        default:
          break;
        }
        break;

      case clang::Type::Record:
        if (check_cplusplus) {
          clang::CXXRecordDecl *cxx_record_decl =
              pointee_qual_type->getAsCXXRecordDecl();
          if (cxx_record_decl) {
            bool is_complete = cxx_record_decl->isCompleteDefinition();

            if (is_complete)
              success = cxx_record_decl->isDynamicClass();
            else {
              ClangASTMetadata *metadata = ClangASTContext::GetMetadata(
                  getASTContext(), cxx_record_decl);
              if (metadata)
                success = metadata->GetIsDynamicCXXType();
              else {
                is_complete = CompilerType(getASTContext(), pointee_qual_type)
                                  .GetCompleteType();
                if (is_complete)
                  success = cxx_record_decl->isDynamicClass();
                else
                  success = false;
              }
            }

            if (success) {
              if (dynamic_pointee_type)
                dynamic_pointee_type->SetCompilerType(getASTContext(),
                                                      pointee_qual_type);
              return true;
            }
          }
        }
        break;

      case clang::Type::ObjCObject:
      case clang::Type::ObjCInterface:
        if (check_objc) {
          if (dynamic_pointee_type)
            dynamic_pointee_type->SetCompilerType(getASTContext(),
                                                  pointee_qual_type);
          return true;
        }
        break;

      default:
        break;
      }
    }
  }
  if (dynamic_pointee_type)
    dynamic_pointee_type->Clear();
  return false;
}

bool ClangASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;

  return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
}

bool ClangASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
}

bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  return GetCanonicalQualType(type)->isVoidType();
}

bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) {
  return ClangASTContextSupportsLanguage(language);
}

bool ClangASTContext::GetCXXClassName(const CompilerType &type,
                                      std::string &class_name) {
  if (type) {
    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
    if (!qual_type.isNull()) {
      clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl) {
        class_name.assign(cxx_record_decl->getIdentifier()->getNameStart());
        return true;
      }
    }
  }
  class_name.clear();
  return false;
}

bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
  if (!type)
    return false;

  clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
  if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
    return true;
  return false;
}

bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
  if (tag_type)
    return tag_type->isBeingDefined();
  return false;
}

bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type,
                                              CompilerType *class_type_ptr) {
  if (!type)
    return false;

  clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));

  if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
    if (class_type_ptr) {
      if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
        const clang::ObjCObjectPointerType *obj_pointer_type =
            llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
        if (obj_pointer_type == nullptr)
          class_type_ptr->Clear();
        else
          class_type_ptr->SetCompilerType(
              type.GetTypeSystem(),
              clang::QualType(obj_pointer_type->getInterfaceType(), 0)
                  .getAsOpaquePtr());
      }
    }
    return true;
  }
  if (class_type_ptr)
    class_type_ptr->Clear();
  return false;
}

bool ClangASTContext::GetObjCClassName(const CompilerType &type,
                                       std::string &class_name) {
  if (!type)
    return false;

  clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));

  const clang::ObjCObjectType *object_type =
      llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
  if (object_type) {
    const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
    if (interface) {
      class_name = interface->getNameAsString();
      return true;
    }
  }
  return false;
}

//----------------------------------------------------------------------
// Type Completion
//----------------------------------------------------------------------

bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  const bool allow_completion = true;
  return GetCompleteQualType(getASTContext(), GetQualType(type),
                             allow_completion);
}

ConstString ClangASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
  std::string type_name;
  if (type) {
    clang::PrintingPolicy printing_policy(getASTContext()->getPrintingPolicy());
    clang::QualType qual_type(GetQualType(type));
    printing_policy.SuppressTagKeyword = true;
    const clang::TypedefType *typedef_type =
        qual_type->getAs<clang::TypedefType>();
    if (typedef_type) {
      const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
      type_name = typedef_decl->getQualifiedNameAsString();
    } else {
      type_name = qual_type.getAsString(printing_policy);
    }
  }
  return ConstString(type_name);
}

uint32_t
ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
                             CompilerType *pointee_or_element_clang_type) {
  if (!type)
    return 0;

  if (pointee_or_element_clang_type)
    pointee_or_element_clang_type->Clear();

  clang::QualType qual_type(GetQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Attributed:
    return GetTypeInfo(
        qual_type->getAs<clang::AttributedType>()
            ->getModifiedType().getAsOpaquePtr(),
        pointee_or_element_clang_type);
  case clang::Type::Builtin: {
    const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(
        qual_type->getCanonicalTypeInternal());

    uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
    switch (builtin_type->getKind()) {
    case clang::BuiltinType::ObjCId:
    case clang::BuiltinType::ObjCClass:
      if (pointee_or_element_clang_type)
        pointee_or_element_clang_type->SetCompilerType(
            getASTContext(), getASTContext()->ObjCBuiltinClassTy);
      builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
      break;

    case clang::BuiltinType::ObjCSel:
      if (pointee_or_element_clang_type)
        pointee_or_element_clang_type->SetCompilerType(getASTContext(),
                                                       getASTContext()->CharTy);
      builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
      break;

    case clang::BuiltinType::Bool:
    case clang::BuiltinType::Char_U:
    case clang::BuiltinType::UChar:
    case clang::BuiltinType::WChar_U:
    case clang::BuiltinType::Char16:
    case clang::BuiltinType::Char32:
    case clang::BuiltinType::UShort:
    case clang::BuiltinType::UInt:
    case clang::BuiltinType::ULong:
    case clang::BuiltinType::ULongLong:
    case clang::BuiltinType::UInt128:
    case clang::BuiltinType::Char_S:
    case clang::BuiltinType::SChar:
    case clang::BuiltinType::WChar_S:
    case clang::BuiltinType::Short:
    case clang::BuiltinType::Int:
    case clang::BuiltinType::Long:
    case clang::BuiltinType::LongLong:
    case clang::BuiltinType::Int128:
    case clang::BuiltinType::Float:
    case clang::BuiltinType::Double:
    case clang::BuiltinType::LongDouble:
      builtin_type_flags |= eTypeIsScalar;
      if (builtin_type->isInteger()) {
        builtin_type_flags |= eTypeIsInteger;
        if (builtin_type->isSignedInteger())
          builtin_type_flags |= eTypeIsSigned;
      } else if (builtin_type->isFloatingPoint())
        builtin_type_flags |= eTypeIsFloat;
      break;
    default:
      break;
    }
    return builtin_type_flags;
  }

  case clang::Type::BlockPointer:
    if (pointee_or_element_clang_type)
      pointee_or_element_clang_type->SetCompilerType(
          getASTContext(), qual_type->getPointeeType());
    return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;

  case clang::Type::Complex: {
    uint32_t complex_type_flags =
        eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
    const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
        qual_type->getCanonicalTypeInternal());
    if (complex_type) {
      clang::QualType complex_element_type(complex_type->getElementType());
      if (complex_element_type->isIntegerType())
        complex_type_flags |= eTypeIsFloat;
      else if (complex_element_type->isFloatingType())
        complex_type_flags |= eTypeIsInteger;
    }
    return complex_type_flags;
  } break;

  case clang::Type::ConstantArray:
  case clang::Type::DependentSizedArray:
  case clang::Type::IncompleteArray:
  case clang::Type::VariableArray:
    if (pointee_or_element_clang_type)
      pointee_or_element_clang_type->SetCompilerType(
          getASTContext(), llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
                               ->getElementType());
    return eTypeHasChildren | eTypeIsArray;

  case clang::Type::DependentName:
    return 0;
  case clang::Type::DependentSizedExtVector:
    return eTypeHasChildren | eTypeIsVector;
  case clang::Type::DependentTemplateSpecialization:
    return eTypeIsTemplate;
  case clang::Type::Decltype:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
        .GetTypeInfo(pointee_or_element_clang_type);

  case clang::Type::Enum:
    if (pointee_or_element_clang_type)
      pointee_or_element_clang_type->SetCompilerType(
          getASTContext(),
          llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
    return eTypeIsEnumeration | eTypeHasValue;

  case clang::Type::Auto:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
        .GetTypeInfo(pointee_or_element_clang_type);
  case clang::Type::Elaborated:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
        .GetTypeInfo(pointee_or_element_clang_type);
  case clang::Type::Paren:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::ParenType>(qual_type)->desugar())
        .GetTypeInfo(pointee_or_element_clang_type);

  case clang::Type::FunctionProto:
    return eTypeIsFuncPrototype | eTypeHasValue;
  case clang::Type::FunctionNoProto:
    return eTypeIsFuncPrototype | eTypeHasValue;
  case clang::Type::InjectedClassName:
    return 0;

  case clang::Type::LValueReference:
  case clang::Type::RValueReference:
    if (pointee_or_element_clang_type)
      pointee_or_element_clang_type->SetCompilerType(
          getASTContext(),
          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
              ->getPointeeType());
    return eTypeHasChildren | eTypeIsReference | eTypeHasValue;

  case clang::Type::MemberPointer:
    return eTypeIsPointer | eTypeIsMember | eTypeHasValue;

  case clang::Type::ObjCObjectPointer:
    if (pointee_or_element_clang_type)
      pointee_or_element_clang_type->SetCompilerType(
          getASTContext(), qual_type->getPointeeType());
    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
           eTypeHasValue;

  case clang::Type::ObjCObject:
    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
  case clang::Type::ObjCInterface:
    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;

  case clang::Type::Pointer:
    if (pointee_or_element_clang_type)
      pointee_or_element_clang_type->SetCompilerType(
          getASTContext(), qual_type->getPointeeType());
    return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;

  case clang::Type::Record:
    if (qual_type->getAsCXXRecordDecl())
      return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
    else
      return eTypeHasChildren | eTypeIsStructUnion;
    break;
  case clang::Type::SubstTemplateTypeParm:
    return eTypeIsTemplate;
  case clang::Type::TemplateTypeParm:
    return eTypeIsTemplate;
  case clang::Type::TemplateSpecialization:
    return eTypeIsTemplate;

  case clang::Type::Typedef:
    return eTypeIsTypedef |
           CompilerType(getASTContext(),
                        llvm::cast<clang::TypedefType>(qual_type)
                            ->getDecl()
                            ->getUnderlyingType())
               .GetTypeInfo(pointee_or_element_clang_type);
  case clang::Type::TypeOfExpr:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypeOfExprType>(qual_type)
                            ->getUnderlyingExpr()
                            ->getType())
        .GetTypeInfo(pointee_or_element_clang_type);
  case clang::Type::TypeOf:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
        .GetTypeInfo(pointee_or_element_clang_type);
  case clang::Type::UnresolvedUsing:
    return 0;

  case clang::Type::ExtVector:
  case clang::Type::Vector: {
    uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
    const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
        qual_type->getCanonicalTypeInternal());
    if (vector_type) {
      if (vector_type->isIntegerType())
        vector_type_flags |= eTypeIsFloat;
      else if (vector_type->isFloatingType())
        vector_type_flags |= eTypeIsInteger;
    }
    return vector_type_flags;
  }
  default:
    return 0;
  }
  return 0;
}

lldb::LanguageType
ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
  if (!type)
    return lldb::eLanguageTypeC;

  // If the type is a reference, then resolve it to what it refers to first:
  clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
  if (qual_type->isAnyPointerType()) {
    if (qual_type->isObjCObjectPointerType())
      return lldb::eLanguageTypeObjC;

    clang::QualType pointee_type(qual_type->getPointeeType());
    if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
      return lldb::eLanguageTypeC_plus_plus;
    if (pointee_type->isObjCObjectOrInterfaceType())
      return lldb::eLanguageTypeObjC;
    if (pointee_type->isObjCClassType())
      return lldb::eLanguageTypeObjC;
    if (pointee_type.getTypePtr() ==
        getASTContext()->ObjCBuiltinIdTy.getTypePtr())
      return lldb::eLanguageTypeObjC;
  } else {
    if (qual_type->isObjCObjectOrInterfaceType())
      return lldb::eLanguageTypeObjC;
    if (qual_type->getAsCXXRecordDecl())
      return lldb::eLanguageTypeC_plus_plus;
    switch (qual_type->getTypeClass()) {
    default:
      break;
    case clang::Type::Builtin:
      switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
      default:
      case clang::BuiltinType::Void:
      case clang::BuiltinType::Bool:
      case clang::BuiltinType::Char_U:
      case clang::BuiltinType::UChar:
      case clang::BuiltinType::WChar_U:
      case clang::BuiltinType::Char16:
      case clang::BuiltinType::Char32:
      case clang::BuiltinType::UShort:
      case clang::BuiltinType::UInt:
      case clang::BuiltinType::ULong:
      case clang::BuiltinType::ULongLong:
      case clang::BuiltinType::UInt128:
      case clang::BuiltinType::Char_S:
      case clang::BuiltinType::SChar:
      case clang::BuiltinType::WChar_S:
      case clang::BuiltinType::Short:
      case clang::BuiltinType::Int:
      case clang::BuiltinType::Long:
      case clang::BuiltinType::LongLong:
      case clang::BuiltinType::Int128:
      case clang::BuiltinType::Float:
      case clang::BuiltinType::Double:
      case clang::BuiltinType::LongDouble:
        break;

      case clang::BuiltinType::NullPtr:
        return eLanguageTypeC_plus_plus;

      case clang::BuiltinType::ObjCId:
      case clang::BuiltinType::ObjCClass:
      case clang::BuiltinType::ObjCSel:
        return eLanguageTypeObjC;

      case clang::BuiltinType::Dependent:
      case clang::BuiltinType::Overload:
      case clang::BuiltinType::BoundMember:
      case clang::BuiltinType::UnknownAny:
        break;
      }
      break;
    case clang::Type::Typedef:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::TypedefType>(qual_type)
                              ->getDecl()
                              ->getUnderlyingType())
          .GetMinimumLanguage();
    }
  }
  return lldb::eLanguageTypeC;
}

lldb::TypeClass
ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
  if (!type)
    return lldb::eTypeClassInvalid;

  clang::QualType qual_type(GetQualType(type));

  switch (qual_type->getTypeClass()) {
  case clang::Type::UnaryTransform:
    break;
  case clang::Type::FunctionNoProto:
    return lldb::eTypeClassFunction;
  case clang::Type::FunctionProto:
    return lldb::eTypeClassFunction;
  case clang::Type::IncompleteArray:
    return lldb::eTypeClassArray;
  case clang::Type::VariableArray:
    return lldb::eTypeClassArray;
  case clang::Type::ConstantArray:
    return lldb::eTypeClassArray;
  case clang::Type::DependentSizedArray:
    return lldb::eTypeClassArray;
  case clang::Type::DependentSizedExtVector:
    return lldb::eTypeClassVector;
  case clang::Type::DependentVector:
    return lldb::eTypeClassVector;
  case clang::Type::ExtVector:
    return lldb::eTypeClassVector;
  case clang::Type::Vector:
    return lldb::eTypeClassVector;
  case clang::Type::Builtin:
    return lldb::eTypeClassBuiltin;
  case clang::Type::ObjCObjectPointer:
    return lldb::eTypeClassObjCObjectPointer;
  case clang::Type::BlockPointer:
    return lldb::eTypeClassBlockPointer;
  case clang::Type::Pointer:
    return lldb::eTypeClassPointer;
  case clang::Type::LValueReference:
    return lldb::eTypeClassReference;
  case clang::Type::RValueReference:
    return lldb::eTypeClassReference;
  case clang::Type::MemberPointer:
    return lldb::eTypeClassMemberPointer;
  case clang::Type::Complex:
    if (qual_type->isComplexType())
      return lldb::eTypeClassComplexFloat;
    else
      return lldb::eTypeClassComplexInteger;
  case clang::Type::ObjCObject:
    return lldb::eTypeClassObjCObject;
  case clang::Type::ObjCInterface:
    return lldb::eTypeClassObjCInterface;
  case clang::Type::Record: {
    const clang::RecordType *record_type =
        llvm::cast<clang::RecordType>(qual_type.getTypePtr());
    const clang::RecordDecl *record_decl = record_type->getDecl();
    if (record_decl->isUnion())
      return lldb::eTypeClassUnion;
    else if (record_decl->isStruct())
      return lldb::eTypeClassStruct;
    else
      return lldb::eTypeClassClass;
  } break;
  case clang::Type::Enum:
    return lldb::eTypeClassEnumeration;
  case clang::Type::Typedef:
    return lldb::eTypeClassTypedef;
  case clang::Type::UnresolvedUsing:
    break;
  case clang::Type::Paren:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::ParenType>(qual_type)->desugar())
        .GetTypeClass();
  case clang::Type::Auto:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
        .GetTypeClass();
  case clang::Type::Elaborated:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
        .GetTypeClass();

  case clang::Type::Attributed:
    break;
  case clang::Type::TemplateTypeParm:
    break;
  case clang::Type::SubstTemplateTypeParm:
    break;
  case clang::Type::SubstTemplateTypeParmPack:
    break;
  case clang::Type::InjectedClassName:
    break;
  case clang::Type::DependentName:
    break;
  case clang::Type::DependentTemplateSpecialization:
    break;
  case clang::Type::PackExpansion:
    break;

  case clang::Type::TypeOfExpr:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypeOfExprType>(qual_type)
                            ->getUnderlyingExpr()
                            ->getType())
        .GetTypeClass();
  case clang::Type::TypeOf:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
        .GetTypeClass();
  case clang::Type::Decltype:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
        .GetTypeClass();
  case clang::Type::TemplateSpecialization:
    break;
  case clang::Type::DeducedTemplateSpecialization:
    break;
  case clang::Type::Atomic:
    break;
  case clang::Type::Pipe:
    break;

  // pointer type decayed from an array or function type.
  case clang::Type::Decayed:
    break;
  case clang::Type::Adjusted:
    break;
  case clang::Type::ObjCTypeParam:
    break;

  case clang::Type::DependentAddressSpace:
    break;
  }
  // We don't know hot to display this type...
  return lldb::eTypeClassOther;
}

unsigned ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
  if (type)
    return GetQualType(type).getQualifiers().getCVRQualifiers();
  return 0;
}

//----------------------------------------------------------------------
// Creating related types
//----------------------------------------------------------------------

CompilerType
ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
                                     uint64_t *stride) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));

    const clang::Type *array_eletype =
        qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();

    if (!array_eletype)
      return CompilerType();

    CompilerType element_type(getASTContext(),
                              array_eletype->getCanonicalTypeUnqualified());

    // TODO: the real stride will be >= this value.. find the real one!
    if (stride)
      *stride = element_type.GetByteSize(nullptr);

    return element_type;
  }
  return CompilerType();
}

CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
                                           uint64_t size) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    if (clang::ASTContext *ast_ctx = getASTContext()) {
      if (size != 0)
        return CompilerType(
            ast_ctx, ast_ctx->getConstantArrayType(
                         qual_type, llvm::APInt(64, size),
                         clang::ArrayType::ArraySizeModifier::Normal, 0));
      else
        return CompilerType(
            ast_ctx,
            ast_ctx->getIncompleteArrayType(
                qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0));
    }
  }

  return CompilerType();
}

CompilerType
ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
  if (type)
    return CompilerType(getASTContext(), GetCanonicalQualType(type));
  return CompilerType();
}

static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
                                                    clang::QualType qual_type) {
  if (qual_type->isPointerType())
    qual_type = ast->getPointerType(
        GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
  else
    qual_type = qual_type.getUnqualifiedType();
  qual_type.removeLocalConst();
  qual_type.removeLocalRestrict();
  qual_type.removeLocalVolatile();
  return qual_type;
}

CompilerType
ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
  if (type)
    return CompilerType(
        getASTContext(),
        GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)));
  return CompilerType();
}

int ClangASTContext::GetFunctionArgumentCount(
    lldb::opaque_compiler_type_t type) {
  if (type) {
    const clang::FunctionProtoType *func =
        llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
    if (func)
      return func->getNumParams();
  }
  return -1;
}

CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx) {
  if (type) {
    const clang::FunctionProtoType *func =
        llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
    if (func) {
      const uint32_t num_args = func->getNumParams();
      if (idx < num_args)
        return CompilerType(getASTContext(), func->getParamType(idx));
    }
  }
  return CompilerType();
}

CompilerType
ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetQualType(type));
    const clang::FunctionProtoType *func =
        llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
    if (func)
      return CompilerType(getASTContext(), func->getReturnType());
  }
  return CompilerType();
}

size_t
ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
  size_t num_functions = 0;
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    switch (qual_type->getTypeClass()) {
    case clang::Type::Record:
      if (GetCompleteQualType(getASTContext(), qual_type)) {
        const clang::RecordType *record_type =
            llvm::cast<clang::RecordType>(qual_type.getTypePtr());
        const clang::RecordDecl *record_decl = record_type->getDecl();
        assert(record_decl);
        const clang::CXXRecordDecl *cxx_record_decl =
            llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
        if (cxx_record_decl)
          num_functions = std::distance(cxx_record_decl->method_begin(),
                                        cxx_record_decl->method_end());
      }
      break;

    case clang::Type::ObjCObjectPointer: {
      const clang::ObjCObjectPointerType *objc_class_type =
          qual_type->getAs<clang::ObjCObjectPointerType>();
      const clang::ObjCInterfaceType *objc_interface_type =
          objc_class_type->getInterfaceType();
      if (objc_interface_type &&
          GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
              const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_interface_type->getDecl();
        if (class_interface_decl) {
          num_functions = std::distance(class_interface_decl->meth_begin(),
                                        class_interface_decl->meth_end());
        }
      }
      break;
    }

    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface:
      if (GetCompleteType(type)) {
        const clang::ObjCObjectType *objc_class_type =
            llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
        if (objc_class_type) {
          clang::ObjCInterfaceDecl *class_interface_decl =
              objc_class_type->getInterface();
          if (class_interface_decl)
            num_functions = std::distance(class_interface_decl->meth_begin(),
                                          class_interface_decl->meth_end());
        }
      }
      break;

    case clang::Type::Typedef:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::TypedefType>(qual_type)
                              ->getDecl()
                              ->getUnderlyingType())
          .GetNumMemberFunctions();

    case clang::Type::Auto:
      return CompilerType(
                 getASTContext(),
                 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
          .GetNumMemberFunctions();

    case clang::Type::Elaborated:
      return CompilerType(
                 getASTContext(),
                 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
          .GetNumMemberFunctions();

    case clang::Type::Paren:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::ParenType>(qual_type)->desugar())
          .GetNumMemberFunctions();

    default:
      break;
    }
  }
  return num_functions;
}

TypeMemberFunctionImpl
ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
                                          size_t idx) {
  std::string name;
  MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
  CompilerType clang_type;
  CompilerDecl clang_decl;
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    switch (qual_type->getTypeClass()) {
    case clang::Type::Record:
      if (GetCompleteQualType(getASTContext(), qual_type)) {
        const clang::RecordType *record_type =
            llvm::cast<clang::RecordType>(qual_type.getTypePtr());
        const clang::RecordDecl *record_decl = record_type->getDecl();
        assert(record_decl);
        const clang::CXXRecordDecl *cxx_record_decl =
            llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
        if (cxx_record_decl) {
          auto method_iter = cxx_record_decl->method_begin();
          auto method_end = cxx_record_decl->method_end();
          if (idx <
              static_cast<size_t>(std::distance(method_iter, method_end))) {
            std::advance(method_iter, idx);
            clang::CXXMethodDecl *cxx_method_decl =
                method_iter->getCanonicalDecl();
            if (cxx_method_decl) {
              name = cxx_method_decl->getDeclName().getAsString();
              if (cxx_method_decl->isStatic())
                kind = lldb::eMemberFunctionKindStaticMethod;
              else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
                kind = lldb::eMemberFunctionKindConstructor;
              else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
                kind = lldb::eMemberFunctionKindDestructor;
              else
                kind = lldb::eMemberFunctionKindInstanceMethod;
              clang_type = CompilerType(
                  this, cxx_method_decl->getType().getAsOpaquePtr());
              clang_decl = CompilerDecl(this, cxx_method_decl);
            }
          }
        }
      }
      break;

    case clang::Type::ObjCObjectPointer: {
      const clang::ObjCObjectPointerType *objc_class_type =
          qual_type->getAs<clang::ObjCObjectPointerType>();
      const clang::ObjCInterfaceType *objc_interface_type =
          objc_class_type->getInterfaceType();
      if (objc_interface_type &&
          GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
              const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_interface_type->getDecl();
        if (class_interface_decl) {
          auto method_iter = class_interface_decl->meth_begin();
          auto method_end = class_interface_decl->meth_end();
          if (idx <
              static_cast<size_t>(std::distance(method_iter, method_end))) {
            std::advance(method_iter, idx);
            clang::ObjCMethodDecl *objc_method_decl =
                method_iter->getCanonicalDecl();
            if (objc_method_decl) {
              clang_decl = CompilerDecl(this, objc_method_decl);
              name = objc_method_decl->getSelector().getAsString();
              if (objc_method_decl->isClassMethod())
                kind = lldb::eMemberFunctionKindStaticMethod;
              else
                kind = lldb::eMemberFunctionKindInstanceMethod;
            }
          }
        }
      }
      break;
    }

    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface:
      if (GetCompleteType(type)) {
        const clang::ObjCObjectType *objc_class_type =
            llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
        if (objc_class_type) {
          clang::ObjCInterfaceDecl *class_interface_decl =
              objc_class_type->getInterface();
          if (class_interface_decl) {
            auto method_iter = class_interface_decl->meth_begin();
            auto method_end = class_interface_decl->meth_end();
            if (idx <
                static_cast<size_t>(std::distance(method_iter, method_end))) {
              std::advance(method_iter, idx);
              clang::ObjCMethodDecl *objc_method_decl =
                  method_iter->getCanonicalDecl();
              if (objc_method_decl) {
                clang_decl = CompilerDecl(this, objc_method_decl);
                name = objc_method_decl->getSelector().getAsString();
                if (objc_method_decl->isClassMethod())
                  kind = lldb::eMemberFunctionKindStaticMethod;
                else
                  kind = lldb::eMemberFunctionKindInstanceMethod;
              }
            }
          }
        }
      }
      break;

    case clang::Type::Typedef:
      return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)
                                          ->getDecl()
                                          ->getUnderlyingType()
                                          .getAsOpaquePtr(),
                                      idx);

    case clang::Type::Auto:
      return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type)
                                          ->getDeducedType()
                                          .getAsOpaquePtr(),
                                      idx);

    case clang::Type::Elaborated:
      return GetMemberFunctionAtIndex(
          llvm::cast<clang::ElaboratedType>(qual_type)
              ->getNamedType()
              .getAsOpaquePtr(),
          idx);

    case clang::Type::Paren:
      return GetMemberFunctionAtIndex(
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
          idx);

    default:
      break;
    }
  }

  if (kind == eMemberFunctionKindUnknown)
    return TypeMemberFunctionImpl();
  else
    return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
}

CompilerType
ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
  if (type)
    return CompilerType(getASTContext(),
                        GetQualType(type).getNonReferenceType());
  return CompilerType();
}

CompilerType ClangASTContext::CreateTypedefType(
    const CompilerType &type, const char *typedef_name,
    const CompilerDeclContext &compiler_decl_ctx) {
  if (type && typedef_name && typedef_name[0]) {
    ClangASTContext *ast =
        llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
    if (!ast)
      return CompilerType();
    clang::ASTContext *clang_ast = ast->getASTContext();
    clang::QualType qual_type(ClangUtil::GetQualType(type));

    clang::DeclContext *decl_ctx =
        ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
    if (decl_ctx == nullptr)
      decl_ctx = ast->getASTContext()->getTranslationUnitDecl();

    clang::TypedefDecl *decl = clang::TypedefDecl::Create(
        *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
        &clang_ast->Idents.get(typedef_name),
        clang_ast->getTrivialTypeSourceInfo(qual_type));

    decl->setAccess(clang::AS_public); // TODO respect proper access specifier

    decl_ctx->addDecl(decl);

    // Get a uniqued clang::QualType for the typedef decl type
    return CompilerType(clang_ast, clang_ast->getTypedefType(decl));
  }
  return CompilerType();
}

CompilerType
ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetQualType(type));
    return CompilerType(getASTContext(),
                        qual_type.getTypePtr()->getPointeeType());
  }
  return CompilerType();
}

CompilerType
ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetQualType(type));

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface:
      return CompilerType(getASTContext(),
                          getASTContext()->getObjCObjectPointerType(qual_type));

    default:
      return CompilerType(getASTContext(),
                          getASTContext()->getPointerType(qual_type));
    }
  }
  return CompilerType();
}

CompilerType
ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
  if (type)
    return CompilerType(this, getASTContext()
                                  ->getLValueReferenceType(GetQualType(type))
                                  .getAsOpaquePtr());
  else
    return CompilerType();
}

CompilerType
ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
  if (type)
    return CompilerType(this, getASTContext()
                                  ->getRValueReferenceType(GetQualType(type))
                                  .getAsOpaquePtr());
  else
    return CompilerType();
}

CompilerType
ClangASTContext::AddConstModifier(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType result(GetQualType(type));
    result.addConst();
    return CompilerType(this, result.getAsOpaquePtr());
  }
  return CompilerType();
}

CompilerType
ClangASTContext::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType result(GetQualType(type));
    result.addVolatile();
    return CompilerType(this, result.getAsOpaquePtr());
  }
  return CompilerType();
}

CompilerType
ClangASTContext::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType result(GetQualType(type));
    result.addRestrict();
    return CompilerType(this, result.getAsOpaquePtr());
  }
  return CompilerType();
}

CompilerType
ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type,
                               const char *typedef_name,
                               const CompilerDeclContext &compiler_decl_ctx) {
  if (type) {
    clang::ASTContext *clang_ast = getASTContext();
    clang::QualType qual_type(GetQualType(type));

    clang::DeclContext *decl_ctx =
        ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
    if (decl_ctx == nullptr)
      decl_ctx = getASTContext()->getTranslationUnitDecl();

    clang::TypedefDecl *decl = clang::TypedefDecl::Create(
        *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
        &clang_ast->Idents.get(typedef_name),
        clang_ast->getTrivialTypeSourceInfo(qual_type));

    clang::TagDecl *tdecl = nullptr;
    if (!qual_type.isNull()) {
      if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
        tdecl = rt->getDecl();
      if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
        tdecl = et->getDecl();
    }

    // Check whether this declaration is an anonymous struct, union, or enum,
    // hidden behind a typedef. If so, we try to check whether we have a
    // typedef tag to attach to the original record declaration
    if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
      tdecl->setTypedefNameForAnonDecl(decl);

    decl->setAccess(clang::AS_public); // TODO respect proper access specifier

    // Get a uniqued clang::QualType for the typedef decl type
    return CompilerType(this, clang_ast->getTypedefType(decl).getAsOpaquePtr());
  }
  return CompilerType();
}

CompilerType
ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
  if (type) {
    const clang::TypedefType *typedef_type =
        llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
    if (typedef_type)
      return CompilerType(getASTContext(),
                          typedef_type->getDecl()->getUnderlyingType());
  }
  return CompilerType();
}

//----------------------------------------------------------------------
// Create related types using the current type's AST
//----------------------------------------------------------------------

CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
  return ClangASTContext::GetBasicType(getASTContext(), basic_type);
}
//----------------------------------------------------------------------
// Exploring the type
//----------------------------------------------------------------------

uint64_t ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
                                     ExecutionContextScope *exe_scope) {
  if (GetCompleteType(type)) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Record:
      if (GetCompleteType(type))
        return getASTContext()->getTypeSize(qual_type);
      else
        return 0;
      break;

    case clang::Type::ObjCInterface:
    case clang::Type::ObjCObject: {
      ExecutionContext exe_ctx(exe_scope);
      Process *process = exe_ctx.GetProcessPtr();
      if (process) {
        ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
        if (objc_runtime) {
          uint64_t bit_size = 0;
          if (objc_runtime->GetTypeBitSize(
                  CompilerType(getASTContext(), qual_type), bit_size))
            return bit_size;
        }
      } else {
        static bool g_printed = false;
        if (!g_printed) {
          StreamString s;
          DumpTypeDescription(type, &s);

          llvm::outs() << "warning: trying to determine the size of type ";
          llvm::outs() << s.GetString() << "\n";
          llvm::outs() << "without a valid ExecutionContext. this is not "
                          "reliable. please file a bug against LLDB.\n";
          llvm::outs() << "backtrace:\n";
          llvm::sys::PrintStackTrace(llvm::outs());
          llvm::outs() << "\n";
          g_printed = true;
        }
      }
    }
      LLVM_FALLTHROUGH;
    default:
      const uint32_t bit_size = getASTContext()->getTypeSize(qual_type);
      if (bit_size == 0) {
        if (qual_type->isIncompleteArrayType())
          return getASTContext()->getTypeSize(
              qual_type->getArrayElementTypeNoTypeQual()
                  ->getCanonicalTypeUnqualified());
      }
      if (qual_type->isObjCObjectOrInterfaceType())
        return bit_size +
               getASTContext()->getTypeSize(
                   getASTContext()->ObjCBuiltinClassTy);
      return bit_size;
    }
  }
  return 0;
}

size_t ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
  if (GetCompleteType(type))
    return getASTContext()->getTypeAlign(GetQualType(type));
  return 0;
}

lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
                                            uint64_t &count) {
  if (!type)
    return lldb::eEncodingInvalid;

  count = 1;
  clang::QualType qual_type(GetCanonicalQualType(type));

  switch (qual_type->getTypeClass()) {
  case clang::Type::UnaryTransform:
    break;

  case clang::Type::FunctionNoProto:
  case clang::Type::FunctionProto:
    break;

  case clang::Type::IncompleteArray:
  case clang::Type::VariableArray:
    break;

  case clang::Type::ConstantArray:
    break;

  case clang::Type::DependentVector:
  case clang::Type::ExtVector:
  case clang::Type::Vector:
    // TODO: Set this to more than one???
    break;

  case clang::Type::Builtin:
    switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
    case clang::BuiltinType::Void:
      break;

    case clang::BuiltinType::Bool:
    case clang::BuiltinType::Char_S:
    case clang::BuiltinType::SChar:
    case clang::BuiltinType::WChar_S:
    case clang::BuiltinType::Short:
    case clang::BuiltinType::Int:
    case clang::BuiltinType::Long:
    case clang::BuiltinType::LongLong:
    case clang::BuiltinType::Int128:
      return lldb::eEncodingSint;

    case clang::BuiltinType::Char_U:
    case clang::BuiltinType::UChar:
    case clang::BuiltinType::WChar_U:
    case clang::BuiltinType::Char8:
    case clang::BuiltinType::Char16:
    case clang::BuiltinType::Char32:
    case clang::BuiltinType::UShort:
    case clang::BuiltinType::UInt:
    case clang::BuiltinType::ULong:
    case clang::BuiltinType::ULongLong:
    case clang::BuiltinType::UInt128:
      return lldb::eEncodingUint;

    // Fixed point types. Note that they are currently ignored.
    case clang::BuiltinType::ShortAccum:
    case clang::BuiltinType::Accum:
    case clang::BuiltinType::LongAccum:
    case clang::BuiltinType::UShortAccum:
    case clang::BuiltinType::UAccum:
    case clang::BuiltinType::ULongAccum:
    case clang::BuiltinType::ShortFract:
    case clang::BuiltinType::Fract:
    case clang::BuiltinType::LongFract:
    case clang::BuiltinType::UShortFract:
    case clang::BuiltinType::UFract:
    case clang::BuiltinType::ULongFract:
    case clang::BuiltinType::SatShortAccum:
    case clang::BuiltinType::SatAccum:
    case clang::BuiltinType::SatLongAccum:
    case clang::BuiltinType::SatUShortAccum:
    case clang::BuiltinType::SatUAccum:
    case clang::BuiltinType::SatULongAccum:
    case clang::BuiltinType::SatShortFract:
    case clang::BuiltinType::SatFract:
    case clang::BuiltinType::SatLongFract:
    case clang::BuiltinType::SatUShortFract:
    case clang::BuiltinType::SatUFract:
    case clang::BuiltinType::SatULongFract:
      break;

    case clang::BuiltinType::Half:
    case clang::BuiltinType::Float:
    case clang::BuiltinType::Float16:
    case clang::BuiltinType::Float128:
    case clang::BuiltinType::Double:
    case clang::BuiltinType::LongDouble:
      return lldb::eEncodingIEEE754;

    case clang::BuiltinType::ObjCClass:
    case clang::BuiltinType::ObjCId:
    case clang::BuiltinType::ObjCSel:
      return lldb::eEncodingUint;

    case clang::BuiltinType::NullPtr:
      return lldb::eEncodingUint;

    case clang::BuiltinType::Kind::ARCUnbridgedCast:
    case clang::BuiltinType::Kind::BoundMember:
    case clang::BuiltinType::Kind::BuiltinFn:
    case clang::BuiltinType::Kind::Dependent:
    case clang::BuiltinType::Kind::OCLClkEvent:
    case clang::BuiltinType::Kind::OCLEvent:
    case clang::BuiltinType::Kind::OCLImage1dRO:
    case clang::BuiltinType::Kind::OCLImage1dWO:
    case clang::BuiltinType::Kind::OCLImage1dRW:
    case clang::BuiltinType::Kind::OCLImage1dArrayRO:
    case clang::BuiltinType::Kind::OCLImage1dArrayWO:
    case clang::BuiltinType::Kind::OCLImage1dArrayRW:
    case clang::BuiltinType::Kind::OCLImage1dBufferRO:
    case clang::BuiltinType::Kind::OCLImage1dBufferWO:
    case clang::BuiltinType::Kind::OCLImage1dBufferRW:
    case clang::BuiltinType::Kind::OCLImage2dRO:
    case clang::BuiltinType::Kind::OCLImage2dWO:
    case clang::BuiltinType::Kind::OCLImage2dRW:
    case clang::BuiltinType::Kind::OCLImage2dArrayRO:
    case clang::BuiltinType::Kind::OCLImage2dArrayWO:
    case clang::BuiltinType::Kind::OCLImage2dArrayRW:
    case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
    case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
    case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
    case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
    case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
    case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
    case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
    case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
    case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
    case clang::BuiltinType::Kind::OCLImage2dDepthRO:
    case clang::BuiltinType::Kind::OCLImage2dDepthWO:
    case clang::BuiltinType::Kind::OCLImage2dDepthRW:
    case clang::BuiltinType::Kind::OCLImage2dMSAARO:
    case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
    case clang::BuiltinType::Kind::OCLImage2dMSAARW:
    case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
    case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
    case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
    case clang::BuiltinType::Kind::OCLImage3dRO:
    case clang::BuiltinType::Kind::OCLImage3dWO:
    case clang::BuiltinType::Kind::OCLImage3dRW:
    case clang::BuiltinType::Kind::OCLQueue:
    case clang::BuiltinType::Kind::OCLReserveID:
    case clang::BuiltinType::Kind::OCLSampler:
    case clang::BuiltinType::Kind::OMPArraySection:
    case clang::BuiltinType::Kind::Overload:
    case clang::BuiltinType::Kind::PseudoObject:
    case clang::BuiltinType::Kind::UnknownAny:
      break;
    }
    break;
  // All pointer types are represented as unsigned integer encodings. We may
  // nee to add a eEncodingPointer if we ever need to know the difference
  case clang::Type::ObjCObjectPointer:
  case clang::Type::BlockPointer:
  case clang::Type::Pointer:
  case clang::Type::LValueReference:
  case clang::Type::RValueReference:
  case clang::Type::MemberPointer:
    return lldb::eEncodingUint;
  case clang::Type::Complex: {
    lldb::Encoding encoding = lldb::eEncodingIEEE754;
    if (qual_type->isComplexType())
      encoding = lldb::eEncodingIEEE754;
    else {
      const clang::ComplexType *complex_type =
          qual_type->getAsComplexIntegerType();
      if (complex_type)
        encoding = CompilerType(getASTContext(), complex_type->getElementType())
                       .GetEncoding(count);
      else
        encoding = lldb::eEncodingSint;
    }
    count = 2;
    return encoding;
  }

  case clang::Type::ObjCInterface:
    break;
  case clang::Type::Record:
    break;
  case clang::Type::Enum:
    return lldb::eEncodingSint;
  case clang::Type::Typedef:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypedefType>(qual_type)
                            ->getDecl()
                            ->getUnderlyingType())
        .GetEncoding(count);

  case clang::Type::Auto:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
        .GetEncoding(count);

  case clang::Type::Elaborated:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
        .GetEncoding(count);

  case clang::Type::Paren:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::ParenType>(qual_type)->desugar())
        .GetEncoding(count);
  case clang::Type::TypeOfExpr:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypeOfExprType>(qual_type)
                            ->getUnderlyingExpr()
                            ->getType())
        .GetEncoding(count);
  case clang::Type::TypeOf:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
        .GetEncoding(count);
  case clang::Type::Decltype:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
        .GetEncoding(count);
  case clang::Type::DependentSizedArray:
  case clang::Type::DependentSizedExtVector:
  case clang::Type::UnresolvedUsing:
  case clang::Type::Attributed:
  case clang::Type::TemplateTypeParm:
  case clang::Type::SubstTemplateTypeParm:
  case clang::Type::SubstTemplateTypeParmPack:
  case clang::Type::InjectedClassName:
  case clang::Type::DependentName:
  case clang::Type::DependentTemplateSpecialization:
  case clang::Type::PackExpansion:
  case clang::Type::ObjCObject:

  case clang::Type::TemplateSpecialization:
  case clang::Type::DeducedTemplateSpecialization:
  case clang::Type::Atomic:
  case clang::Type::Adjusted:
  case clang::Type::Pipe:
    break;

  // pointer type decayed from an array or function type.
  case clang::Type::Decayed:
    break;
  case clang::Type::ObjCTypeParam:
    break;

  case clang::Type::DependentAddressSpace:
    break;
  }
  count = 0;
  return lldb::eEncodingInvalid;
}

lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
  if (!type)
    return lldb::eFormatDefault;

  clang::QualType qual_type(GetCanonicalQualType(type));

  switch (qual_type->getTypeClass()) {
  case clang::Type::UnaryTransform:
    break;

  case clang::Type::FunctionNoProto:
  case clang::Type::FunctionProto:
    break;

  case clang::Type::IncompleteArray:
  case clang::Type::VariableArray:
    break;

  case clang::Type::ConstantArray:
    return lldb::eFormatVoid; // no value

  case clang::Type::DependentVector:
  case clang::Type::ExtVector:
  case clang::Type::Vector:
    break;

  case clang::Type::Builtin:
    switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
    // default: assert(0 && "Unknown builtin type!");
    case clang::BuiltinType::UnknownAny:
    case clang::BuiltinType::Void:
    case clang::BuiltinType::BoundMember:
      break;

    case clang::BuiltinType::Bool:
      return lldb::eFormatBoolean;
    case clang::BuiltinType::Char_S:
    case clang::BuiltinType::SChar:
    case clang::BuiltinType::WChar_S:
    case clang::BuiltinType::Char_U:
    case clang::BuiltinType::UChar:
    case clang::BuiltinType::WChar_U:
      return lldb::eFormatChar;
    case clang::BuiltinType::Char16:
      return lldb::eFormatUnicode16;
    case clang::BuiltinType::Char32:
      return lldb::eFormatUnicode32;
    case clang::BuiltinType::UShort:
      return lldb::eFormatUnsigned;
    case clang::BuiltinType::Short:
      return lldb::eFormatDecimal;
    case clang::BuiltinType::UInt:
      return lldb::eFormatUnsigned;
    case clang::BuiltinType::Int:
      return lldb::eFormatDecimal;
    case clang::BuiltinType::ULong:
      return lldb::eFormatUnsigned;
    case clang::BuiltinType::Long:
      return lldb::eFormatDecimal;
    case clang::BuiltinType::ULongLong:
      return lldb::eFormatUnsigned;
    case clang::BuiltinType::LongLong:
      return lldb::eFormatDecimal;
    case clang::BuiltinType::UInt128:
      return lldb::eFormatUnsigned;
    case clang::BuiltinType::Int128:
      return lldb::eFormatDecimal;
    case clang::BuiltinType::Half:
    case clang::BuiltinType::Float:
    case clang::BuiltinType::Double:
    case clang::BuiltinType::LongDouble:
      return lldb::eFormatFloat;
    default:
      return lldb::eFormatHex;
    }
    break;
  case clang::Type::ObjCObjectPointer:
    return lldb::eFormatHex;
  case clang::Type::BlockPointer:
    return lldb::eFormatHex;
  case clang::Type::Pointer:
    return lldb::eFormatHex;
  case clang::Type::LValueReference:
  case clang::Type::RValueReference:
    return lldb::eFormatHex;
  case clang::Type::MemberPointer:
    break;
  case clang::Type::Complex: {
    if (qual_type->isComplexType())
      return lldb::eFormatComplex;
    else
      return lldb::eFormatComplexInteger;
  }
  case clang::Type::ObjCInterface:
    break;
  case clang::Type::Record:
    break;
  case clang::Type::Enum:
    return lldb::eFormatEnum;
  case clang::Type::Typedef:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypedefType>(qual_type)
                            ->getDecl()
                            ->getUnderlyingType())
        .GetFormat();
  case clang::Type::Auto:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::AutoType>(qual_type)->desugar())
        .GetFormat();
  case clang::Type::Paren:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::ParenType>(qual_type)->desugar())
        .GetFormat();
  case clang::Type::Elaborated:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
        .GetFormat();
  case clang::Type::TypeOfExpr:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypeOfExprType>(qual_type)
                            ->getUnderlyingExpr()
                            ->getType())
        .GetFormat();
  case clang::Type::TypeOf:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
        .GetFormat();
  case clang::Type::Decltype:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
        .GetFormat();
  case clang::Type::DependentSizedArray:
  case clang::Type::DependentSizedExtVector:
  case clang::Type::UnresolvedUsing:
  case clang::Type::Attributed:
  case clang::Type::TemplateTypeParm:
  case clang::Type::SubstTemplateTypeParm:
  case clang::Type::SubstTemplateTypeParmPack:
  case clang::Type::InjectedClassName:
  case clang::Type::DependentName:
  case clang::Type::DependentTemplateSpecialization:
  case clang::Type::PackExpansion:
  case clang::Type::ObjCObject:

  case clang::Type::TemplateSpecialization:
  case clang::Type::DeducedTemplateSpecialization:
  case clang::Type::Atomic:
  case clang::Type::Adjusted:
  case clang::Type::Pipe:
    break;

  // pointer type decayed from an array or function type.
  case clang::Type::Decayed:
    break;
  case clang::Type::ObjCTypeParam:
    break;

  case clang::Type::DependentAddressSpace:
    break;
  }
  // We don't know hot to display this type...
  return lldb::eFormatBytes;
}

static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
                             bool check_superclass) {
  while (class_interface_decl) {
    if (class_interface_decl->ivar_size() > 0)
      return true;

    if (check_superclass)
      class_interface_decl = class_interface_decl->getSuperClass();
    else
      break;
  }
  return false;
}

uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
                                         bool omit_empty_base_classes) {
  if (!type)
    return 0;

  uint32_t num_children = 0;
  clang::QualType qual_type(GetQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Builtin:
    switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
    case clang::BuiltinType::ObjCId:    // child is Class
    case clang::BuiltinType::ObjCClass: // child is Class
      num_children = 1;
      break;

    default:
      break;
    }
    break;

  case clang::Type::Complex:
    return 0;

  case clang::Type::Record:
    if (GetCompleteQualType(getASTContext(), qual_type)) {
      const clang::RecordType *record_type =
          llvm::cast<clang::RecordType>(qual_type.getTypePtr());
      const clang::RecordDecl *record_decl = record_type->getDecl();
      assert(record_decl);
      const clang::CXXRecordDecl *cxx_record_decl =
          llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
      if (cxx_record_decl) {
        if (omit_empty_base_classes) {
          // Check each base classes to see if it or any of its base classes
          // contain any fields. This can help limit the noise in variable
          // views by not having to show base classes that contain no members.
          clang::CXXRecordDecl::base_class_const_iterator base_class,
              base_class_end;
          for (base_class = cxx_record_decl->bases_begin(),
              base_class_end = cxx_record_decl->bases_end();
               base_class != base_class_end; ++base_class) {
            const clang::CXXRecordDecl *base_class_decl =
                llvm::cast<clang::CXXRecordDecl>(
                    base_class->getType()
                        ->getAs<clang::RecordType>()
                        ->getDecl());

            // Skip empty base classes
            if (ClangASTContext::RecordHasFields(base_class_decl) == false)
              continue;

            num_children++;
          }
        } else {
          // Include all base classes
          num_children += cxx_record_decl->getNumBases();
        }
      }
      clang::RecordDecl::field_iterator field, field_end;
      for (field = record_decl->field_begin(),
          field_end = record_decl->field_end();
           field != field_end; ++field)
        ++num_children;
    }
    break;

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface:
    if (GetCompleteQualType(getASTContext(), qual_type)) {
      const clang::ObjCObjectType *objc_class_type =
          llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
      assert(objc_class_type);
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();

        if (class_interface_decl) {

          clang::ObjCInterfaceDecl *superclass_interface_decl =
              class_interface_decl->getSuperClass();
          if (superclass_interface_decl) {
            if (omit_empty_base_classes) {
              if (ObjCDeclHasIVars(superclass_interface_decl, true))
                ++num_children;
            } else
              ++num_children;
          }

          num_children += class_interface_decl->ivar_size();
        }
      }
    }
    break;

  case clang::Type::ObjCObjectPointer: {
    const clang::ObjCObjectPointerType *pointer_type =
        llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
    clang::QualType pointee_type = pointer_type->getPointeeType();
    uint32_t num_pointee_children =
        CompilerType(getASTContext(), pointee_type)
            .GetNumChildren(omit_empty_base_classes);
    // If this type points to a simple type, then it has 1 child
    if (num_pointee_children == 0)
      num_children = 1;
    else
      num_children = num_pointee_children;
  } break;

  case clang::Type::Vector:
  case clang::Type::ExtVector:
    num_children =
        llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
    break;

  case clang::Type::ConstantArray:
    num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())
                       ->getSize()
                       .getLimitedValue();
    break;

  case clang::Type::Pointer: {
    const clang::PointerType *pointer_type =
        llvm::cast<clang::PointerType>(qual_type.getTypePtr());
    clang::QualType pointee_type(pointer_type->getPointeeType());
    uint32_t num_pointee_children =
        CompilerType(getASTContext(), pointee_type)
            .GetNumChildren(omit_empty_base_classes);
    if (num_pointee_children == 0) {
      // We have a pointer to a pointee type that claims it has no children. We
      // will want to look at
      num_children = GetNumPointeeChildren(pointee_type);
    } else
      num_children = num_pointee_children;
  } break;

  case clang::Type::LValueReference:
  case clang::Type::RValueReference: {
    const clang::ReferenceType *reference_type =
        llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
    clang::QualType pointee_type = reference_type->getPointeeType();
    uint32_t num_pointee_children =
        CompilerType(getASTContext(), pointee_type)
            .GetNumChildren(omit_empty_base_classes);
    // If this type points to a simple type, then it has 1 child
    if (num_pointee_children == 0)
      num_children = 1;
    else
      num_children = num_pointee_children;
  } break;

  case clang::Type::Typedef:
    num_children =
        CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
                                          ->getDecl()
                                          ->getUnderlyingType())
            .GetNumChildren(omit_empty_base_classes);
    break;

  case clang::Type::Auto:
    num_children =
        CompilerType(getASTContext(),
                     llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
            .GetNumChildren(omit_empty_base_classes);
    break;

  case clang::Type::Elaborated:
    num_children =
        CompilerType(
            getASTContext(),
            llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
            .GetNumChildren(omit_empty_base_classes);
    break;

  case clang::Type::Paren:
    num_children =
        CompilerType(getASTContext(),
                     llvm::cast<clang::ParenType>(qual_type)->desugar())
            .GetNumChildren(omit_empty_base_classes);
    break;
  default:
    break;
  }
  return num_children;
}

CompilerType ClangASTContext::GetBuiltinTypeByName(const ConstString &name) {
  return GetBasicType(GetBasicTypeEnumeration(name));
}

lldb::BasicType
ClangASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
  if (type) {
    clang::QualType qual_type(GetQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    if (type_class == clang::Type::Builtin) {
      switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
      case clang::BuiltinType::Void:
        return eBasicTypeVoid;
      case clang::BuiltinType::Bool:
        return eBasicTypeBool;
      case clang::BuiltinType::Char_S:
        return eBasicTypeSignedChar;
      case clang::BuiltinType::Char_U:
        return eBasicTypeUnsignedChar;
      case clang::BuiltinType::Char16:
        return eBasicTypeChar16;
      case clang::BuiltinType::Char32:
        return eBasicTypeChar32;
      case clang::BuiltinType::UChar:
        return eBasicTypeUnsignedChar;
      case clang::BuiltinType::SChar:
        return eBasicTypeSignedChar;
      case clang::BuiltinType::WChar_S:
        return eBasicTypeSignedWChar;
      case clang::BuiltinType::WChar_U:
        return eBasicTypeUnsignedWChar;
      case clang::BuiltinType::Short:
        return eBasicTypeShort;
      case clang::BuiltinType::UShort:
        return eBasicTypeUnsignedShort;
      case clang::BuiltinType::Int:
        return eBasicTypeInt;
      case clang::BuiltinType::UInt:
        return eBasicTypeUnsignedInt;
      case clang::BuiltinType::Long:
        return eBasicTypeLong;
      case clang::BuiltinType::ULong:
        return eBasicTypeUnsignedLong;
      case clang::BuiltinType::LongLong:
        return eBasicTypeLongLong;
      case clang::BuiltinType::ULongLong:
        return eBasicTypeUnsignedLongLong;
      case clang::BuiltinType::Int128:
        return eBasicTypeInt128;
      case clang::BuiltinType::UInt128:
        return eBasicTypeUnsignedInt128;

      case clang::BuiltinType::Half:
        return eBasicTypeHalf;
      case clang::BuiltinType::Float:
        return eBasicTypeFloat;
      case clang::BuiltinType::Double:
        return eBasicTypeDouble;
      case clang::BuiltinType::LongDouble:
        return eBasicTypeLongDouble;

      case clang::BuiltinType::NullPtr:
        return eBasicTypeNullPtr;
      case clang::BuiltinType::ObjCId:
        return eBasicTypeObjCID;
      case clang::BuiltinType::ObjCClass:
        return eBasicTypeObjCClass;
      case clang::BuiltinType::ObjCSel:
        return eBasicTypeObjCSel;
      default:
        return eBasicTypeOther;
      }
    }
  }
  return eBasicTypeInvalid;
}

void ClangASTContext::ForEachEnumerator(
    lldb::opaque_compiler_type_t type,
    std::function<bool(const CompilerType &integer_type,
                       const ConstString &name,
                       const llvm::APSInt &value)> const &callback) {
  const clang::EnumType *enum_type =
      llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
  if (enum_type) {
    const clang::EnumDecl *enum_decl = enum_type->getDecl();
    if (enum_decl) {
      CompilerType integer_type(this,
                                enum_decl->getIntegerType().getAsOpaquePtr());

      clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
      for (enum_pos = enum_decl->enumerator_begin(),
          enum_end_pos = enum_decl->enumerator_end();
           enum_pos != enum_end_pos; ++enum_pos) {
        ConstString name(enum_pos->getNameAsString().c_str());
        if (!callback(integer_type, name, enum_pos->getInitVal()))
          break;
      }
    }
  }
}

#pragma mark Aggregate Types

uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
  if (!type)
    return 0;

  uint32_t count = 0;
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::RecordType *record_type =
          llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
      if (record_type) {
        clang::RecordDecl *record_decl = record_type->getDecl();
        if (record_decl) {
          uint32_t field_idx = 0;
          clang::RecordDecl::field_iterator field, field_end;
          for (field = record_decl->field_begin(),
              field_end = record_decl->field_end();
               field != field_end; ++field)
            ++field_idx;
          count = field_idx;
        }
      }
    }
    break;

  case clang::Type::Typedef:
    count =
        CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
                                          ->getDecl()
                                          ->getUnderlyingType())
            .GetNumFields();
    break;

  case clang::Type::Auto:
    count =
        CompilerType(getASTContext(),
                     llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
            .GetNumFields();
    break;

  case clang::Type::Elaborated:
    count = CompilerType(
                getASTContext(),
                llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
                .GetNumFields();
    break;

  case clang::Type::Paren:
    count = CompilerType(getASTContext(),
                         llvm::cast<clang::ParenType>(qual_type)->desugar())
                .GetNumFields();
    break;

  case clang::Type::ObjCObjectPointer: {
    const clang::ObjCObjectPointerType *objc_class_type =
        qual_type->getAs<clang::ObjCObjectPointerType>();
    const clang::ObjCInterfaceType *objc_interface_type =
        objc_class_type->getInterfaceType();
    if (objc_interface_type &&
        GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
            const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_interface_type->getDecl();
      if (class_interface_decl) {
        count = class_interface_decl->ivar_size();
      }
    }
    break;
  }

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface:
    if (GetCompleteType(type)) {
      const clang::ObjCObjectType *objc_class_type =
          llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();

        if (class_interface_decl)
          count = class_interface_decl->ivar_size();
      }
    }
    break;

  default:
    break;
  }
  return count;
}

static lldb::opaque_compiler_type_t
GetObjCFieldAtIndex(clang::ASTContext *ast,
                    clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
                    std::string &name, uint64_t *bit_offset_ptr,
                    uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
  if (class_interface_decl) {
    if (idx < (class_interface_decl->ivar_size())) {
      clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
          ivar_end = class_interface_decl->ivar_end();
      uint32_t ivar_idx = 0;

      for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
           ++ivar_pos, ++ivar_idx) {
        if (ivar_idx == idx) {
          const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;

          clang::QualType ivar_qual_type(ivar_decl->getType());

          name.assign(ivar_decl->getNameAsString());

          if (bit_offset_ptr) {
            const clang::ASTRecordLayout &interface_layout =
                ast->getASTObjCInterfaceLayout(class_interface_decl);
            *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx);
          }

          const bool is_bitfield = ivar_pos->isBitField();

          if (bitfield_bit_size_ptr) {
            *bitfield_bit_size_ptr = 0;

            if (is_bitfield && ast) {
              clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
              llvm::APSInt bitfield_apsint;
              if (bitfield_bit_size_expr &&
                  bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint,
                                                        *ast)) {
                *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
              }
            }
          }
          if (is_bitfield_ptr)
            *is_bitfield_ptr = is_bitfield;

          return ivar_qual_type.getAsOpaquePtr();
        }
      }
    }
  }
  return nullptr;
}

CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
                                              size_t idx, std::string &name,
                                              uint64_t *bit_offset_ptr,
                                              uint32_t *bitfield_bit_size_ptr,
                                              bool *is_bitfield_ptr) {
  if (!type)
    return CompilerType();

  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::RecordType *record_type =
          llvm::cast<clang::RecordType>(qual_type.getTypePtr());
      const clang::RecordDecl *record_decl = record_type->getDecl();
      uint32_t field_idx = 0;
      clang::RecordDecl::field_iterator field, field_end;
      for (field = record_decl->field_begin(),
          field_end = record_decl->field_end();
           field != field_end; ++field, ++field_idx) {
        if (idx == field_idx) {
          // Print the member type if requested
          // Print the member name and equal sign
          name.assign(field->getNameAsString());

          // Figure out the type byte size (field_type_info.first) and
          // alignment (field_type_info.second) from the AST context.
          if (bit_offset_ptr) {
            const clang::ASTRecordLayout &record_layout =
                getASTContext()->getASTRecordLayout(record_decl);
            *bit_offset_ptr = record_layout.getFieldOffset(field_idx);
          }

          const bool is_bitfield = field->isBitField();

          if (bitfield_bit_size_ptr) {
            *bitfield_bit_size_ptr = 0;

            if (is_bitfield) {
              clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
              llvm::APSInt bitfield_apsint;
              if (bitfield_bit_size_expr &&
                  bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint,
                                                        *getASTContext())) {
                *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
              }
            }
          }
          if (is_bitfield_ptr)
            *is_bitfield_ptr = is_bitfield;

          return CompilerType(getASTContext(), field->getType());
        }
      }
    }
    break;

  case clang::Type::ObjCObjectPointer: {
    const clang::ObjCObjectPointerType *objc_class_type =
        qual_type->getAs<clang::ObjCObjectPointerType>();
    const clang::ObjCInterfaceType *objc_interface_type =
        objc_class_type->getInterfaceType();
    if (objc_interface_type &&
        GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
            const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_interface_type->getDecl();
      if (class_interface_decl) {
        return CompilerType(
            this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
                                      idx, name, bit_offset_ptr,
                                      bitfield_bit_size_ptr, is_bitfield_ptr));
      }
    }
    break;
  }

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface:
    if (GetCompleteType(type)) {
      const clang::ObjCObjectType *objc_class_type =
          llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
      assert(objc_class_type);
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();
        return CompilerType(
            this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
                                      idx, name, bit_offset_ptr,
                                      bitfield_bit_size_ptr, is_bitfield_ptr));
      }
    }
    break;

  case clang::Type::Typedef:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::TypedefType>(qual_type)
                            ->getDecl()
                            ->getUnderlyingType())
        .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
                         is_bitfield_ptr);

  case clang::Type::Auto:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
        .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
                         is_bitfield_ptr);

  case clang::Type::Elaborated:
    return CompilerType(
               getASTContext(),
               llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
        .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
                         is_bitfield_ptr);

  case clang::Type::Paren:
    return CompilerType(getASTContext(),
                        llvm::cast<clang::ParenType>(qual_type)->desugar())
        .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
                         is_bitfield_ptr);

  default:
    break;
  }
  return CompilerType();
}

uint32_t
ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
  uint32_t count = 0;
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl)
        count = cxx_record_decl->getNumBases();
    }
    break;

  case clang::Type::ObjCObjectPointer:
    count = GetPointeeType(type).GetNumDirectBaseClasses();
    break;

  case clang::Type::ObjCObject:
    if (GetCompleteType(type)) {
      const clang::ObjCObjectType *objc_class_type =
          qual_type->getAsObjCQualifiedInterfaceType();
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();

        if (class_interface_decl && class_interface_decl->getSuperClass())
          count = 1;
      }
    }
    break;
  case clang::Type::ObjCInterface:
    if (GetCompleteType(type)) {
      const clang::ObjCInterfaceType *objc_interface_type =
          qual_type->getAs<clang::ObjCInterfaceType>();
      if (objc_interface_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_interface_type->getInterface();

        if (class_interface_decl && class_interface_decl->getSuperClass())
          count = 1;
      }
    }
    break;

  case clang::Type::Typedef:
    count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
                                        ->getDecl()
                                        ->getUnderlyingType()
                                        .getAsOpaquePtr());
    break;

  case clang::Type::Auto:
    count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type)
                                        ->getDeducedType()
                                        .getAsOpaquePtr());
    break;

  case clang::Type::Elaborated:
    count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
                                        ->getNamedType()
                                        .getAsOpaquePtr());
    break;

  case clang::Type::Paren:
    return GetNumDirectBaseClasses(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());

  default:
    break;
  }
  return count;
}

uint32_t
ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
  uint32_t count = 0;
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl)
        count = cxx_record_decl->getNumVBases();
    }
    break;

  case clang::Type::Typedef:
    count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
                                         ->getDecl()
                                         ->getUnderlyingType()
                                         .getAsOpaquePtr());
    break;

  case clang::Type::Auto:
    count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type)
                                         ->getDeducedType()
                                         .getAsOpaquePtr());
    break;

  case clang::Type::Elaborated:
    count =
        GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
                                     ->getNamedType()
                                     .getAsOpaquePtr());
    break;

  case clang::Type::Paren:
    count = GetNumVirtualBaseClasses(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
    break;

  default:
    break;
  }
  return count;
}

CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl) {
        uint32_t curr_idx = 0;
        clang::CXXRecordDecl::base_class_const_iterator base_class,
            base_class_end;
        for (base_class = cxx_record_decl->bases_begin(),
            base_class_end = cxx_record_decl->bases_end();
             base_class != base_class_end; ++base_class, ++curr_idx) {
          if (curr_idx == idx) {
            if (bit_offset_ptr) {
              const clang::ASTRecordLayout &record_layout =
                  getASTContext()->getASTRecordLayout(cxx_record_decl);
              const clang::CXXRecordDecl *base_class_decl =
                  llvm::cast<clang::CXXRecordDecl>(
                      base_class->getType()
                          ->getAs<clang::RecordType>()
                          ->getDecl());
              if (base_class->isVirtual())
                *bit_offset_ptr =
                    record_layout.getVBaseClassOffset(base_class_decl)
                        .getQuantity() *
                    8;
              else
                *bit_offset_ptr =
                    record_layout.getBaseClassOffset(base_class_decl)
                        .getQuantity() *
                    8;
            }
            return CompilerType(this, base_class->getType().getAsOpaquePtr());
          }
        }
      }
    }
    break;

  case clang::Type::ObjCObjectPointer:
    return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);

  case clang::Type::ObjCObject:
    if (idx == 0 && GetCompleteType(type)) {
      const clang::ObjCObjectType *objc_class_type =
          qual_type->getAsObjCQualifiedInterfaceType();
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();

        if (class_interface_decl) {
          clang::ObjCInterfaceDecl *superclass_interface_decl =
              class_interface_decl->getSuperClass();
          if (superclass_interface_decl) {
            if (bit_offset_ptr)
              *bit_offset_ptr = 0;
            return CompilerType(getASTContext(),
                                getASTContext()->getObjCInterfaceType(
                                    superclass_interface_decl));
          }
        }
      }
    }
    break;
  case clang::Type::ObjCInterface:
    if (idx == 0 && GetCompleteType(type)) {
      const clang::ObjCObjectType *objc_interface_type =
          qual_type->getAs<clang::ObjCInterfaceType>();
      if (objc_interface_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_interface_type->getInterface();

        if (class_interface_decl) {
          clang::ObjCInterfaceDecl *superclass_interface_decl =
              class_interface_decl->getSuperClass();
          if (superclass_interface_decl) {
            if (bit_offset_ptr)
              *bit_offset_ptr = 0;
            return CompilerType(getASTContext(),
                                getASTContext()->getObjCInterfaceType(
                                    superclass_interface_decl));
          }
        }
      }
    }
    break;

  case clang::Type::Typedef:
    return GetDirectBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
                                         ->getDecl()
                                         ->getUnderlyingType()
                                         .getAsOpaquePtr(),
                                     idx, bit_offset_ptr);

  case clang::Type::Auto:
    return GetDirectBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
                                         ->getDeducedType()
                                         .getAsOpaquePtr(),
                                     idx, bit_offset_ptr);

  case clang::Type::Elaborated:
    return GetDirectBaseClassAtIndex(
        llvm::cast<clang::ElaboratedType>(qual_type)
            ->getNamedType()
            .getAsOpaquePtr(),
        idx, bit_offset_ptr);

  case clang::Type::Paren:
    return GetDirectBaseClassAtIndex(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
        idx, bit_offset_ptr);

  default:
    break;
  }
  return CompilerType();
}

CompilerType ClangASTContext::GetVirtualBaseClassAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl) {
        uint32_t curr_idx = 0;
        clang::CXXRecordDecl::base_class_const_iterator base_class,
            base_class_end;
        for (base_class = cxx_record_decl->vbases_begin(),
            base_class_end = cxx_record_decl->vbases_end();
             base_class != base_class_end; ++base_class, ++curr_idx) {
          if (curr_idx == idx) {
            if (bit_offset_ptr) {
              const clang::ASTRecordLayout &record_layout =
                  getASTContext()->getASTRecordLayout(cxx_record_decl);
              const clang::CXXRecordDecl *base_class_decl =
                  llvm::cast<clang::CXXRecordDecl>(
                      base_class->getType()
                          ->getAs<clang::RecordType>()
                          ->getDecl());
              *bit_offset_ptr =
                  record_layout.getVBaseClassOffset(base_class_decl)
                      .getQuantity() *
                  8;
            }
            return CompilerType(this, base_class->getType().getAsOpaquePtr());
          }
        }
      }
    }
    break;

  case clang::Type::Typedef:
    return GetVirtualBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
                                          ->getDecl()
                                          ->getUnderlyingType()
                                          .getAsOpaquePtr(),
                                      idx, bit_offset_ptr);

  case clang::Type::Auto:
    return GetVirtualBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
                                          ->getDeducedType()
                                          .getAsOpaquePtr(),
                                      idx, bit_offset_ptr);

  case clang::Type::Elaborated:
    return GetVirtualBaseClassAtIndex(
        llvm::cast<clang::ElaboratedType>(qual_type)
            ->getNamedType()
            .getAsOpaquePtr(),
        idx, bit_offset_ptr);

  case clang::Type::Paren:
    return GetVirtualBaseClassAtIndex(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
        idx, bit_offset_ptr);

  default:
    break;
  }
  return CompilerType();
}

// If a pointer to a pointee type (the clang_type arg) says that it has no
// children, then we either need to trust it, or override it and return a
// different result. For example, an "int *" has one child that is an integer,
// but a function pointer doesn't have any children. Likewise if a Record type
// claims it has no children, then there really is nothing to show.
uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) {
  if (type.isNull())
    return 0;

  clang::QualType qual_type(type.getCanonicalType());
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Builtin:
    switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
    case clang::BuiltinType::UnknownAny:
    case clang::BuiltinType::Void:
    case clang::BuiltinType::NullPtr:
    case clang::BuiltinType::OCLEvent:
    case clang::BuiltinType::OCLImage1dRO:
    case clang::BuiltinType::OCLImage1dWO:
    case clang::BuiltinType::OCLImage1dRW:
    case clang::BuiltinType::OCLImage1dArrayRO:
    case clang::BuiltinType::OCLImage1dArrayWO:
    case clang::BuiltinType::OCLImage1dArrayRW:
    case clang::BuiltinType::OCLImage1dBufferRO:
    case clang::BuiltinType::OCLImage1dBufferWO:
    case clang::BuiltinType::OCLImage1dBufferRW:
    case clang::BuiltinType::OCLImage2dRO:
    case clang::BuiltinType::OCLImage2dWO:
    case clang::BuiltinType::OCLImage2dRW:
    case clang::BuiltinType::OCLImage2dArrayRO:
    case clang::BuiltinType::OCLImage2dArrayWO:
    case clang::BuiltinType::OCLImage2dArrayRW:
    case clang::BuiltinType::OCLImage3dRO:
    case clang::BuiltinType::OCLImage3dWO:
    case clang::BuiltinType::OCLImage3dRW:
    case clang::BuiltinType::OCLSampler:
      return 0;
    case clang::BuiltinType::Bool:
    case clang::BuiltinType::Char_U:
    case clang::BuiltinType::UChar:
    case clang::BuiltinType::WChar_U:
    case clang::BuiltinType::Char16:
    case clang::BuiltinType::Char32:
    case clang::BuiltinType::UShort:
    case clang::BuiltinType::UInt:
    case clang::BuiltinType::ULong:
    case clang::BuiltinType::ULongLong:
    case clang::BuiltinType::UInt128:
    case clang::BuiltinType::Char_S:
    case clang::BuiltinType::SChar:
    case clang::BuiltinType::WChar_S:
    case clang::BuiltinType::Short:
    case clang::BuiltinType::Int:
    case clang::BuiltinType::Long:
    case clang::BuiltinType::LongLong:
    case clang::BuiltinType::Int128:
    case clang::BuiltinType::Float:
    case clang::BuiltinType::Double:
    case clang::BuiltinType::LongDouble:
    case clang::BuiltinType::Dependent:
    case clang::BuiltinType::Overload:
    case clang::BuiltinType::ObjCId:
    case clang::BuiltinType::ObjCClass:
    case clang::BuiltinType::ObjCSel:
    case clang::BuiltinType::BoundMember:
    case clang::BuiltinType::Half:
    case clang::BuiltinType::ARCUnbridgedCast:
    case clang::BuiltinType::PseudoObject:
    case clang::BuiltinType::BuiltinFn:
    case clang::BuiltinType::OMPArraySection:
      return 1;
    default:
      return 0;
    }
    break;

  case clang::Type::Complex:
    return 1;
  case clang::Type::Pointer:
    return 1;
  case clang::Type::BlockPointer:
    return 0; // If block pointers don't have debug info, then no children for
              // them
  case clang::Type::LValueReference:
    return 1;
  case clang::Type::RValueReference:
    return 1;
  case clang::Type::MemberPointer:
    return 0;
  case clang::Type::ConstantArray:
    return 0;
  case clang::Type::IncompleteArray:
    return 0;
  case clang::Type::VariableArray:
    return 0;
  case clang::Type::DependentSizedArray:
    return 0;
  case clang::Type::DependentSizedExtVector:
    return 0;
  case clang::Type::Vector:
    return 0;
  case clang::Type::ExtVector:
    return 0;
  case clang::Type::FunctionProto:
    return 0; // When we function pointers, they have no children...
  case clang::Type::FunctionNoProto:
    return 0; // When we function pointers, they have no children...
  case clang::Type::UnresolvedUsing:
    return 0;
  case clang::Type::Paren:
    return GetNumPointeeChildren(
        llvm::cast<clang::ParenType>(qual_type)->desugar());
  case clang::Type::Typedef:
    return GetNumPointeeChildren(llvm::cast<clang::TypedefType>(qual_type)
                                     ->getDecl()
                                     ->getUnderlyingType());
  case clang::Type::Auto:
    return GetNumPointeeChildren(
        llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
  case clang::Type::Elaborated:
    return GetNumPointeeChildren(
        llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
  case clang::Type::TypeOfExpr:
    return GetNumPointeeChildren(llvm::cast<clang::TypeOfExprType>(qual_type)
                                     ->getUnderlyingExpr()
                                     ->getType());
  case clang::Type::TypeOf:
    return GetNumPointeeChildren(
        llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType());
  case clang::Type::Decltype:
    return GetNumPointeeChildren(
        llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType());
  case clang::Type::Record:
    return 0;
  case clang::Type::Enum:
    return 1;
  case clang::Type::TemplateTypeParm:
    return 1;
  case clang::Type::SubstTemplateTypeParm:
    return 1;
  case clang::Type::TemplateSpecialization:
    return 1;
  case clang::Type::InjectedClassName:
    return 0;
  case clang::Type::DependentName:
    return 1;
  case clang::Type::DependentTemplateSpecialization:
    return 1;
  case clang::Type::ObjCObject:
    return 0;
  case clang::Type::ObjCInterface:
    return 0;
  case clang::Type::ObjCObjectPointer:
    return 1;
  default:
    break;
  }
  return 0;
}

CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
    bool transparent_pointers, bool omit_empty_base_classes,
    bool ignore_array_bounds, std::string &child_name,
    uint32_t &child_byte_size, int32_t &child_byte_offset,
    uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
    bool &child_is_base_class, bool &child_is_deref_of_parent,
    ValueObject *valobj, uint64_t &language_flags) {
  if (!type)
    return CompilerType();

  clang::QualType parent_qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass parent_type_class =
      parent_qual_type->getTypeClass();
  child_bitfield_bit_size = 0;
  child_bitfield_bit_offset = 0;
  child_is_base_class = false;
  language_flags = 0;

  const bool idx_is_valid = idx < GetNumChildren(type, omit_empty_base_classes);
  int32_t bit_offset;
  switch (parent_type_class) {
  case clang::Type::Builtin:
    if (idx_is_valid) {
      switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) {
      case clang::BuiltinType::ObjCId:
      case clang::BuiltinType::ObjCClass:
        child_name = "isa";
        child_byte_size =
            getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) /
            CHAR_BIT;
        return CompilerType(getASTContext(),
                            getASTContext()->ObjCBuiltinClassTy);

      default:
        break;
      }
    }
    break;

  case clang::Type::Record:
    if (idx_is_valid && GetCompleteType(type)) {
      const clang::RecordType *record_type =
          llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
      const clang::RecordDecl *record_decl = record_type->getDecl();
      assert(record_decl);
      const clang::ASTRecordLayout &record_layout =
          getASTContext()->getASTRecordLayout(record_decl);
      uint32_t child_idx = 0;

      const clang::CXXRecordDecl *cxx_record_decl =
          llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
      if (cxx_record_decl) {
        // We might have base classes to print out first
        clang::CXXRecordDecl::base_class_const_iterator base_class,
            base_class_end;
        for (base_class = cxx_record_decl->bases_begin(),
            base_class_end = cxx_record_decl->bases_end();
             base_class != base_class_end; ++base_class) {
          const clang::CXXRecordDecl *base_class_decl = nullptr;

          // Skip empty base classes
          if (omit_empty_base_classes) {
            base_class_decl = llvm::cast<clang::CXXRecordDecl>(
                base_class->getType()->getAs<clang::RecordType>()->getDecl());
            if (ClangASTContext::RecordHasFields(base_class_decl) == false)
              continue;
          }

          if (idx == child_idx) {
            if (base_class_decl == nullptr)
              base_class_decl = llvm::cast<clang::CXXRecordDecl>(
                  base_class->getType()->getAs<clang::RecordType>()->getDecl());

            if (base_class->isVirtual()) {
              bool handled = false;
              if (valobj) {
                Status err;
                AddressType addr_type = eAddressTypeInvalid;
                lldb::addr_t vtable_ptr_addr =
                    valobj->GetCPPVTableAddress(addr_type);

                if (vtable_ptr_addr != LLDB_INVALID_ADDRESS &&
                    addr_type == eAddressTypeLoad) {

                  ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
                  Process *process = exe_ctx.GetProcessPtr();
                  if (process) {
                    clang::VTableContextBase *vtable_ctx =
                        getASTContext()->getVTableContext();
                    if (vtable_ctx) {
                      if (vtable_ctx->isMicrosoft()) {
                        clang::MicrosoftVTableContext *msoft_vtable_ctx =
                            static_cast<clang::MicrosoftVTableContext *>(
                                vtable_ctx);

                        if (vtable_ptr_addr) {
                          const lldb::addr_t vbtable_ptr_addr =
                              vtable_ptr_addr +
                              record_layout.getVBPtrOffset().getQuantity();

                          const lldb::addr_t vbtable_ptr =
                              process->ReadPointerFromMemory(vbtable_ptr_addr,
                                                             err);
                          if (vbtable_ptr != LLDB_INVALID_ADDRESS) {
                            // Get the index into the virtual base table. The
                            // index is the index in uint32_t from vbtable_ptr
                            const unsigned vbtable_index =
                                msoft_vtable_ctx->getVBTableIndex(
                                    cxx_record_decl, base_class_decl);
                            const lldb::addr_t base_offset_addr =
                                vbtable_ptr + vbtable_index * 4;
                            const int32_t base_offset =
                                process->ReadSignedIntegerFromMemory(
                                    base_offset_addr, 4, INT32_MAX, err);
                            if (base_offset != INT32_MAX) {
                              handled = true;
                              bit_offset = base_offset * 8;
                            }
                          }
                        }
                      } else {
                        clang::ItaniumVTableContext *itanium_vtable_ctx =
                            static_cast<clang::ItaniumVTableContext *>(
                                vtable_ctx);
                        if (vtable_ptr_addr) {
                          const lldb::addr_t vtable_ptr =
                              process->ReadPointerFromMemory(vtable_ptr_addr,
                                                             err);
                          if (vtable_ptr != LLDB_INVALID_ADDRESS) {
                            clang::CharUnits base_offset_offset =
                                itanium_vtable_ctx->getVirtualBaseOffsetOffset(
                                    cxx_record_decl, base_class_decl);
                            const lldb::addr_t base_offset_addr =
                                vtable_ptr + base_offset_offset.getQuantity();
                            const uint32_t base_offset_size =
                                process->GetAddressByteSize();
                            const int64_t base_offset =
                                process->ReadSignedIntegerFromMemory(
                                    base_offset_addr, base_offset_size,
                                    UINT32_MAX, err);
                            if (base_offset < UINT32_MAX) {
                              handled = true;
                              bit_offset = base_offset * 8;
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
              if (!handled)
                bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
                                 .getQuantity() *
                             8;
            } else
              bit_offset = record_layout.getBaseClassOffset(base_class_decl)
                               .getQuantity() *
                           8;

            // Base classes should be a multiple of 8 bits in size
            child_byte_offset = bit_offset / 8;
            CompilerType base_class_clang_type(getASTContext(),
                                               base_class->getType());
            child_name = base_class_clang_type.GetTypeName().AsCString("");
            uint64_t base_class_clang_type_bit_size =
                base_class_clang_type.GetBitSize(
                    exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);

            // Base classes bit sizes should be a multiple of 8 bits in size
            assert(base_class_clang_type_bit_size % 8 == 0);
            child_byte_size = base_class_clang_type_bit_size / 8;
            child_is_base_class = true;
            return base_class_clang_type;
          }
          // We don't increment the child index in the for loop since we might
          // be skipping empty base classes
          ++child_idx;
        }
      }
      // Make sure index is in range...
      uint32_t field_idx = 0;
      clang::RecordDecl::field_iterator field, field_end;
      for (field = record_decl->field_begin(),
          field_end = record_decl->field_end();
           field != field_end; ++field, ++field_idx, ++child_idx) {
        if (idx == child_idx) {
          // Print the member type if requested
          // Print the member name and equal sign
          child_name.assign(field->getNameAsString());

          // Figure out the type byte size (field_type_info.first) and
          // alignment (field_type_info.second) from the AST context.
          CompilerType field_clang_type(getASTContext(), field->getType());
          assert(field_idx < record_layout.getFieldCount());
          child_byte_size = field_clang_type.GetByteSize(
              exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
          const uint32_t child_bit_size = child_byte_size * 8;

          // Figure out the field offset within the current struct/union/class
          // type
          bit_offset = record_layout.getFieldOffset(field_idx);
          if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
                                               child_bitfield_bit_size)) {
            child_bitfield_bit_offset = bit_offset % child_bit_size;
            const uint32_t child_bit_offset =
                bit_offset - child_bitfield_bit_offset;
            child_byte_offset = child_bit_offset / 8;
          } else {
            child_byte_offset = bit_offset / 8;
          }

          return field_clang_type;
        }
      }
    }
    break;

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface:
    if (idx_is_valid && GetCompleteType(type)) {
      const clang::ObjCObjectType *objc_class_type =
          llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
      assert(objc_class_type);
      if (objc_class_type) {
        uint32_t child_idx = 0;
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();

        if (class_interface_decl) {

          const clang::ASTRecordLayout &interface_layout =
              getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
          clang::ObjCInterfaceDecl *superclass_interface_decl =
              class_interface_decl->getSuperClass();
          if (superclass_interface_decl) {
            if (omit_empty_base_classes) {
              CompilerType base_class_clang_type(
                  getASTContext(), getASTContext()->getObjCInterfaceType(
                                       superclass_interface_decl));
              if (base_class_clang_type.GetNumChildren(
                      omit_empty_base_classes) > 0) {
                if (idx == 0) {
                  clang::QualType ivar_qual_type(
                      getASTContext()->getObjCInterfaceType(
                          superclass_interface_decl));

                  child_name.assign(
                      superclass_interface_decl->getNameAsString());

                  clang::TypeInfo ivar_type_info =
                      getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());

                  child_byte_size = ivar_type_info.Width / 8;
                  child_byte_offset = 0;
                  child_is_base_class = true;

                  return CompilerType(getASTContext(), ivar_qual_type);
                }

                ++child_idx;
              }
            } else
              ++child_idx;
          }

          const uint32_t superclass_idx = child_idx;

          if (idx < (child_idx + class_interface_decl->ivar_size())) {
            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
                ivar_end = class_interface_decl->ivar_end();

            for (ivar_pos = class_interface_decl->ivar_begin();
                 ivar_pos != ivar_end; ++ivar_pos) {
              if (child_idx == idx) {
                clang::ObjCIvarDecl *ivar_decl = *ivar_pos;

                clang::QualType ivar_qual_type(ivar_decl->getType());

                child_name.assign(ivar_decl->getNameAsString());

                clang::TypeInfo ivar_type_info =
                    getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());

                child_byte_size = ivar_type_info.Width / 8;

                // Figure out the field offset within the current
                // struct/union/class type For ObjC objects, we can't trust the
                // bit offset we get from the Clang AST, since that doesn't
                // account for the space taken up by unbacked properties, or
                // from the changing size of base classes that are newer than
                // this class. So if we have a process around that we can ask
                // about this object, do so.
                child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
                Process *process = nullptr;
                if (exe_ctx)
                  process = exe_ctx->GetProcessPtr();
                if (process) {
                  ObjCLanguageRuntime *objc_runtime =
                      process->GetObjCLanguageRuntime();
                  if (objc_runtime != nullptr) {
                    CompilerType parent_ast_type(getASTContext(),
                                                 parent_qual_type);
                    child_byte_offset = objc_runtime->GetByteOffsetForIvar(
                        parent_ast_type, ivar_decl->getNameAsString().c_str());
                  }
                }

                // Setting this to INT32_MAX to make sure we don't compute it
                // twice...
                bit_offset = INT32_MAX;

                if (child_byte_offset ==
                    static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
                  bit_offset = interface_layout.getFieldOffset(child_idx -
                                                               superclass_idx);
                  child_byte_offset = bit_offset / 8;
                }

                // Note, the ObjC Ivar Byte offset is just that, it doesn't
                // account for the bit offset of a bitfield within its
                // containing object.  So regardless of where we get the byte
                // offset from, we still need to get the bit offset for
                // bitfields from the layout.

                if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl,
                                                     child_bitfield_bit_size)) {
                  if (bit_offset == INT32_MAX)
                    bit_offset = interface_layout.getFieldOffset(
                        child_idx - superclass_idx);

                  child_bitfield_bit_offset = bit_offset % 8;
                }
                return CompilerType(getASTContext(), ivar_qual_type);
              }
              ++child_idx;
            }
          }
        }
      }
    }
    break;

  case clang::Type::ObjCObjectPointer:
    if (idx_is_valid) {
      CompilerType pointee_clang_type(GetPointeeType(type));

      if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
        child_is_deref_of_parent = false;
        bool tmp_child_is_deref_of_parent = false;
        return pointee_clang_type.GetChildCompilerTypeAtIndex(
            exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
            ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
            child_bitfield_bit_size, child_bitfield_bit_offset,
            child_is_base_class, tmp_child_is_deref_of_parent, valobj,
            language_flags);
      } else {
        child_is_deref_of_parent = true;
        const char *parent_name =
            valobj ? valobj->GetName().GetCString() : NULL;
        if (parent_name) {
          child_name.assign(1, '*');
          child_name += parent_name;
        }

        // We have a pointer to an simple type
        if (idx == 0 && pointee_clang_type.GetCompleteType()) {
          child_byte_size = pointee_clang_type.GetByteSize(
              exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
          child_byte_offset = 0;
          return pointee_clang_type;
        }
      }
    }
    break;

  case clang::Type::Vector:
  case clang::Type::ExtVector:
    if (idx_is_valid) {
      const clang::VectorType *array =
          llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
      if (array) {
        CompilerType element_type(getASTContext(), array->getElementType());
        if (element_type.GetCompleteType()) {
          char element_name[64];
          ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
                     static_cast<uint64_t>(idx));
          child_name.assign(element_name);
          child_byte_size = element_type.GetByteSize(
              exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
          child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
          return element_type;
        }
      }
    }
    break;

  case clang::Type::ConstantArray:
  case clang::Type::IncompleteArray:
    if (ignore_array_bounds || idx_is_valid) {
      const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
      if (array) {
        CompilerType element_type(getASTContext(), array->getElementType());
        if (element_type.GetCompleteType()) {
          child_name = llvm::formatv("[{0}]", idx);
          child_byte_size = element_type.GetByteSize(
              exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
          child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
          return element_type;
        }
      }
    }
    break;

  case clang::Type::Pointer: {
    CompilerType pointee_clang_type(GetPointeeType(type));

    // Don't dereference "void *" pointers
    if (pointee_clang_type.IsVoidType())
      return CompilerType();

    if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
      child_is_deref_of_parent = false;
      bool tmp_child_is_deref_of_parent = false;
      return pointee_clang_type.GetChildCompilerTypeAtIndex(
          exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
          ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
          child_bitfield_bit_size, child_bitfield_bit_offset,
          child_is_base_class, tmp_child_is_deref_of_parent, valobj,
          language_flags);
    } else {
      child_is_deref_of_parent = true;

      const char *parent_name =
          valobj ? valobj->GetName().GetCString() : NULL;
      if (parent_name) {
        child_name.assign(1, '*');
        child_name += parent_name;
      }

      // We have a pointer to an simple type
      if (idx == 0) {
        child_byte_size = pointee_clang_type.GetByteSize(
            exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
        child_byte_offset = 0;
        return pointee_clang_type;
      }
    }
    break;
  }

  case clang::Type::LValueReference:
  case clang::Type::RValueReference:
    if (idx_is_valid) {
      const clang::ReferenceType *reference_type =
          llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
      CompilerType pointee_clang_type(getASTContext(),
                                      reference_type->getPointeeType());
      if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
        child_is_deref_of_parent = false;
        bool tmp_child_is_deref_of_parent = false;
        return pointee_clang_type.GetChildCompilerTypeAtIndex(
            exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
            ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
            child_bitfield_bit_size, child_bitfield_bit_offset,
            child_is_base_class, tmp_child_is_deref_of_parent, valobj,
            language_flags);
      } else {
        const char *parent_name =
            valobj ? valobj->GetName().GetCString() : NULL;
        if (parent_name) {
          child_name.assign(1, '&');
          child_name += parent_name;
        }

        // We have a pointer to an simple type
        if (idx == 0) {
          child_byte_size = pointee_clang_type.GetByteSize(
              exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
          child_byte_offset = 0;
          return pointee_clang_type;
        }
      }
    }
    break;

  case clang::Type::Typedef: {
    CompilerType typedefed_clang_type(
        getASTContext(), llvm::cast<clang::TypedefType>(parent_qual_type)
                             ->getDecl()
                             ->getUnderlyingType());
    return typedefed_clang_type.GetChildCompilerTypeAtIndex(
        exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
        ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
        child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
        child_is_deref_of_parent, valobj, language_flags);
  } break;

  case clang::Type::Auto: {
    CompilerType elaborated_clang_type(
        getASTContext(),
        llvm::cast<clang::AutoType>(parent_qual_type)->getDeducedType());
    return elaborated_clang_type.GetChildCompilerTypeAtIndex(
        exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
        ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
        child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
        child_is_deref_of_parent, valobj, language_flags);
  }

  case clang::Type::Elaborated: {
    CompilerType elaborated_clang_type(
        getASTContext(),
        llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
    return elaborated_clang_type.GetChildCompilerTypeAtIndex(
        exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
        ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
        child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
        child_is_deref_of_parent, valobj, language_flags);
  }

  case clang::Type::Paren: {
    CompilerType paren_clang_type(
        getASTContext(),
        llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
    return paren_clang_type.GetChildCompilerTypeAtIndex(
        exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
        ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
        child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
        child_is_deref_of_parent, valobj, language_flags);
  }

  default:
    break;
  }
  return CompilerType();
}

static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl,
                                      const clang::CXXBaseSpecifier *base_spec,
                                      bool omit_empty_base_classes) {
  uint32_t child_idx = 0;

  const clang::CXXRecordDecl *cxx_record_decl =
      llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);

  //    const char *super_name = record_decl->getNameAsCString();
  //    const char *base_name =
  //    base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
  //    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
  //
  if (cxx_record_decl) {
    clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
    for (base_class = cxx_record_decl->bases_begin(),
        base_class_end = cxx_record_decl->bases_end();
         base_class != base_class_end; ++base_class) {
      if (omit_empty_base_classes) {
        if (BaseSpecifierIsEmpty(base_class))
          continue;
      }

      //            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
      //            super_name, base_name,
      //                    child_idx,
      //                    base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
      //
      //
      if (base_class == base_spec)
        return child_idx;
      ++child_idx;
    }
  }

  return UINT32_MAX;
}

static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
                                       clang::NamedDecl *canonical_decl,
                                       bool omit_empty_base_classes) {
  uint32_t child_idx = ClangASTContext::GetNumBaseClasses(
      llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
      omit_empty_base_classes);

  clang::RecordDecl::field_iterator field, field_end;
  for (field = record_decl->field_begin(), field_end = record_decl->field_end();
       field != field_end; ++field, ++child_idx) {
    if (field->getCanonicalDecl() == canonical_decl)
      return child_idx;
  }

  return UINT32_MAX;
}

// Look for a child member (doesn't include base classes, but it does include
// their members) in the type hierarchy. Returns an index path into
// "clang_type" on how to reach the appropriate member.
//
//    class A
//    {
//    public:
//        int m_a;
//        int m_b;
//    };
//
//    class B
//    {
//    };
//
//    class C :
//        public B,
//        public A
//    {
//    };
//
// If we have a clang type that describes "class C", and we wanted to looked
// "m_b" in it:
//
// With omit_empty_base_classes == false we would get an integer array back
// with: { 1,  1 } The first index 1 is the child index for "class A" within
// class C The second index 1 is the child index for "m_b" within class A
//
// With omit_empty_base_classes == true we would get an integer array back
// with: { 0,  1 } The first index 0 is the child index for "class A" within
// class C (since class B doesn't have any members it doesn't count) The second
// index 1 is the child index for "m_b" within class A

size_t ClangASTContext::GetIndexOfChildMemberWithName(
    lldb::opaque_compiler_type_t type, const char *name,
    bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
  if (type && name && name[0]) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Record:
      if (GetCompleteType(type)) {
        const clang::RecordType *record_type =
            llvm::cast<clang::RecordType>(qual_type.getTypePtr());
        const clang::RecordDecl *record_decl = record_type->getDecl();

        assert(record_decl);
        uint32_t child_idx = 0;

        const clang::CXXRecordDecl *cxx_record_decl =
            llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);

        // Try and find a field that matches NAME
        clang::RecordDecl::field_iterator field, field_end;
        llvm::StringRef name_sref(name);
        for (field = record_decl->field_begin(),
            field_end = record_decl->field_end();
             field != field_end; ++field, ++child_idx) {
          llvm::StringRef field_name = field->getName();
          if (field_name.empty()) {
            CompilerType field_type(getASTContext(), field->getType());
            child_indexes.push_back(child_idx);
            if (field_type.GetIndexOfChildMemberWithName(
                    name, omit_empty_base_classes, child_indexes))
              return child_indexes.size();
            child_indexes.pop_back();

          } else if (field_name.equals(name_sref)) {
            // We have to add on the number of base classes to this index!
            child_indexes.push_back(
                child_idx + ClangASTContext::GetNumBaseClasses(
                                cxx_record_decl, omit_empty_base_classes));
            return child_indexes.size();
          }
        }

        if (cxx_record_decl) {
          const clang::RecordDecl *parent_record_decl = cxx_record_decl;

          // printf ("parent = %s\n", parent_record_decl->getNameAsCString());

          // const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
          // Didn't find things easily, lets let clang do its thang...
          clang::IdentifierInfo &ident_ref =
              getASTContext()->Idents.get(name_sref);
          clang::DeclarationName decl_name(&ident_ref);

          clang::CXXBasePaths paths;
          if (cxx_record_decl->lookupInBases(
                  [decl_name](const clang::CXXBaseSpecifier *specifier,
                              clang::CXXBasePath &path) {
                    return clang::CXXRecordDecl::FindOrdinaryMember(
                        specifier, path, decl_name);
                  },
                  paths)) {
            clang::CXXBasePaths::const_paths_iterator path,
                path_end = paths.end();
            for (path = paths.begin(); path != path_end; ++path) {
              const size_t num_path_elements = path->size();
              for (size_t e = 0; e < num_path_elements; ++e) {
                clang::CXXBasePathElement elem = (*path)[e];

                child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base,
                                                  omit_empty_base_classes);
                if (child_idx == UINT32_MAX) {
                  child_indexes.clear();
                  return 0;
                } else {
                  child_indexes.push_back(child_idx);
                  parent_record_decl = llvm::cast<clang::RecordDecl>(
                      elem.Base->getType()
                          ->getAs<clang::RecordType>()
                          ->getDecl());
                }
              }
              for (clang::NamedDecl *path_decl : path->Decls) {
                child_idx = GetIndexForRecordChild(
                    parent_record_decl, path_decl, omit_empty_base_classes);
                if (child_idx == UINT32_MAX) {
                  child_indexes.clear();
                  return 0;
                } else {
                  child_indexes.push_back(child_idx);
                }
              }
            }
            return child_indexes.size();
          }
        }
      }
      break;

    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface:
      if (GetCompleteType(type)) {
        llvm::StringRef name_sref(name);
        const clang::ObjCObjectType *objc_class_type =
            llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
        assert(objc_class_type);
        if (objc_class_type) {
          uint32_t child_idx = 0;
          clang::ObjCInterfaceDecl *class_interface_decl =
              objc_class_type->getInterface();

          if (class_interface_decl) {
            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
                ivar_end = class_interface_decl->ivar_end();
            clang::ObjCInterfaceDecl *superclass_interface_decl =
                class_interface_decl->getSuperClass();

            for (ivar_pos = class_interface_decl->ivar_begin();
                 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
              const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;

              if (ivar_decl->getName().equals(name_sref)) {
                if ((!omit_empty_base_classes && superclass_interface_decl) ||
                    (omit_empty_base_classes &&
                     ObjCDeclHasIVars(superclass_interface_decl, true)))
                  ++child_idx;

                child_indexes.push_back(child_idx);
                return child_indexes.size();
              }
            }

            if (superclass_interface_decl) {
              // The super class index is always zero for ObjC classes, so we
              // push it onto the child indexes in case we find an ivar in our
              // superclass...
              child_indexes.push_back(0);

              CompilerType superclass_clang_type(
                  getASTContext(), getASTContext()->getObjCInterfaceType(
                                       superclass_interface_decl));
              if (superclass_clang_type.GetIndexOfChildMemberWithName(
                      name, omit_empty_base_classes, child_indexes)) {
                // We did find an ivar in a superclass so just return the
                // results!
                return child_indexes.size();
              }

              // We didn't find an ivar matching "name" in our superclass, pop
              // the superclass zero index that we pushed on above.
              child_indexes.pop_back();
            }
          }
        }
      }
      break;

    case clang::Type::ObjCObjectPointer: {
      CompilerType objc_object_clang_type(
          getASTContext(),
          llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
              ->getPointeeType());
      return objc_object_clang_type.GetIndexOfChildMemberWithName(
          name, omit_empty_base_classes, child_indexes);
    } break;

    case clang::Type::ConstantArray: {
      //                const clang::ConstantArrayType *array =
      //                llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
      //                const uint64_t element_count =
      //                array->getSize().getLimitedValue();
      //
      //                if (idx < element_count)
      //                {
      //                    std::pair<uint64_t, unsigned> field_type_info =
      //                    ast->getTypeInfo(array->getElementType());
      //
      //                    char element_name[32];
      //                    ::snprintf (element_name, sizeof (element_name),
      //                    "%s[%u]", parent_name ? parent_name : "", idx);
      //
      //                    child_name.assign(element_name);
      //                    assert(field_type_info.first % 8 == 0);
      //                    child_byte_size = field_type_info.first / 8;
      //                    child_byte_offset = idx * child_byte_size;
      //                    return array->getElementType().getAsOpaquePtr();
      //                }
    } break;

    //        case clang::Type::MemberPointerType:
    //            {
    //                MemberPointerType *mem_ptr_type =
    //                llvm::cast<MemberPointerType>(qual_type.getTypePtr());
    //                clang::QualType pointee_type =
    //                mem_ptr_type->getPointeeType();
    //
    //                if (ClangASTContext::IsAggregateType
    //                (pointee_type.getAsOpaquePtr()))
    //                {
    //                    return GetIndexOfChildWithName (ast,
    //                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
    //                                                    name);
    //                }
    //            }
    //            break;
    //
    case clang::Type::LValueReference:
    case clang::Type::RValueReference: {
      const clang::ReferenceType *reference_type =
          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
      clang::QualType pointee_type(reference_type->getPointeeType());
      CompilerType pointee_clang_type(getASTContext(), pointee_type);

      if (pointee_clang_type.IsAggregateType()) {
        return pointee_clang_type.GetIndexOfChildMemberWithName(
            name, omit_empty_base_classes, child_indexes);
      }
    } break;

    case clang::Type::Pointer: {
      CompilerType pointee_clang_type(GetPointeeType(type));

      if (pointee_clang_type.IsAggregateType()) {
        return pointee_clang_type.GetIndexOfChildMemberWithName(
            name, omit_empty_base_classes, child_indexes);
      }
    } break;

    case clang::Type::Typedef:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::TypedefType>(qual_type)
                              ->getDecl()
                              ->getUnderlyingType())
          .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
                                         child_indexes);

    case clang::Type::Auto:
      return CompilerType(
                 getASTContext(),
                 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
          .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
                                         child_indexes);

    case clang::Type::Elaborated:
      return CompilerType(
                 getASTContext(),
                 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
          .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
                                         child_indexes);

    case clang::Type::Paren:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::ParenType>(qual_type)->desugar())
          .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
                                         child_indexes);

    default:
      break;
    }
  }
  return 0;
}

// Get the index of the child of "clang_type" whose name matches. This function
// doesn't descend into the children, but only looks one level deep and name
// matches can include base class names.

uint32_t
ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
                                         const char *name,
                                         bool omit_empty_base_classes) {
  if (type && name && name[0]) {
    clang::QualType qual_type(GetCanonicalQualType(type));

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();

    switch (type_class) {
    case clang::Type::Record:
      if (GetCompleteType(type)) {
        const clang::RecordType *record_type =
            llvm::cast<clang::RecordType>(qual_type.getTypePtr());
        const clang::RecordDecl *record_decl = record_type->getDecl();

        assert(record_decl);
        uint32_t child_idx = 0;

        const clang::CXXRecordDecl *cxx_record_decl =
            llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);

        if (cxx_record_decl) {
          clang::CXXRecordDecl::base_class_const_iterator base_class,
              base_class_end;
          for (base_class = cxx_record_decl->bases_begin(),
              base_class_end = cxx_record_decl->bases_end();
               base_class != base_class_end; ++base_class) {
            // Skip empty base classes
            clang::CXXRecordDecl *base_class_decl =
                llvm::cast<clang::CXXRecordDecl>(
                    base_class->getType()
                        ->getAs<clang::RecordType>()
                        ->getDecl());
            if (omit_empty_base_classes &&
                ClangASTContext::RecordHasFields(base_class_decl) == false)
              continue;

            CompilerType base_class_clang_type(getASTContext(),
                                               base_class->getType());
            std::string base_class_type_name(
                base_class_clang_type.GetTypeName().AsCString(""));
            if (base_class_type_name.compare(name) == 0)
              return child_idx;
            ++child_idx;
          }
        }

        // Try and find a field that matches NAME
        clang::RecordDecl::field_iterator field, field_end;
        llvm::StringRef name_sref(name);
        for (field = record_decl->field_begin(),
            field_end = record_decl->field_end();
             field != field_end; ++field, ++child_idx) {
          if (field->getName().equals(name_sref))
            return child_idx;
        }
      }
      break;

    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface:
      if (GetCompleteType(type)) {
        llvm::StringRef name_sref(name);
        const clang::ObjCObjectType *objc_class_type =
            llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
        assert(objc_class_type);
        if (objc_class_type) {
          uint32_t child_idx = 0;
          clang::ObjCInterfaceDecl *class_interface_decl =
              objc_class_type->getInterface();

          if (class_interface_decl) {
            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
                ivar_end = class_interface_decl->ivar_end();
            clang::ObjCInterfaceDecl *superclass_interface_decl =
                class_interface_decl->getSuperClass();

            for (ivar_pos = class_interface_decl->ivar_begin();
                 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
              const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;

              if (ivar_decl->getName().equals(name_sref)) {
                if ((!omit_empty_base_classes && superclass_interface_decl) ||
                    (omit_empty_base_classes &&
                     ObjCDeclHasIVars(superclass_interface_decl, true)))
                  ++child_idx;

                return child_idx;
              }
            }

            if (superclass_interface_decl) {
              if (superclass_interface_decl->getName().equals(name_sref))
                return 0;
            }
          }
        }
      }
      break;

    case clang::Type::ObjCObjectPointer: {
      CompilerType pointee_clang_type(
          getASTContext(),
          llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
              ->getPointeeType());
      return pointee_clang_type.GetIndexOfChildWithName(
          name, omit_empty_base_classes);
    } break;

    case clang::Type::ConstantArray: {
      //                const clang::ConstantArrayType *array =
      //                llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
      //                const uint64_t element_count =
      //                array->getSize().getLimitedValue();
      //
      //                if (idx < element_count)
      //                {
      //                    std::pair<uint64_t, unsigned> field_type_info =
      //                    ast->getTypeInfo(array->getElementType());
      //
      //                    char element_name[32];
      //                    ::snprintf (element_name, sizeof (element_name),
      //                    "%s[%u]", parent_name ? parent_name : "", idx);
      //
      //                    child_name.assign(element_name);
      //                    assert(field_type_info.first % 8 == 0);
      //                    child_byte_size = field_type_info.first / 8;
      //                    child_byte_offset = idx * child_byte_size;
      //                    return array->getElementType().getAsOpaquePtr();
      //                }
    } break;

    //        case clang::Type::MemberPointerType:
    //            {
    //                MemberPointerType *mem_ptr_type =
    //                llvm::cast<MemberPointerType>(qual_type.getTypePtr());
    //                clang::QualType pointee_type =
    //                mem_ptr_type->getPointeeType();
    //
    //                if (ClangASTContext::IsAggregateType
    //                (pointee_type.getAsOpaquePtr()))
    //                {
    //                    return GetIndexOfChildWithName (ast,
    //                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
    //                                                    name);
    //                }
    //            }
    //            break;
    //
    case clang::Type::LValueReference:
    case clang::Type::RValueReference: {
      const clang::ReferenceType *reference_type =
          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
      CompilerType pointee_type(getASTContext(),
                                reference_type->getPointeeType());

      if (pointee_type.IsAggregateType()) {
        return pointee_type.GetIndexOfChildWithName(name,
                                                    omit_empty_base_classes);
      }
    } break;

    case clang::Type::Pointer: {
      const clang::PointerType *pointer_type =
          llvm::cast<clang::PointerType>(qual_type.getTypePtr());
      CompilerType pointee_type(getASTContext(),
                                pointer_type->getPointeeType());

      if (pointee_type.IsAggregateType()) {
        return pointee_type.GetIndexOfChildWithName(name,
                                                    omit_empty_base_classes);
      } else {
        //                    if (parent_name)
        //                    {
        //                        child_name.assign(1, '*');
        //                        child_name += parent_name;
        //                    }
        //
        //                    // We have a pointer to an simple type
        //                    if (idx == 0)
        //                    {
        //                        std::pair<uint64_t, unsigned> clang_type_info
        //                        = ast->getTypeInfo(pointee_type);
        //                        assert(clang_type_info.first % 8 == 0);
        //                        child_byte_size = clang_type_info.first / 8;
        //                        child_byte_offset = 0;
        //                        return pointee_type.getAsOpaquePtr();
        //                    }
      }
    } break;

    case clang::Type::Auto:
      return CompilerType(
                 getASTContext(),
                 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
          .GetIndexOfChildWithName(name, omit_empty_base_classes);

    case clang::Type::Elaborated:
      return CompilerType(
                 getASTContext(),
                 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
          .GetIndexOfChildWithName(name, omit_empty_base_classes);

    case clang::Type::Paren:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::ParenType>(qual_type)->desugar())
          .GetIndexOfChildWithName(name, omit_empty_base_classes);

    case clang::Type::Typedef:
      return CompilerType(getASTContext(),
                          llvm::cast<clang::TypedefType>(qual_type)
                              ->getDecl()
                              ->getUnderlyingType())
          .GetIndexOfChildWithName(name, omit_empty_base_classes);

    default:
      break;
    }
  }
  return UINT32_MAX;
}

size_t
ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
  if (!type)
    return 0;

  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl) {
        const clang::ClassTemplateSpecializationDecl *template_decl =
            llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
                cxx_record_decl);
        if (template_decl)
          return template_decl->getTemplateArgs().size();
      }
    }
    break;

  case clang::Type::Typedef:
    return (CompilerType(getASTContext(),
                         llvm::cast<clang::TypedefType>(qual_type)
                             ->getDecl()
                             ->getUnderlyingType()))
        .GetNumTemplateArguments();

  case clang::Type::Auto:
    return (CompilerType(
                getASTContext(),
                llvm::cast<clang::AutoType>(qual_type)->getDeducedType()))
        .GetNumTemplateArguments();

  case clang::Type::Elaborated:
    return (CompilerType(
                getASTContext(),
                llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()))
        .GetNumTemplateArguments();

  case clang::Type::Paren:
    return (CompilerType(getASTContext(),
                         llvm::cast<clang::ParenType>(qual_type)->desugar()))
        .GetNumTemplateArguments();

  default:
    break;
  }

  return 0;
}

const clang::ClassTemplateSpecializationDecl *
ClangASTContext::GetAsTemplateSpecialization(
    lldb::opaque_compiler_type_t type) {
  if (!type)
    return nullptr;

  clang::QualType qual_type(GetCanonicalQualType(type));
  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record: {
    if (! GetCompleteType(type))
      return nullptr;
    const clang::CXXRecordDecl *cxx_record_decl =
        qual_type->getAsCXXRecordDecl();
    if (!cxx_record_decl)
      return nullptr;
    return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
        cxx_record_decl);
  }

  case clang::Type::Typedef:
    return GetAsTemplateSpecialization(llvm::cast<clang::TypedefType>(qual_type)
                                           ->getDecl()
                                           ->getUnderlyingType()
                                           .getAsOpaquePtr());

  case clang::Type::Auto:
    return GetAsTemplateSpecialization(llvm::cast<clang::AutoType>(qual_type)
                                           ->getDeducedType()
                                           .getAsOpaquePtr());

  case clang::Type::Elaborated:
    return GetAsTemplateSpecialization(
        llvm::cast<clang::ElaboratedType>(qual_type)
            ->getNamedType()
            .getAsOpaquePtr());

  case clang::Type::Paren:
    return GetAsTemplateSpecialization(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());

  default:
    return nullptr;
  }
}

lldb::TemplateArgumentKind
ClangASTContext::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
                                         size_t arg_idx) {
  const clang::ClassTemplateSpecializationDecl *template_decl =
      GetAsTemplateSpecialization(type);
  if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
    return eTemplateArgumentKindNull;

  switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
  case clang::TemplateArgument::Null:
    return eTemplateArgumentKindNull;

  case clang::TemplateArgument::NullPtr:
    return eTemplateArgumentKindNullPtr;

  case clang::TemplateArgument::Type:
    return eTemplateArgumentKindType;

  case clang::TemplateArgument::Declaration:
    return eTemplateArgumentKindDeclaration;

  case clang::TemplateArgument::Integral:
    return eTemplateArgumentKindIntegral;

  case clang::TemplateArgument::Template:
    return eTemplateArgumentKindTemplate;

  case clang::TemplateArgument::TemplateExpansion:
    return eTemplateArgumentKindTemplateExpansion;

  case clang::TemplateArgument::Expression:
    return eTemplateArgumentKindExpression;

  case clang::TemplateArgument::Pack:
    return eTemplateArgumentKindPack;
  }
  llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
}

CompilerType
ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
                                         size_t idx) {
  const clang::ClassTemplateSpecializationDecl *template_decl =
      GetAsTemplateSpecialization(type);
  if (!template_decl || idx >= template_decl->getTemplateArgs().size())
    return CompilerType();

  const clang::TemplateArgument &template_arg =
      template_decl->getTemplateArgs()[idx];
  if (template_arg.getKind() != clang::TemplateArgument::Type)
    return CompilerType();

  return CompilerType(getASTContext(), template_arg.getAsType());
}

llvm::Optional<CompilerType::IntegralTemplateArgument>
ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
                                             size_t idx) {
  const clang::ClassTemplateSpecializationDecl *template_decl =
      GetAsTemplateSpecialization(type);
  if (! template_decl || idx >= template_decl->getTemplateArgs().size())
    return llvm::None;

  const clang::TemplateArgument &template_arg =
      template_decl->getTemplateArgs()[idx];
  if (template_arg.getKind() != clang::TemplateArgument::Integral)
    return llvm::None;

  return {{template_arg.getAsIntegral(),
           CompilerType(getASTContext(), template_arg.getIntegralType())}};
}

CompilerType ClangASTContext::GetTypeForFormatters(void *type) {
  if (type)
    return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
  return CompilerType();
}

clang::EnumDecl *ClangASTContext::GetAsEnumDecl(const CompilerType &type) {
  const clang::EnumType *enutype =
      llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
  if (enutype)
    return enutype->getDecl();
  return NULL;
}

clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) {
  const clang::RecordType *record_type =
      llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
  if (record_type)
    return record_type->getDecl();
  return nullptr;
}

clang::TagDecl *ClangASTContext::GetAsTagDecl(const CompilerType &type) {
  clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
  if (qual_type.isNull())
    return nullptr;
  else
    return qual_type->getAsTagDecl();
}

clang::TypedefNameDecl *
ClangASTContext::GetAsTypedefDecl(const CompilerType &type) {
  const clang::TypedefType *typedef_type =
      llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type));
  if (typedef_type)
    return typedef_type->getDecl();
  return nullptr;
}

clang::CXXRecordDecl *
ClangASTContext::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
  return GetCanonicalQualType(type)->getAsCXXRecordDecl();
}

clang::ObjCInterfaceDecl *
ClangASTContext::GetAsObjCInterfaceDecl(const CompilerType &type) {
  const clang::ObjCObjectType *objc_class_type =
      llvm::dyn_cast<clang::ObjCObjectType>(
          ClangUtil::GetCanonicalQualType(type));
  if (objc_class_type)
    return objc_class_type->getInterface();
  return nullptr;
}

clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
    const CompilerType &type, const char *name,
    const CompilerType &field_clang_type, AccessType access,
    uint32_t bitfield_bit_size) {
  if (!type.IsValid() || !field_clang_type.IsValid())
    return nullptr;
  ClangASTContext *ast =
      llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
  if (!ast)
    return nullptr;
  clang::ASTContext *clang_ast = ast->getASTContext();

  clang::FieldDecl *field = nullptr;

  clang::Expr *bit_width = nullptr;
  if (bitfield_bit_size != 0) {
    llvm::APInt bitfield_bit_size_apint(
        clang_ast->getTypeSize(clang_ast->IntTy), bitfield_bit_size);
    bit_width = new (*clang_ast)
        clang::IntegerLiteral(*clang_ast, bitfield_bit_size_apint,
                              clang_ast->IntTy, clang::SourceLocation());
  }

  clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
  if (record_decl) {
    field = clang::FieldDecl::Create(
        *clang_ast, record_decl, clang::SourceLocation(),
        clang::SourceLocation(),
        name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
        ClangUtil::GetQualType(field_clang_type),      // Field type
        nullptr,                                       // TInfo *
        bit_width,                                     // BitWidth
        false,                                         // Mutable
        clang::ICIS_NoInit);                           // HasInit

    if (!name) {
      // Determine whether this field corresponds to an anonymous struct or
      // union.
      if (const clang::TagType *TagT =
              field->getType()->getAs<clang::TagType>()) {
        if (clang::RecordDecl *Rec =
                llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl()))
          if (!Rec->getDeclName()) {
            Rec->setAnonymousStructOrUnion(true);
            field->setImplicit();
          }
      }
    }

    if (field) {
      field->setAccess(
          ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));

      record_decl->addDecl(field);

#ifdef LLDB_CONFIGURATION_DEBUG
      VerifyDecl(field);
#endif
    }
  } else {
    clang::ObjCInterfaceDecl *class_interface_decl =
        ast->GetAsObjCInterfaceDecl(type);

    if (class_interface_decl) {
      const bool is_synthesized = false;

      field_clang_type.GetCompleteType();

      field = clang::ObjCIvarDecl::Create(
          *clang_ast, class_interface_decl, clang::SourceLocation(),
          clang::SourceLocation(),
          name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
          ClangUtil::GetQualType(field_clang_type),      // Field type
          nullptr,                                       // TypeSourceInfo *
          ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
          is_synthesized);

      if (field) {
        class_interface_decl->addDecl(field);

#ifdef LLDB_CONFIGURATION_DEBUG
        VerifyDecl(field);
#endif
      }
    }
  }
  return field;
}

void ClangASTContext::BuildIndirectFields(const CompilerType &type) {
  if (!type)
    return;

  ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
  if (!ast)
    return;

  clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);

  if (!record_decl)
    return;

  typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;

  IndirectFieldVector indirect_fields;
  clang::RecordDecl::field_iterator field_pos;
  clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
  clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
  for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
       last_field_pos = field_pos++) {
    if (field_pos->isAnonymousStructOrUnion()) {
      clang::QualType field_qual_type = field_pos->getType();

      const clang::RecordType *field_record_type =
          field_qual_type->getAs<clang::RecordType>();

      if (!field_record_type)
        continue;

      clang::RecordDecl *field_record_decl = field_record_type->getDecl();

      if (!field_record_decl)
        continue;

      for (clang::RecordDecl::decl_iterator
               di = field_record_decl->decls_begin(),
               de = field_record_decl->decls_end();
           di != de; ++di) {
        if (clang::FieldDecl *nested_field_decl =
                llvm::dyn_cast<clang::FieldDecl>(*di)) {
          clang::NamedDecl **chain =
              new (*ast->getASTContext()) clang::NamedDecl *[2];
          chain[0] = *field_pos;
          chain[1] = nested_field_decl;
          clang::IndirectFieldDecl *indirect_field =
              clang::IndirectFieldDecl::Create(
                  *ast->getASTContext(), record_decl, clang::SourceLocation(),
                  nested_field_decl->getIdentifier(),
                  nested_field_decl->getType(), {chain, 2});

          indirect_field->setImplicit();

          indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
              field_pos->getAccess(), nested_field_decl->getAccess()));

          indirect_fields.push_back(indirect_field);
        } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
                       llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) {
          size_t nested_chain_size =
              nested_indirect_field_decl->getChainingSize();
          clang::NamedDecl **chain = new (*ast->getASTContext())
              clang::NamedDecl *[nested_chain_size + 1];
          chain[0] = *field_pos;

          int chain_index = 1;
          for (clang::IndirectFieldDecl::chain_iterator
                   nci = nested_indirect_field_decl->chain_begin(),
                   nce = nested_indirect_field_decl->chain_end();
               nci < nce; ++nci) {
            chain[chain_index] = *nci;
            chain_index++;
          }

          clang::IndirectFieldDecl *indirect_field =
              clang::IndirectFieldDecl::Create(
                  *ast->getASTContext(), record_decl, clang::SourceLocation(),
                  nested_indirect_field_decl->getIdentifier(),
                  nested_indirect_field_decl->getType(),
                  {chain, nested_chain_size + 1});

          indirect_field->setImplicit();

          indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
              field_pos->getAccess(), nested_indirect_field_decl->getAccess()));

          indirect_fields.push_back(indirect_field);
        }
      }
    }
  }

  // Check the last field to see if it has an incomplete array type as its last
  // member and if it does, the tell the record decl about it
  if (last_field_pos != field_end_pos) {
    if (last_field_pos->getType()->isIncompleteArrayType())
      record_decl->hasFlexibleArrayMember();
  }

  for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
                                     ife = indirect_fields.end();
       ifi < ife; ++ifi) {
    record_decl->addDecl(*ifi);
  }
}

void ClangASTContext::SetIsPacked(const CompilerType &type) {
  if (type) {
    ClangASTContext *ast =
        llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
    if (ast) {
      clang::RecordDecl *record_decl = GetAsRecordDecl(type);

      if (!record_decl)
        return;

      record_decl->addAttr(
          clang::PackedAttr::CreateImplicit(*ast->getASTContext()));
    }
  }
}

clang::VarDecl *ClangASTContext::AddVariableToRecordType(
    const CompilerType &type, const char *name, const CompilerType &var_type,
    AccessType access) {
  clang::VarDecl *var_decl = nullptr;

  if (!type.IsValid() || !var_type.IsValid())
    return nullptr;
  ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
  if (!ast)
    return nullptr;

  clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
  if (record_decl) {
    var_decl = clang::VarDecl::Create(
        *ast->getASTContext(),   // ASTContext &
        record_decl,             // DeclContext *
        clang::SourceLocation(), // clang::SourceLocation StartLoc
        clang::SourceLocation(), // clang::SourceLocation IdLoc
        name ? &ast->getASTContext()->Idents.get(name)
             : nullptr,                   // clang::IdentifierInfo *
        ClangUtil::GetQualType(var_type), // Variable clang::QualType
        nullptr,                          // TypeSourceInfo *
        clang::SC_Static);                // StorageClass
    if (var_decl) {
      var_decl->setAccess(
          ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
      record_decl->addDecl(var_decl);

#ifdef LLDB_CONFIGURATION_DEBUG
      VerifyDecl(var_decl);
#endif
    }
  }
  return var_decl;
}

clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
    lldb::opaque_compiler_type_t type, const char *name, const char *mangled_name,
    const CompilerType &method_clang_type, lldb::AccessType access,
    bool is_virtual, bool is_static, bool is_inline, bool is_explicit,
    bool is_attr_used, bool is_artificial) {
  if (!type || !method_clang_type.IsValid() || name == nullptr ||
      name[0] == '\0')
    return nullptr;

  clang::QualType record_qual_type(GetCanonicalQualType(type));

  clang::CXXRecordDecl *cxx_record_decl =
      record_qual_type->getAsCXXRecordDecl();

  if (cxx_record_decl == nullptr)
    return nullptr;

  clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));

  clang::CXXMethodDecl *cxx_method_decl = nullptr;

  clang::DeclarationName decl_name(&getASTContext()->Idents.get(name));

  const clang::FunctionType *function_type =
      llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());

  if (function_type == nullptr)
    return nullptr;

  const clang::FunctionProtoType *method_function_prototype(
      llvm::dyn_cast<clang::FunctionProtoType>(function_type));

  if (!method_function_prototype)
    return nullptr;

  unsigned int num_params = method_function_prototype->getNumParams();

  clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
  clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);

  if (is_artificial)
    return nullptr; // skip everything artificial

  if (name[0] == '~') {
    cxx_dtor_decl = clang::CXXDestructorDecl::Create(
        *getASTContext(), cxx_record_decl, clang::SourceLocation(),
        clang::DeclarationNameInfo(
            getASTContext()->DeclarationNames.getCXXDestructorName(
                getASTContext()->getCanonicalType(record_qual_type)),
            clang::SourceLocation()),
        method_qual_type, nullptr, is_inline, is_artificial);
    cxx_method_decl = cxx_dtor_decl;
  } else if (decl_name == cxx_record_decl->getDeclName()) {
    cxx_ctor_decl = clang::CXXConstructorDecl::Create(
        *getASTContext(), cxx_record_decl, clang::SourceLocation(),
        clang::DeclarationNameInfo(
            getASTContext()->DeclarationNames.getCXXConstructorName(
                getASTContext()->getCanonicalType(record_qual_type)),
            clang::SourceLocation()),
        method_qual_type,
        nullptr, // TypeSourceInfo *
        is_explicit, is_inline, is_artificial, false /*is_constexpr*/);
    cxx_method_decl = cxx_ctor_decl;
  } else {
    clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
    clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;

    if (IsOperator(name, op_kind)) {
      if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
        // Check the number of operator parameters. Sometimes we have seen bad
        // DWARF that doesn't correctly describe operators and if we try to
        // create a method and add it to the class, clang will assert and
        // crash, so we need to make sure things are acceptable.
        const bool is_method = true;
        if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
                is_method, op_kind, num_params))
          return nullptr;
        cxx_method_decl = clang::CXXMethodDecl::Create(
            *getASTContext(), cxx_record_decl, clang::SourceLocation(),
            clang::DeclarationNameInfo(
                getASTContext()->DeclarationNames.getCXXOperatorName(op_kind),
                clang::SourceLocation()),
            method_qual_type,
            nullptr, // TypeSourceInfo *
            SC, is_inline, false /*is_constexpr*/, clang::SourceLocation());
      } else if (num_params == 0) {
        // Conversion operators don't take params...
        cxx_method_decl = clang::CXXConversionDecl::Create(
            *getASTContext(), cxx_record_decl, clang::SourceLocation(),
            clang::DeclarationNameInfo(
                getASTContext()->DeclarationNames.getCXXConversionFunctionName(
                    getASTContext()->getCanonicalType(
                        function_type->getReturnType())),
                clang::SourceLocation()),
            method_qual_type,
            nullptr, // TypeSourceInfo *
            is_inline, is_explicit, false /*is_constexpr*/,
            clang::SourceLocation());
      }
    }

    if (cxx_method_decl == nullptr) {
      cxx_method_decl = clang::CXXMethodDecl::Create(
          *getASTContext(), cxx_record_decl, clang::SourceLocation(),
          clang::DeclarationNameInfo(decl_name, clang::SourceLocation()),
          method_qual_type,
          nullptr, // TypeSourceInfo *
          SC, is_inline, false /*is_constexpr*/, clang::SourceLocation());
    }
  }

  clang::AccessSpecifier access_specifier =
      ClangASTContext::ConvertAccessTypeToAccessSpecifier(access);

  cxx_method_decl->setAccess(access_specifier);
  cxx_method_decl->setVirtualAsWritten(is_virtual);

  if (is_attr_used)
    cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));

  if (mangled_name != NULL) {
    cxx_method_decl->addAttr(
        clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
  }

  // Populate the method decl with parameter decls

  llvm::SmallVector<clang::ParmVarDecl *, 12> params;

  for (unsigned param_index = 0; param_index < num_params; ++param_index) {
    params.push_back(clang::ParmVarDecl::Create(
        *getASTContext(), cxx_method_decl, clang::SourceLocation(),
        clang::SourceLocation(),
        nullptr, // anonymous
        method_function_prototype->getParamType(param_index), nullptr,
        clang::SC_None, nullptr));
  }

  cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));

  cxx_record_decl->addDecl(cxx_method_decl);

  // Sometimes the debug info will mention a constructor (default/copy/move),
  // destructor, or assignment operator (copy/move) but there won't be any
  // version of this in the code. So we check if the function was artificially
  // generated and if it is trivial and this lets the compiler/backend know
  // that it can inline the IR for these when it needs to and we can avoid a
  // "missing function" error when running expressions.

  if (is_artificial) {
    if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
                           cxx_record_decl->hasTrivialDefaultConstructor()) ||
                          (cxx_ctor_decl->isCopyConstructor() &&
                           cxx_record_decl->hasTrivialCopyConstructor()) ||
                          (cxx_ctor_decl->isMoveConstructor() &&
                           cxx_record_decl->hasTrivialMoveConstructor()))) {
      cxx_ctor_decl->setDefaulted();
      cxx_ctor_decl->setTrivial(true);
    } else if (cxx_dtor_decl) {
      if (cxx_record_decl->hasTrivialDestructor()) {
        cxx_dtor_decl->setDefaulted();
        cxx_dtor_decl->setTrivial(true);
      }
    } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
                cxx_record_decl->hasTrivialCopyAssignment()) ||
               (cxx_method_decl->isMoveAssignmentOperator() &&
                cxx_record_decl->hasTrivialMoveAssignment())) {
      cxx_method_decl->setDefaulted();
      cxx_method_decl->setTrivial(true);
    }
  }

#ifdef LLDB_CONFIGURATION_DEBUG
  VerifyDecl(cxx_method_decl);
#endif

  //    printf ("decl->isPolymorphic()             = %i\n",
  //    cxx_record_decl->isPolymorphic());
  //    printf ("decl->isAggregate()               = %i\n",
  //    cxx_record_decl->isAggregate());
  //    printf ("decl->isPOD()                     = %i\n",
  //    cxx_record_decl->isPOD());
  //    printf ("decl->isEmpty()                   = %i\n",
  //    cxx_record_decl->isEmpty());
  //    printf ("decl->isAbstract()                = %i\n",
  //    cxx_record_decl->isAbstract());
  //    printf ("decl->hasTrivialConstructor()     = %i\n",
  //    cxx_record_decl->hasTrivialConstructor());
  //    printf ("decl->hasTrivialCopyConstructor() = %i\n",
  //    cxx_record_decl->hasTrivialCopyConstructor());
  //    printf ("decl->hasTrivialCopyAssignment()  = %i\n",
  //    cxx_record_decl->hasTrivialCopyAssignment());
  //    printf ("decl->hasTrivialDestructor()      = %i\n",
  //    cxx_record_decl->hasTrivialDestructor());
  return cxx_method_decl;
}

void ClangASTContext::AddMethodOverridesForCXXRecordType(
    lldb::opaque_compiler_type_t type) {
  if (auto *record = GetAsCXXRecordDecl(type))
    for (auto *method : record->methods())
      addOverridesForMethod(method);
}

#pragma mark C++ Base Classes

clang::CXXBaseSpecifier *
ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
                                          AccessType access, bool is_virtual,
                                          bool base_of_class) {
  if (type)
    return new clang::CXXBaseSpecifier(
        clang::SourceRange(), is_virtual, base_of_class,
        ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
        getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
        clang::SourceLocation());
  return nullptr;
}

void ClangASTContext::DeleteBaseClassSpecifiers(
    clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes) {
  for (unsigned i = 0; i < num_base_classes; ++i) {
    delete base_classes[i];
    base_classes[i] = nullptr;
  }
}

bool ClangASTContext::SetBaseClassesForClassType(
    lldb::opaque_compiler_type_t type,
    clang::CXXBaseSpecifier const *const *base_classes,
    unsigned num_base_classes) {
  if (type) {
    clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
    if (cxx_record_decl) {
      cxx_record_decl->setBases(base_classes, num_base_classes);
      return true;
    }
  }
  return false;
}

bool ClangASTContext::SetObjCSuperClass(
    const CompilerType &type, const CompilerType &superclass_clang_type) {
  ClangASTContext *ast =
      llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
  if (!ast)
    return false;
  clang::ASTContext *clang_ast = ast->getASTContext();

  if (type && superclass_clang_type.IsValid() &&
      superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
    clang::ObjCInterfaceDecl *class_interface_decl =
        GetAsObjCInterfaceDecl(type);
    clang::ObjCInterfaceDecl *super_interface_decl =
        GetAsObjCInterfaceDecl(superclass_clang_type);
    if (class_interface_decl && super_interface_decl) {
      class_interface_decl->setSuperClass(clang_ast->getTrivialTypeSourceInfo(
          clang_ast->getObjCInterfaceType(super_interface_decl)));
      return true;
    }
  }
  return false;
}

bool ClangASTContext::AddObjCClassProperty(
    const CompilerType &type, const char *property_name,
    const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
    const char *property_setter_name, const char *property_getter_name,
    uint32_t property_attributes, ClangASTMetadata *metadata) {
  if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
      property_name[0] == '\0')
    return false;
  ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
  if (!ast)
    return false;
  clang::ASTContext *clang_ast = ast->getASTContext();

  clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);

  if (class_interface_decl) {
    CompilerType property_clang_type_to_access;

    if (property_clang_type.IsValid())
      property_clang_type_to_access = property_clang_type;
    else if (ivar_decl)
      property_clang_type_to_access =
          CompilerType(clang_ast, ivar_decl->getType());

    if (class_interface_decl && property_clang_type_to_access.IsValid()) {
      clang::TypeSourceInfo *prop_type_source;
      if (ivar_decl)
        prop_type_source =
            clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType());
      else
        prop_type_source = clang_ast->getTrivialTypeSourceInfo(
            ClangUtil::GetQualType(property_clang_type));

      clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
          *clang_ast, class_interface_decl,
          clang::SourceLocation(), // Source Location
          &clang_ast->Idents.get(property_name),
          clang::SourceLocation(), // Source Location for AT
          clang::SourceLocation(), // Source location for (
          ivar_decl ? ivar_decl->getType()
                    : ClangUtil::GetQualType(property_clang_type),
          prop_type_source);

      if (property_decl) {
        if (metadata)
          ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);

        class_interface_decl->addDecl(property_decl);

        clang::Selector setter_sel, getter_sel;

        if (property_setter_name != nullptr) {
          std::string property_setter_no_colon(
              property_setter_name, strlen(property_setter_name) - 1);
          clang::IdentifierInfo *setter_ident =
              &clang_ast->Idents.get(property_setter_no_colon);
          setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
        } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
          std::string setter_sel_string("set");
          setter_sel_string.push_back(::toupper(property_name[0]));
          setter_sel_string.append(&property_name[1]);
          clang::IdentifierInfo *setter_ident =
              &clang_ast->Idents.get(setter_sel_string);
          setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
        }
        property_decl->setSetterName(setter_sel);
        property_decl->setPropertyAttributes(
            clang::ObjCPropertyDecl::OBJC_PR_setter);

        if (property_getter_name != nullptr) {
          clang::IdentifierInfo *getter_ident =
              &clang_ast->Idents.get(property_getter_name);
          getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
        } else {
          clang::IdentifierInfo *getter_ident =
              &clang_ast->Idents.get(property_name);
          getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
        }
        property_decl->setGetterName(getter_sel);
        property_decl->setPropertyAttributes(
            clang::ObjCPropertyDecl::OBJC_PR_getter);

        if (ivar_decl)
          property_decl->setPropertyIvarDecl(ivar_decl);

        if (property_attributes & DW_APPLE_PROPERTY_readonly)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_readonly);
        if (property_attributes & DW_APPLE_PROPERTY_readwrite)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_readwrite);
        if (property_attributes & DW_APPLE_PROPERTY_assign)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_assign);
        if (property_attributes & DW_APPLE_PROPERTY_retain)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_retain);
        if (property_attributes & DW_APPLE_PROPERTY_copy)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_copy);
        if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
        if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_nullability);
        if (property_attributes &
            clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
        if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
          property_decl->setPropertyAttributes(
              clang::ObjCPropertyDecl::OBJC_PR_class);

        const bool isInstance =
            (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;

        if (!getter_sel.isNull() &&
            !(isInstance
                  ? class_interface_decl->lookupInstanceMethod(getter_sel)
                  : class_interface_decl->lookupClassMethod(getter_sel))) {
          const bool isVariadic = false;
          const bool isSynthesized = false;
          const bool isImplicitlyDeclared = true;
          const bool isDefined = false;
          const clang::ObjCMethodDecl::ImplementationControl impControl =
              clang::ObjCMethodDecl::None;
          const bool HasRelatedResultType = false;

          clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
              *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
              getter_sel, ClangUtil::GetQualType(property_clang_type_to_access),
              nullptr, class_interface_decl, isInstance, isVariadic,
              isSynthesized, isImplicitlyDeclared, isDefined, impControl,
              HasRelatedResultType);

          if (getter && metadata)
            ClangASTContext::SetMetadata(clang_ast, getter, *metadata);

          if (getter) {
            getter->setMethodParams(*clang_ast,
                                    llvm::ArrayRef<clang::ParmVarDecl *>(),
                                    llvm::ArrayRef<clang::SourceLocation>());

            class_interface_decl->addDecl(getter);
          }
        }

        if (!setter_sel.isNull() &&
            !(isInstance
                  ? class_interface_decl->lookupInstanceMethod(setter_sel)
                  : class_interface_decl->lookupClassMethod(setter_sel))) {
          clang::QualType result_type = clang_ast->VoidTy;
          const bool isVariadic = false;
          const bool isSynthesized = false;
          const bool isImplicitlyDeclared = true;
          const bool isDefined = false;
          const clang::ObjCMethodDecl::ImplementationControl impControl =
              clang::ObjCMethodDecl::None;
          const bool HasRelatedResultType = false;

          clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create(
              *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
              setter_sel, result_type, nullptr, class_interface_decl,
              isInstance, isVariadic, isSynthesized, isImplicitlyDeclared,
              isDefined, impControl, HasRelatedResultType);

          if (setter && metadata)
            ClangASTContext::SetMetadata(clang_ast, setter, *metadata);

          llvm::SmallVector<clang::ParmVarDecl *, 1> params;

          params.push_back(clang::ParmVarDecl::Create(
              *clang_ast, setter, clang::SourceLocation(),
              clang::SourceLocation(),
              nullptr, // anonymous
              ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
              clang::SC_Auto, nullptr));

          if (setter) {
            setter->setMethodParams(
                *clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
                llvm::ArrayRef<clang::SourceLocation>());

            class_interface_decl->addDecl(setter);
          }
        }

        return true;
      }
    }
  }
  return false;
}

bool ClangASTContext::IsObjCClassTypeAndHasIVars(const CompilerType &type,
                                                 bool check_superclass) {
  clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
  if (class_interface_decl)
    return ObjCDeclHasIVars(class_interface_decl, check_superclass);
  return false;
}

clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
    const CompilerType &type,
    const char *name, // the full symbol name as seen in the symbol table
                      // (lldb::opaque_compiler_type_t type, "-[NString
                      // stringWithCString:]")
    const CompilerType &method_clang_type, lldb::AccessType access,
    bool is_artificial, bool is_variadic) {
  if (!type || !method_clang_type.IsValid())
    return nullptr;

  clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);

  if (class_interface_decl == nullptr)
    return nullptr;
  ClangASTContext *lldb_ast =
      llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
  if (lldb_ast == nullptr)
    return nullptr;
  clang::ASTContext *ast = lldb_ast->getASTContext();

  const char *selector_start = ::strchr(name, ' ');
  if (selector_start == nullptr)
    return nullptr;

  selector_start++;
  llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;

  size_t len = 0;
  const char *start;
  // printf ("name = '%s'\n", name);

  unsigned num_selectors_with_args = 0;
  for (start = selector_start; start && *start != '\0' && *start != ']';
       start += len) {
    len = ::strcspn(start, ":]");
    bool has_arg = (start[len] == ':');
    if (has_arg)
      ++num_selectors_with_args;
    selector_idents.push_back(&ast->Idents.get(llvm::StringRef(start, len)));
    if (has_arg)
      len += 1;
  }

  if (selector_idents.size() == 0)
    return nullptr;

  clang::Selector method_selector = ast->Selectors.getSelector(
      num_selectors_with_args ? selector_idents.size() : 0,
      selector_idents.data());

  clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));

  // Populate the method decl with parameter decls
  const clang::Type *method_type(method_qual_type.getTypePtr());

  if (method_type == nullptr)
    return nullptr;

  const clang::FunctionProtoType *method_function_prototype(
      llvm::dyn_cast<clang::FunctionProtoType>(method_type));

  if (!method_function_prototype)
    return nullptr;

  bool is_synthesized = false;
  bool is_defined = false;
  clang::ObjCMethodDecl::ImplementationControl imp_control =
      clang::ObjCMethodDecl::None;

  const unsigned num_args = method_function_prototype->getNumParams();

  if (num_args != num_selectors_with_args)
    return nullptr; // some debug information is corrupt.  We are not going to
                    // deal with it.

  clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create(
      *ast,
      clang::SourceLocation(), // beginLoc,
      clang::SourceLocation(), // endLoc,
      method_selector, method_function_prototype->getReturnType(),
      nullptr, // TypeSourceInfo *ResultTInfo,
      ClangASTContext::GetASTContext(ast)->GetDeclContextForType(
          ClangUtil::GetQualType(type)),
      name[0] == '-', is_variadic, is_synthesized,
      true, // is_implicitly_declared; we force this to true because we don't
            // have source locations
      is_defined, imp_control, false /*has_related_result_type*/);

  if (objc_method_decl == nullptr)
    return nullptr;

  if (num_args > 0) {
    llvm::SmallVector<clang::ParmVarDecl *, 12> params;

    for (unsigned param_index = 0; param_index < num_args; ++param_index) {
      params.push_back(clang::ParmVarDecl::Create(
          *ast, objc_method_decl, clang::SourceLocation(),
          clang::SourceLocation(),
          nullptr, // anonymous
          method_function_prototype->getParamType(param_index), nullptr,
          clang::SC_Auto, nullptr));
    }

    objc_method_decl->setMethodParams(
        *ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
        llvm::ArrayRef<clang::SourceLocation>());
  }

  class_interface_decl->addDecl(objc_method_decl);

#ifdef LLDB_CONFIGURATION_DEBUG
  VerifyDecl(objc_method_decl);
#endif

  return objc_method_decl;
}

bool ClangASTContext::GetHasExternalStorage(const CompilerType &type) {
  if (ClangUtil::IsClangType(type))
    return false;

  clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record: {
    clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
    if (cxx_record_decl)
      return cxx_record_decl->hasExternalLexicalStorage() ||
             cxx_record_decl->hasExternalVisibleStorage();
  } break;

  case clang::Type::Enum: {
    clang::EnumDecl *enum_decl =
        llvm::cast<clang::EnumType>(qual_type)->getDecl();
    if (enum_decl)
      return enum_decl->hasExternalLexicalStorage() ||
             enum_decl->hasExternalVisibleStorage();
  } break;

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface: {
    const clang::ObjCObjectType *objc_class_type =
        llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
    assert(objc_class_type);
    if (objc_class_type) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_class_type->getInterface();

      if (class_interface_decl)
        return class_interface_decl->hasExternalLexicalStorage() ||
               class_interface_decl->hasExternalVisibleStorage();
    }
  } break;

  case clang::Type::Typedef:
    return GetHasExternalStorage(CompilerType(
        type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)
                                  ->getDecl()
                                  ->getUnderlyingType()
                                  .getAsOpaquePtr()));

  case clang::Type::Auto:
    return GetHasExternalStorage(CompilerType(
        type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)
                                  ->getDeducedType()
                                  .getAsOpaquePtr()));

  case clang::Type::Elaborated:
    return GetHasExternalStorage(CompilerType(
        type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
                                  ->getNamedType()
                                  .getAsOpaquePtr()));

  case clang::Type::Paren:
    return GetHasExternalStorage(CompilerType(
        type.GetTypeSystem(),
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));

  default:
    break;
  }
  return false;
}

bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
                                            bool has_extern) {
  if (!type)
    return false;

  clang::QualType qual_type(GetCanonicalQualType(type));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record: {
    clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
    if (cxx_record_decl) {
      cxx_record_decl->setHasExternalLexicalStorage(has_extern);
      cxx_record_decl->setHasExternalVisibleStorage(has_extern);
      return true;
    }
  } break;

  case clang::Type::Enum: {
    clang::EnumDecl *enum_decl =
        llvm::cast<clang::EnumType>(qual_type)->getDecl();
    if (enum_decl) {
      enum_decl->setHasExternalLexicalStorage(has_extern);
      enum_decl->setHasExternalVisibleStorage(has_extern);
      return true;
    }
  } break;

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface: {
    const clang::ObjCObjectType *objc_class_type =
        llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
    assert(objc_class_type);
    if (objc_class_type) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_class_type->getInterface();

      if (class_interface_decl) {
        class_interface_decl->setHasExternalLexicalStorage(has_extern);
        class_interface_decl->setHasExternalVisibleStorage(has_extern);
        return true;
      }
    }
  } break;

  case clang::Type::Typedef:
    return SetHasExternalStorage(llvm::cast<clang::TypedefType>(qual_type)
                                     ->getDecl()
                                     ->getUnderlyingType()
                                     .getAsOpaquePtr(),
                                 has_extern);

  case clang::Type::Auto:
    return SetHasExternalStorage(llvm::cast<clang::AutoType>(qual_type)
                                     ->getDeducedType()
                                     .getAsOpaquePtr(),
                                 has_extern);

  case clang::Type::Elaborated:
    return SetHasExternalStorage(llvm::cast<clang::ElaboratedType>(qual_type)
                                     ->getNamedType()
                                     .getAsOpaquePtr(),
                                 has_extern);

  case clang::Type::Paren:
    return SetHasExternalStorage(
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
        has_extern);

  default:
    break;
  }
  return false;
}

#pragma mark TagDecl

bool ClangASTContext::StartTagDeclarationDefinition(const CompilerType &type) {
  clang::QualType qual_type(ClangUtil::GetQualType(type));
  if (!qual_type.isNull()) {
    const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
    if (tag_type) {
      clang::TagDecl *tag_decl = tag_type->getDecl();
      if (tag_decl) {
        tag_decl->startDefinition();
        return true;
      }
    }

    const clang::ObjCObjectType *object_type =
        qual_type->getAs<clang::ObjCObjectType>();
    if (object_type) {
      clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
      if (interface_decl) {
        interface_decl->startDefinition();
        return true;
      }
    }
  }
  return false;
}

bool ClangASTContext::CompleteTagDeclarationDefinition(
    const CompilerType &type) {
  clang::QualType qual_type(ClangUtil::GetQualType(type));
  if (!qual_type.isNull()) {
    // Make sure we use the same methodology as
    // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end
    // the definition. Previously we were calling
    const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
    if (tag_type) {
      clang::TagDecl *tag_decl = tag_type->getDecl();
      if (tag_decl) {
        clang::CXXRecordDecl *cxx_record_decl =
            llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl);

        if (cxx_record_decl) {
          if (!cxx_record_decl->isCompleteDefinition())
            cxx_record_decl->completeDefinition();
          cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
          cxx_record_decl->setHasExternalLexicalStorage(false);
          cxx_record_decl->setHasExternalVisibleStorage(false);
          return true;
        }
      }
    }

    const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();

    if (enutype) {
      clang::EnumDecl *enum_decl = enutype->getDecl();

      if (enum_decl) {
        if (!enum_decl->isCompleteDefinition()) {
          ClangASTContext *lldb_ast =
              llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
          if (lldb_ast == nullptr)
            return false;
          clang::ASTContext *ast = lldb_ast->getASTContext();

          /// TODO This really needs to be fixed.

          QualType integer_type(enum_decl->getIntegerType());
          if (!integer_type.isNull()) {
            unsigned NumPositiveBits = 1;
            unsigned NumNegativeBits = 0;

            clang::QualType promotion_qual_type;
            // If the enum integer type is less than an integer in bit width,
            // then we must promote it to an integer size.
            if (ast->getTypeSize(enum_decl->getIntegerType()) <
                ast->getTypeSize(ast->IntTy)) {
              if (enum_decl->getIntegerType()->isSignedIntegerType())
                promotion_qual_type = ast->IntTy;
              else
                promotion_qual_type = ast->UnsignedIntTy;
            } else
              promotion_qual_type = enum_decl->getIntegerType();

            enum_decl->completeDefinition(enum_decl->getIntegerType(),
                                          promotion_qual_type, NumPositiveBits,
                                          NumNegativeBits);
          }
        }
        return true;
      }
    }
  }
  return false;
}

clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
    lldb::opaque_compiler_type_t type,
    const CompilerType &enumerator_clang_type, const Declaration &decl,
    const char *name, int64_t enum_value, uint32_t enum_value_bit_size) {
  if (type && enumerator_clang_type.IsValid() && name && name[0]) {
    clang::QualType enum_qual_type(GetCanonicalQualType(type));

    bool is_signed = false;
    enumerator_clang_type.IsIntegerType(is_signed);
    const clang::Type *clang_type = enum_qual_type.getTypePtr();
    if (clang_type) {
      const clang::EnumType *enutype =
          llvm::dyn_cast<clang::EnumType>(clang_type);

      if (enutype) {
        llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
        enum_llvm_apsint = enum_value;
        clang::EnumConstantDecl *enumerator_decl =
            clang::EnumConstantDecl::Create(
                *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
                name ? &getASTContext()->Idents.get(name)
                     : nullptr, // Identifier
                ClangUtil::GetQualType(enumerator_clang_type),
                nullptr, enum_llvm_apsint);

        if (enumerator_decl) {
          enutype->getDecl()->addDecl(enumerator_decl);

#ifdef LLDB_CONFIGURATION_DEBUG
          VerifyDecl(enumerator_decl);
#endif

          return enumerator_decl;
        }
      }
    }
  }
  return nullptr;
}

CompilerType
ClangASTContext::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
  clang::QualType enum_qual_type(GetCanonicalQualType(type));
  const clang::Type *clang_type = enum_qual_type.getTypePtr();
  if (clang_type) {
    const clang::EnumType *enutype =
        llvm::dyn_cast<clang::EnumType>(clang_type);
    if (enutype) {
      clang::EnumDecl *enum_decl = enutype->getDecl();
      if (enum_decl)
        return CompilerType(getASTContext(), enum_decl->getIntegerType());
    }
  }
  return CompilerType();
}

CompilerType
ClangASTContext::CreateMemberPointerType(const CompilerType &type,
                                         const CompilerType &pointee_type) {
  if (type && pointee_type.IsValid() &&
      type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
    ClangASTContext *ast =
        llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
    if (!ast)
      return CompilerType();
    return CompilerType(ast->getASTContext(),
                        ast->getASTContext()->getMemberPointerType(
                            ClangUtil::GetQualType(pointee_type),
                            ClangUtil::GetQualType(type).getTypePtr()));
  }
  return CompilerType();
}

size_t
ClangASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
                                           const char *s, uint8_t *dst,
                                           size_t dst_size) {
  if (type) {
    clang::QualType qual_type(GetCanonicalQualType(type));
    uint32_t count = 0;
    bool is_complex = false;
    if (IsFloatingPointType(type, count, is_complex)) {
      // TODO: handle complex and vector types
      if (count != 1)
        return false;

      llvm::StringRef s_sref(s);
      llvm::APFloat ap_float(getASTContext()->getFloatTypeSemantics(qual_type),
                             s_sref);

      const uint64_t bit_size = getASTContext()->getTypeSize(qual_type);
      const uint64_t byte_size = bit_size / 8;
      if (dst_size >= byte_size) {
        Scalar scalar = ap_float.bitcastToAPInt().zextOrTrunc(
            llvm::NextPowerOf2(byte_size) * 8);
        lldb_private::Status get_data_error;
        if (scalar.GetAsMemoryData(dst, byte_size,
                                   lldb_private::endian::InlHostByteOrder(),
                                   get_data_error))
          return byte_size;
      }
    }
  }
  return 0;
}

//----------------------------------------------------------------------
// Dumping types
//----------------------------------------------------------------------
#define DEPTH_INCREMENT 2

void ClangASTContext::DumpValue(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
    lldb::Format format, const DataExtractor &data,
    lldb::offset_t data_byte_offset, size_t data_byte_size,
    uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
    bool show_summary, bool verbose, uint32_t depth) {
  if (!type)
    return;

  clang::QualType qual_type(GetQualType(type));
  switch (qual_type->getTypeClass()) {
  case clang::Type::Record:
    if (GetCompleteType(type)) {
      const clang::RecordType *record_type =
          llvm::cast<clang::RecordType>(qual_type.getTypePtr());
      const clang::RecordDecl *record_decl = record_type->getDecl();
      assert(record_decl);
      uint32_t field_bit_offset = 0;
      uint32_t field_byte_offset = 0;
      const clang::ASTRecordLayout &record_layout =
          getASTContext()->getASTRecordLayout(record_decl);
      uint32_t child_idx = 0;

      const clang::CXXRecordDecl *cxx_record_decl =
          llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
      if (cxx_record_decl) {
        // We might have base classes to print out first
        clang::CXXRecordDecl::base_class_const_iterator base_class,
            base_class_end;
        for (base_class = cxx_record_decl->bases_begin(),
            base_class_end = cxx_record_decl->bases_end();
             base_class != base_class_end; ++base_class) {
          const clang::CXXRecordDecl *base_class_decl =
              llvm::cast<clang::CXXRecordDecl>(
                  base_class->getType()->getAs<clang::RecordType>()->getDecl());

          // Skip empty base classes
          if (verbose == false &&
              ClangASTContext::RecordHasFields(base_class_decl) == false)
            continue;

          if (base_class->isVirtual())
            field_bit_offset =
                record_layout.getVBaseClassOffset(base_class_decl)
                    .getQuantity() *
                8;
          else
            field_bit_offset = record_layout.getBaseClassOffset(base_class_decl)
                                   .getQuantity() *
                               8;
          field_byte_offset = field_bit_offset / 8;
          assert(field_bit_offset % 8 == 0);
          if (child_idx == 0)
            s->PutChar('{');
          else
            s->PutChar(',');

          clang::QualType base_class_qual_type = base_class->getType();
          std::string base_class_type_name(base_class_qual_type.getAsString());

          // Indent and print the base class type name
          s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT),
                    base_class_type_name);

          clang::TypeInfo base_class_type_info =
              getASTContext()->getTypeInfo(base_class_qual_type);

          // Dump the value of the member
          CompilerType base_clang_type(getASTContext(), base_class_qual_type);
          base_clang_type.DumpValue(
              exe_ctx,
              s, // Stream to dump to
              base_clang_type
                  .GetFormat(), // The format with which to display the member
              data, // Data buffer containing all bytes for this type
              data_byte_offset + field_byte_offset, // Offset into "data" where
                                                    // to grab value from
              base_class_type_info.Width / 8, // Size of this type in bytes
              0,                              // Bitfield bit size
              0,                              // Bitfield bit offset
              show_types,   // Boolean indicating if we should show the variable
                            // types
              show_summary, // Boolean indicating if we should show a summary
                            // for the current type
              verbose,      // Verbose output?
              depth + DEPTH_INCREMENT); // Scope depth for any types that have
                                        // children

          ++child_idx;
        }
      }
      uint32_t field_idx = 0;
      clang::RecordDecl::field_iterator field, field_end;
      for (field = record_decl->field_begin(),
          field_end = record_decl->field_end();
           field != field_end; ++field, ++field_idx, ++child_idx) {
        // Print the starting squiggly bracket (if this is the first member) or
        // comma (for member 2 and beyond) for the struct/union/class member.
        if (child_idx == 0)
          s->PutChar('{');
        else
          s->PutChar(',');

        // Indent
        s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");

        clang::QualType field_type = field->getType();
        // Print the member type if requested
        // Figure out the type byte size (field_type_info.first) and alignment
        // (field_type_info.second) from the AST context.
        clang::TypeInfo field_type_info =
            getASTContext()->getTypeInfo(field_type);
        assert(field_idx < record_layout.getFieldCount());
        // Figure out the field offset within the current struct/union/class
        // type
        field_bit_offset = record_layout.getFieldOffset(field_idx);
        field_byte_offset = field_bit_offset / 8;
        uint32_t field_bitfield_bit_size = 0;
        uint32_t field_bitfield_bit_offset = 0;
        if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
                                             field_bitfield_bit_size))
          field_bitfield_bit_offset = field_bit_offset % 8;

        if (show_types) {
          std::string field_type_name(field_type.getAsString());
          if (field_bitfield_bit_size > 0)
            s->Printf("(%s:%u) ", field_type_name.c_str(),
                      field_bitfield_bit_size);
          else
            s->Printf("(%s) ", field_type_name.c_str());
        }
        // Print the member name and equal sign
        s->Printf("%s = ", field->getNameAsString().c_str());

        // Dump the value of the member
        CompilerType field_clang_type(getASTContext(), field_type);
        field_clang_type.DumpValue(
            exe_ctx,
            s, // Stream to dump to
            field_clang_type
                .GetFormat(), // The format with which to display the member
            data,             // Data buffer containing all bytes for this type
            data_byte_offset + field_byte_offset, // Offset into "data" where to
                                                  // grab value from
            field_type_info.Width / 8,            // Size of this type in bytes
            field_bitfield_bit_size,              // Bitfield bit size
            field_bitfield_bit_offset,            // Bitfield bit offset
            show_types,   // Boolean indicating if we should show the variable
                          // types
            show_summary, // Boolean indicating if we should show a summary for
                          // the current type
            verbose,      // Verbose output?
            depth + DEPTH_INCREMENT); // Scope depth for any types that have
                                      // children
      }

      // Indent the trailing squiggly bracket
      if (child_idx > 0)
        s->Printf("\n%*s}", depth, "");
    }
    return;

  case clang::Type::Enum:
    if (GetCompleteType(type)) {
      const clang::EnumType *enutype =
          llvm::cast<clang::EnumType>(qual_type.getTypePtr());
      const clang::EnumDecl *enum_decl = enutype->getDecl();
      assert(enum_decl);
      clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
      lldb::offset_t offset = data_byte_offset;
      const int64_t enum_value = data.GetMaxU64Bitfield(
          &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
      for (enum_pos = enum_decl->enumerator_begin(),
          enum_end_pos = enum_decl->enumerator_end();
           enum_pos != enum_end_pos; ++enum_pos) {
        if (enum_pos->getInitVal() == enum_value) {
          s->Printf("%s", enum_pos->getNameAsString().c_str());
          return;
        }
      }
      // If we have gotten here we didn't get find the enumerator in the enum
      // decl, so just print the integer.
      s->Printf("%" PRIi64, enum_value);
    }
    return;

  case clang::Type::ConstantArray: {
    const clang::ConstantArrayType *array =
        llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
    bool is_array_of_characters = false;
    clang::QualType element_qual_type = array->getElementType();

    const clang::Type *canonical_type =
        element_qual_type->getCanonicalTypeInternal().getTypePtr();
    if (canonical_type)
      is_array_of_characters = canonical_type->isCharType();

    const uint64_t element_count = array->getSize().getLimitedValue();

    clang::TypeInfo field_type_info =
        getASTContext()->getTypeInfo(element_qual_type);

    uint32_t element_idx = 0;
    uint32_t element_offset = 0;
    uint64_t element_byte_size = field_type_info.Width / 8;
    uint32_t element_stride = element_byte_size;

    if (is_array_of_characters) {
      s->PutChar('"');
      DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar,
                        element_byte_size, element_count, UINT32_MAX,
                        LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('"');
      return;
    } else {
      CompilerType element_clang_type(getASTContext(), element_qual_type);
      lldb::Format element_format = element_clang_type.GetFormat();

      for (element_idx = 0; element_idx < element_count; ++element_idx) {
        // Print the starting squiggly bracket (if this is the first member) or
        // comman (for member 2 and beyong) for the struct/union/class member.
        if (element_idx == 0)
          s->PutChar('{');
        else
          s->PutChar(',');

        // Indent and print the index
        s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);

        // Figure out the field offset within the current struct/union/class
        // type
        element_offset = element_idx * element_stride;

        // Dump the value of the member
        element_clang_type.DumpValue(
            exe_ctx,
            s,              // Stream to dump to
            element_format, // The format with which to display the element
            data,           // Data buffer containing all bytes for this type
            data_byte_offset +
                element_offset, // Offset into "data" where to grab value from
            element_byte_size,  // Size of this type in bytes
            0,                  // Bitfield bit size
            0,                  // Bitfield bit offset
            show_types,   // Boolean indicating if we should show the variable
                          // types
            show_summary, // Boolean indicating if we should show a summary for
                          // the current type
            verbose,      // Verbose output?
            depth + DEPTH_INCREMENT); // Scope depth for any types that have
                                      // children
      }

      // Indent the trailing squiggly bracket
      if (element_idx > 0)
        s->Printf("\n%*s}", depth, "");
    }
  }
    return;

  case clang::Type::Typedef: {
    clang::QualType typedef_qual_type =
        llvm::cast<clang::TypedefType>(qual_type)
            ->getDecl()
            ->getUnderlyingType();

    CompilerType typedef_clang_type(getASTContext(), typedef_qual_type);
    lldb::Format typedef_format = typedef_clang_type.GetFormat();
    clang::TypeInfo typedef_type_info =
        getASTContext()->getTypeInfo(typedef_qual_type);
    uint64_t typedef_byte_size = typedef_type_info.Width / 8;

    return typedef_clang_type.DumpValue(
        exe_ctx,
        s,                   // Stream to dump to
        typedef_format,      // The format with which to display the element
        data,                // Data buffer containing all bytes for this type
        data_byte_offset,    // Offset into "data" where to grab value from
        typedef_byte_size,   // Size of this type in bytes
        bitfield_bit_size,   // Bitfield bit size
        bitfield_bit_offset, // Bitfield bit offset
        show_types,   // Boolean indicating if we should show the variable types
        show_summary, // Boolean indicating if we should show a summary for the
                      // current type
        verbose,      // Verbose output?
        depth);       // Scope depth for any types that have children
  } break;

  case clang::Type::Auto: {
    clang::QualType elaborated_qual_type =
        llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
    CompilerType elaborated_clang_type(getASTContext(), elaborated_qual_type);
    lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
    clang::TypeInfo elaborated_type_info =
        getASTContext()->getTypeInfo(elaborated_qual_type);
    uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;

    return elaborated_clang_type.DumpValue(
        exe_ctx,
        s,                    // Stream to dump to
        elaborated_format,    // The format with which to display the element
        data,                 // Data buffer containing all bytes for this type
        data_byte_offset,     // Offset into "data" where to grab value from
        elaborated_byte_size, // Size of this type in bytes
        bitfield_bit_size,    // Bitfield bit size
        bitfield_bit_offset,  // Bitfield bit offset
        show_types,   // Boolean indicating if we should show the variable types
        show_summary, // Boolean indicating if we should show a summary for the
                      // current type
        verbose,      // Verbose output?
        depth);       // Scope depth for any types that have children
  } break;

  case clang::Type::Elaborated: {
    clang::QualType elaborated_qual_type =
        llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
    CompilerType elaborated_clang_type(getASTContext(), elaborated_qual_type);
    lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
    clang::TypeInfo elaborated_type_info =
        getASTContext()->getTypeInfo(elaborated_qual_type);
    uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;

    return elaborated_clang_type.DumpValue(
        exe_ctx,
        s,                    // Stream to dump to
        elaborated_format,    // The format with which to display the element
        data,                 // Data buffer containing all bytes for this type
        data_byte_offset,     // Offset into "data" where to grab value from
        elaborated_byte_size, // Size of this type in bytes
        bitfield_bit_size,    // Bitfield bit size
        bitfield_bit_offset,  // Bitfield bit offset
        show_types,   // Boolean indicating if we should show the variable types
        show_summary, // Boolean indicating if we should show a summary for the
                      // current type
        verbose,      // Verbose output?
        depth);       // Scope depth for any types that have children
  } break;

  case clang::Type::Paren: {
    clang::QualType desugar_qual_type =
        llvm::cast<clang::ParenType>(qual_type)->desugar();
    CompilerType desugar_clang_type(getASTContext(), desugar_qual_type);

    lldb::Format desugar_format = desugar_clang_type.GetFormat();
    clang::TypeInfo desugar_type_info =
        getASTContext()->getTypeInfo(desugar_qual_type);
    uint64_t desugar_byte_size = desugar_type_info.Width / 8;

    return desugar_clang_type.DumpValue(
        exe_ctx,
        s,                   // Stream to dump to
        desugar_format,      // The format with which to display the element
        data,                // Data buffer containing all bytes for this type
        data_byte_offset,    // Offset into "data" where to grab value from
        desugar_byte_size,   // Size of this type in bytes
        bitfield_bit_size,   // Bitfield bit size
        bitfield_bit_offset, // Bitfield bit offset
        show_types,   // Boolean indicating if we should show the variable types
        show_summary, // Boolean indicating if we should show a summary for the
                      // current type
        verbose,      // Verbose output?
        depth);       // Scope depth for any types that have children
  } break;

  default:
    // We are down to a scalar type that we just need to display.
    DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1,
                      UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
                      bitfield_bit_offset);

    if (show_summary)
      DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
    break;
  }
}

bool ClangASTContext::DumpTypeValue(
    lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
    const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
    uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
    ExecutionContextScope *exe_scope) {
  if (!type)
    return false;
  if (IsAggregateType(type)) {
    return false;
  } else {
    clang::QualType qual_type(GetQualType(type));

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Typedef: {
      clang::QualType typedef_qual_type =
          llvm::cast<clang::TypedefType>(qual_type)
              ->getDecl()
              ->getUnderlyingType();
      CompilerType typedef_clang_type(getASTContext(), typedef_qual_type);
      if (format == eFormatDefault)
        format = typedef_clang_type.GetFormat();
      clang::TypeInfo typedef_type_info =
          getASTContext()->getTypeInfo(typedef_qual_type);
      uint64_t typedef_byte_size = typedef_type_info.Width / 8;

      return typedef_clang_type.DumpTypeValue(
          s,
          format,            // The format with which to display the element
          data,              // Data buffer containing all bytes for this type
          byte_offset,       // Offset into "data" where to grab value from
          typedef_byte_size, // Size of this type in bytes
          bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
                             // treat as a bitfield
          bitfield_bit_offset, // Offset in bits of a bitfield value if
                               // bitfield_bit_size != 0
          exe_scope);
    } break;

    case clang::Type::Enum:
      // If our format is enum or default, show the enumeration value as its
      // enumeration string value, else just display it as requested.
      if ((format == eFormatEnum || format == eFormatDefault) &&
          GetCompleteType(type)) {
        const clang::EnumType *enutype =
            llvm::cast<clang::EnumType>(qual_type.getTypePtr());
        const clang::EnumDecl *enum_decl = enutype->getDecl();
        assert(enum_decl);
        clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
        const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
        lldb::offset_t offset = byte_offset;
        if (is_signed) {
          const int64_t enum_svalue = data.GetMaxS64Bitfield(
              &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
          for (enum_pos = enum_decl->enumerator_begin(),
              enum_end_pos = enum_decl->enumerator_end();
               enum_pos != enum_end_pos; ++enum_pos) {
            if (enum_pos->getInitVal().getSExtValue() == enum_svalue) {
              s->PutCString(enum_pos->getNameAsString());
              return true;
            }
          }
          // If we have gotten here we didn't get find the enumerator in the
          // enum decl, so just print the integer.
          s->Printf("%" PRIi64, enum_svalue);
        } else {
          const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
              &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
          for (enum_pos = enum_decl->enumerator_begin(),
              enum_end_pos = enum_decl->enumerator_end();
               enum_pos != enum_end_pos; ++enum_pos) {
            if (enum_pos->getInitVal().getZExtValue() == enum_uvalue) {
              s->PutCString(enum_pos->getNameAsString());
              return true;
            }
          }
          // If we have gotten here we didn't get find the enumerator in the
          // enum decl, so just print the integer.
          s->Printf("%" PRIu64, enum_uvalue);
        }
        return true;
      }
      // format was not enum, just fall through and dump the value as
      // requested....
      LLVM_FALLTHROUGH;

    default:
      // We are down to a scalar type that we just need to display.
      {
        uint32_t item_count = 1;
        // A few formats, we might need to modify our size and count for
        // depending
        // on how we are trying to display the value...
        switch (format) {
        default:
        case eFormatBoolean:
        case eFormatBinary:
        case eFormatComplex:
        case eFormatCString: // NULL terminated C strings
        case eFormatDecimal:
        case eFormatEnum:
        case eFormatHex:
        case eFormatHexUppercase:
        case eFormatFloat:
        case eFormatOctal:
        case eFormatOSType:
        case eFormatUnsigned:
        case eFormatPointer:
        case eFormatVectorOfChar:
        case eFormatVectorOfSInt8:
        case eFormatVectorOfUInt8:
        case eFormatVectorOfSInt16:
        case eFormatVectorOfUInt16:
        case eFormatVectorOfSInt32:
        case eFormatVectorOfUInt32:
        case eFormatVectorOfSInt64:
        case eFormatVectorOfUInt64:
        case eFormatVectorOfFloat32:
        case eFormatVectorOfFloat64:
        case eFormatVectorOfUInt128:
          break;

        case eFormatChar:
        case eFormatCharPrintable:
        case eFormatCharArray:
        case eFormatBytes:
        case eFormatBytesWithASCII:
          item_count = byte_size;
          byte_size = 1;
          break;

        case eFormatUnicode16:
          item_count = byte_size / 2;
          byte_size = 2;
          break;

        case eFormatUnicode32:
          item_count = byte_size / 4;
          byte_size = 4;
          break;
        }
        return DumpDataExtractor(data, s, byte_offset, format, byte_size,
                                 item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
                                 bitfield_bit_size, bitfield_bit_offset,
                                 exe_scope);
      }
      break;
    }
  }
  return 0;
}

void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
                                  ExecutionContext *exe_ctx, Stream *s,
                                  const lldb_private::DataExtractor &data,
                                  lldb::offset_t data_byte_offset,
                                  size_t data_byte_size) {
  uint32_t length = 0;
  if (IsCStringType(type, length)) {
    if (exe_ctx) {
      Process *process = exe_ctx->GetProcessPtr();
      if (process) {
        lldb::offset_t offset = data_byte_offset;
        lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
        std::vector<uint8_t> buf;
        if (length > 0)
          buf.resize(length);
        else
          buf.resize(256);

        DataExtractor cstr_data(&buf.front(), buf.size(),
                                process->GetByteOrder(), 4);
        buf.back() = '\0';
        size_t bytes_read;
        size_t total_cstr_len = 0;
        Status error;
        while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(),
                                                 buf.size(), error)) > 0) {
          const size_t len = strlen((const char *)&buf.front());
          if (len == 0)
            break;
          if (total_cstr_len == 0)
            s->PutCString(" \"");
          DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len,
                            UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
          total_cstr_len += len;
          if (len < buf.size())
            break;
          pointer_address += total_cstr_len;
        }
        if (total_cstr_len > 0)
          s->PutChar('"');
      }
    }
  }
}

void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
  StreamFile s(stdout, false);
  DumpTypeDescription(type, &s);
  ClangASTMetadata *metadata =
      ClangASTContext::GetMetadata(getASTContext(), type);
  if (metadata) {
    metadata->Dump(&s);
  }
}

void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
                                          Stream *s) {
  if (type) {
    clang::QualType qual_type(GetQualType(type));

    llvm::SmallVector<char, 1024> buf;
    llvm::raw_svector_ostream llvm_ostrm(buf);

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface: {
      GetCompleteType(type);

      const clang::ObjCObjectType *objc_class_type =
          llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
      assert(objc_class_type);
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();
        if (class_interface_decl) {
          clang::PrintingPolicy policy = getASTContext()->getPrintingPolicy();
          class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
        }
      }
    } break;

    case clang::Type::Typedef: {
      const clang::TypedefType *typedef_type =
          qual_type->getAs<clang::TypedefType>();
      if (typedef_type) {
        const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
        std::string clang_typedef_name(
            typedef_decl->getQualifiedNameAsString());
        if (!clang_typedef_name.empty()) {
          s->PutCString("typedef ");
          s->PutCString(clang_typedef_name);
        }
      }
    } break;

    case clang::Type::Auto:
      CompilerType(getASTContext(),
                   llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
          .DumpTypeDescription(s);
      return;

    case clang::Type::Elaborated:
      CompilerType(getASTContext(),
                   llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
          .DumpTypeDescription(s);
      return;

    case clang::Type::Paren:
      CompilerType(getASTContext(),
                   llvm::cast<clang::ParenType>(qual_type)->desugar())
          .DumpTypeDescription(s);
      return;

    case clang::Type::Record: {
      GetCompleteType(type);

      const clang::RecordType *record_type =
          llvm::cast<clang::RecordType>(qual_type.getTypePtr());
      const clang::RecordDecl *record_decl = record_type->getDecl();
      const clang::CXXRecordDecl *cxx_record_decl =
          llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);

      if (cxx_record_decl)
        cxx_record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
                               s->GetIndentLevel());
      else
        record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
                           s->GetIndentLevel());
    } break;

    default: {
      const clang::TagType *tag_type =
          llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
      if (tag_type) {
        clang::TagDecl *tag_decl = tag_type->getDecl();
        if (tag_decl)
          tag_decl->print(llvm_ostrm, 0);
      } else {
        std::string clang_type_name(qual_type.getAsString());
        if (!clang_type_name.empty())
          s->PutCString(clang_type_name);
      }
    }
    }

    if (buf.size() > 0) {
      s->Write(buf.data(), buf.size());
    }
  }
}

void ClangASTContext::DumpTypeName(const CompilerType &type) {
  if (ClangUtil::IsClangType(type)) {
    clang::QualType qual_type(
        ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));

    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
    switch (type_class) {
    case clang::Type::Record: {
      const clang::CXXRecordDecl *cxx_record_decl =
          qual_type->getAsCXXRecordDecl();
      if (cxx_record_decl)
        printf("class %s", cxx_record_decl->getName().str().c_str());
    } break;

    case clang::Type::Enum: {
      clang::EnumDecl *enum_decl =
          llvm::cast<clang::EnumType>(qual_type)->getDecl();
      if (enum_decl) {
        printf("enum %s", enum_decl->getName().str().c_str());
      }
    } break;

    case clang::Type::ObjCObject:
    case clang::Type::ObjCInterface: {
      const clang::ObjCObjectType *objc_class_type =
          llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
      if (objc_class_type) {
        clang::ObjCInterfaceDecl *class_interface_decl =
            objc_class_type->getInterface();
        // We currently can't complete objective C types through the newly
        // added ASTContext because it only supports TagDecl objects right
        // now...
        if (class_interface_decl)
          printf("@class %s", class_interface_decl->getName().str().c_str());
      }
    } break;

    case clang::Type::Typedef:
      printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)
                               ->getDecl()
                               ->getName()
                               .str()
                               .c_str());
      break;

    case clang::Type::Auto:
      printf("auto ");
      return DumpTypeName(CompilerType(type.GetTypeSystem(),
                                       llvm::cast<clang::AutoType>(qual_type)
                                           ->getDeducedType()
                                           .getAsOpaquePtr()));

    case clang::Type::Elaborated:
      printf("elaborated ");
      return DumpTypeName(CompilerType(
          type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
                                    ->getNamedType()
                                    .getAsOpaquePtr()));

    case clang::Type::Paren:
      printf("paren ");
      return DumpTypeName(CompilerType(
          type.GetTypeSystem(),
          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));

    default:
      printf("ClangASTContext::DumpTypeName() type_class = %u", type_class);
      break;
    }
  }
}

clang::ClassTemplateDecl *ClangASTContext::ParseClassTemplateDecl(
    clang::DeclContext *decl_ctx, lldb::AccessType access_type,
    const char *parent_name, int tag_decl_kind,
    const ClangASTContext::TemplateParameterInfos &template_param_infos) {
  if (template_param_infos.IsValid()) {
    std::string template_basename(parent_name);
    template_basename.erase(template_basename.find('<'));

    return CreateClassTemplateDecl(decl_ctx, access_type,
                                   template_basename.c_str(), tag_decl_kind,
                                   template_param_infos);
  }
  return NULL;
}

void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) {
  ClangASTContext *ast = (ClangASTContext *)baton;
  SymbolFile *sym_file = ast->GetSymbolFile();
  if (sym_file) {
    CompilerType clang_type = GetTypeForDecl(decl);
    if (clang_type)
      sym_file->CompleteType(clang_type);
  }
}

void ClangASTContext::CompleteObjCInterfaceDecl(
    void *baton, clang::ObjCInterfaceDecl *decl) {
  ClangASTContext *ast = (ClangASTContext *)baton;
  SymbolFile *sym_file = ast->GetSymbolFile();
  if (sym_file) {
    CompilerType clang_type = GetTypeForDecl(decl);
    if (clang_type)
      sym_file->CompleteType(clang_type);
  }
}

DWARFASTParser *ClangASTContext::GetDWARFParser() {
  if (!m_dwarf_ast_parser_ap)
    m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this));
  return m_dwarf_ast_parser_ap.get();
}

PDBASTParser *ClangASTContext::GetPDBParser() {
  if (!m_pdb_ast_parser_ap)
    m_pdb_ast_parser_ap.reset(new PDBASTParser(*this));
  return m_pdb_ast_parser_ap.get();
}

bool ClangASTContext::LayoutRecordType(
    void *baton, const clang::RecordDecl *record_decl, uint64_t &bit_size,
    uint64_t &alignment,
    llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
        &base_offsets,
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
        &vbase_offsets) {
  ClangASTContext *ast = (ClangASTContext *)baton;
  lldb_private::ClangASTImporter *importer = nullptr;
  if (ast->m_dwarf_ast_parser_ap)
    importer = &ast->m_dwarf_ast_parser_ap->GetClangASTImporter();
  if (!importer && ast->m_pdb_ast_parser_ap)
    importer = &ast->m_pdb_ast_parser_ap->GetClangASTImporter();
  if (!importer)
    return false;

  return importer->LayoutRecordType(record_decl, bit_size, alignment,
                                    field_offsets, base_offsets, vbase_offsets);
}

//----------------------------------------------------------------------
// CompilerDecl override functions
//----------------------------------------------------------------------

ConstString ClangASTContext::DeclGetName(void *opaque_decl) {
  if (opaque_decl) {
    clang::NamedDecl *nd =
        llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl);
    if (nd != nullptr)
      return ConstString(nd->getDeclName().getAsString());
  }
  return ConstString();
}

ConstString ClangASTContext::DeclGetMangledName(void *opaque_decl) {
  if (opaque_decl) {
    clang::NamedDecl *nd =
        llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)opaque_decl);
    if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd)) {
      clang::MangleContext *mc = getMangleContext();
      if (mc && mc->shouldMangleCXXName(nd)) {
        llvm::SmallVector<char, 1024> buf;
        llvm::raw_svector_ostream llvm_ostrm(buf);
        if (llvm::isa<clang::CXXConstructorDecl>(nd)) {
          mc->mangleCXXCtor(llvm::dyn_cast<clang::CXXConstructorDecl>(nd),
                            Ctor_Complete, llvm_ostrm);
        } else if (llvm::isa<clang::CXXDestructorDecl>(nd)) {
          mc->mangleCXXDtor(llvm::dyn_cast<clang::CXXDestructorDecl>(nd),
                            Dtor_Complete, llvm_ostrm);
        } else {
          mc->mangleName(nd, llvm_ostrm);
        }
        if (buf.size() > 0)
          return ConstString(buf.data(), buf.size());
      }
    }
  }
  return ConstString();
}

CompilerDeclContext ClangASTContext::DeclGetDeclContext(void *opaque_decl) {
  if (opaque_decl)
    return CompilerDeclContext(this,
                               ((clang::Decl *)opaque_decl)->getDeclContext());
  else
    return CompilerDeclContext();
}

CompilerType ClangASTContext::DeclGetFunctionReturnType(void *opaque_decl) {
  if (clang::FunctionDecl *func_decl =
          llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
    return CompilerType(this, func_decl->getReturnType().getAsOpaquePtr());
  if (clang::ObjCMethodDecl *objc_method =
          llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
    return CompilerType(this, objc_method->getReturnType().getAsOpaquePtr());
  else
    return CompilerType();
}

size_t ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl) {
  if (clang::FunctionDecl *func_decl =
          llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
    return func_decl->param_size();
  if (clang::ObjCMethodDecl *objc_method =
          llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
    return objc_method->param_size();
  else
    return 0;
}

CompilerType ClangASTContext::DeclGetFunctionArgumentType(void *opaque_decl,
                                                          size_t idx) {
  if (clang::FunctionDecl *func_decl =
          llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) {
    if (idx < func_decl->param_size()) {
      ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
      if (var_decl)
        return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
    }
  } else if (clang::ObjCMethodDecl *objc_method =
                 llvm::dyn_cast<clang::ObjCMethodDecl>(
                     (clang::Decl *)opaque_decl)) {
    if (idx < objc_method->param_size())
      return CompilerType(
          this,
          objc_method->parameters()[idx]->getOriginalType().getAsOpaquePtr());
  }
  return CompilerType();
}

//----------------------------------------------------------------------
// CompilerDeclContext functions
//----------------------------------------------------------------------

std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName(
    void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
  std::vector<CompilerDecl> found_decls;
  if (opaque_decl_ctx) {
    DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
    std::set<DeclContext *> searched;
    std::multimap<DeclContext *, DeclContext *> search_queue;
    SymbolFile *symbol_file = GetSymbolFile();

    for (clang::DeclContext *decl_context = root_decl_ctx;
         decl_context != nullptr && found_decls.empty();
         decl_context = decl_context->getParent()) {
      search_queue.insert(std::make_pair(decl_context, decl_context));

      for (auto it = search_queue.find(decl_context); it != search_queue.end();
           it++) {
        if (!searched.insert(it->second).second)
          continue;
        symbol_file->ParseDeclsForContext(
            CompilerDeclContext(this, it->second));

        for (clang::Decl *child : it->second->decls()) {
          if (clang::UsingDirectiveDecl *ud =
                  llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
            if (ignore_using_decls)
              continue;
            clang::DeclContext *from = ud->getCommonAncestor();
            if (searched.find(ud->getNominatedNamespace()) == searched.end())
              search_queue.insert(
                  std::make_pair(from, ud->getNominatedNamespace()));
          } else if (clang::UsingDecl *ud =
                         llvm::dyn_cast<clang::UsingDecl>(child)) {
            if (ignore_using_decls)
              continue;
            for (clang::UsingShadowDecl *usd : ud->shadows()) {
              clang::Decl *target = usd->getTargetDecl();
              if (clang::NamedDecl *nd =
                      llvm::dyn_cast<clang::NamedDecl>(target)) {
                IdentifierInfo *ii = nd->getIdentifier();
                if (ii != nullptr &&
                    ii->getName().equals(name.AsCString(nullptr)))
                  found_decls.push_back(CompilerDecl(this, nd));
              }
            }
          } else if (clang::NamedDecl *nd =
                         llvm::dyn_cast<clang::NamedDecl>(child)) {
            IdentifierInfo *ii = nd->getIdentifier();
            if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
              found_decls.push_back(CompilerDecl(this, nd));
          }
        }
      }
    }
  }
  return found_decls;
}

// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
// and return the number of levels it took to find it, or
// LLDB_INVALID_DECL_LEVEL if not found.  If the decl was imported via a using
// declaration, its name and/or type, if set, will be used to check that the
// decl found in the scope is a match.
//
// The optional name is required by languages (like C++) to handle using
// declarations like:
//
//     void poo();
//     namespace ns {
//         void foo();
//         void goo();
//     }
//     void bar() {
//         using ns::foo;
//         // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
//         // LLDB_INVALID_DECL_LEVEL for 'goo'.
//     }
//
// The optional type is useful in the case that there's a specific overload
// that we're looking for that might otherwise be shadowed, like:
//
//     void foo(int);
//     namespace ns {
//         void foo();
//     }
//     void bar() {
//         using ns::foo;
//         // CountDeclLevels returns 0 for { 'foo', void() },
//         // 1 for { 'foo', void(int) }, and
//         // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
//     }
//
// NOTE: Because file statics are at the TranslationUnit along with globals, a
// function at file scope will return the same level as a function at global
// scope. Ideally we'd like to treat the file scope as an additional scope just
// below the global scope.  More work needs to be done to recognise that, if
// the decl we're trying to look up is static, we should compare its source
// file with that of the current scope and return a lower number for it.
uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
                                          clang::DeclContext *child_decl_ctx,
                                          ConstString *child_name,
                                          CompilerType *child_type) {
  if (frame_decl_ctx) {
    std::set<DeclContext *> searched;
    std::multimap<DeclContext *, DeclContext *> search_queue;
    SymbolFile *symbol_file = GetSymbolFile();

    // Get the lookup scope for the decl we're trying to find.
    clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();

    // Look for it in our scope's decl context and its parents.
    uint32_t level = 0;
    for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
         decl_ctx = decl_ctx->getParent()) {
      if (!decl_ctx->isLookupContext())
        continue;
      if (decl_ctx == parent_decl_ctx)
        // Found it!
        return level;
      search_queue.insert(std::make_pair(decl_ctx, decl_ctx));
      for (auto it = search_queue.find(decl_ctx); it != search_queue.end();
           it++) {
        if (searched.find(it->second) != searched.end())
          continue;

        // Currently DWARF has one shared translation unit for all Decls at top
        // level, so this would erroneously find using statements anywhere.  So
        // don't look at the top-level translation unit.
        // TODO fix this and add a testcase that depends on it.

        if (llvm::isa<clang::TranslationUnitDecl>(it->second))
          continue;

        searched.insert(it->second);
        symbol_file->ParseDeclsForContext(
            CompilerDeclContext(this, it->second));

        for (clang::Decl *child : it->second->decls()) {
          if (clang::UsingDirectiveDecl *ud =
                  llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
            clang::DeclContext *ns = ud->getNominatedNamespace();
            if (ns == parent_decl_ctx)
              // Found it!
              return level;
            clang::DeclContext *from = ud->getCommonAncestor();
            if (searched.find(ns) == searched.end())
              search_queue.insert(std::make_pair(from, ns));
          } else if (child_name) {
            if (clang::UsingDecl *ud =
                    llvm::dyn_cast<clang::UsingDecl>(child)) {
              for (clang::UsingShadowDecl *usd : ud->shadows()) {
                clang::Decl *target = usd->getTargetDecl();
                clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target);
                if (!nd)
                  continue;
                // Check names.
                IdentifierInfo *ii = nd->getIdentifier();
                if (ii == nullptr ||
                    !ii->getName().equals(child_name->AsCString(nullptr)))
                  continue;
                // Check types, if one was provided.
                if (child_type) {
                  CompilerType clang_type = ClangASTContext::GetTypeForDecl(nd);
                  if (!AreTypesSame(clang_type, *child_type,
                                    /*ignore_qualifiers=*/true))
                    continue;
                }
                // Found it!
                return level;
              }
            }
          }
        }
      }
      ++level;
    }
  }
  return LLDB_INVALID_DECL_LEVEL;
}

bool ClangASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) {
  if (opaque_decl_ctx)
    return ((clang::DeclContext *)opaque_decl_ctx)->isRecord();
  else
    return false;
}

ConstString ClangASTContext::DeclContextGetName(void *opaque_decl_ctx) {
  if (opaque_decl_ctx) {
    clang::NamedDecl *named_decl =
        llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
    if (named_decl)
      return ConstString(named_decl->getName());
  }
  return ConstString();
}

ConstString
ClangASTContext::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
  if (opaque_decl_ctx) {
    clang::NamedDecl *named_decl =
        llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
    if (named_decl)
      return ConstString(
          llvm::StringRef(named_decl->getQualifiedNameAsString()));
  }
  return ConstString();
}

bool ClangASTContext::DeclContextIsClassMethod(
    void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
    bool *is_instance_method_ptr, ConstString *language_object_name_ptr) {
  if (opaque_decl_ctx) {
    clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
    if (ObjCMethodDecl *objc_method =
            llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) {
      if (is_instance_method_ptr)
        *is_instance_method_ptr = objc_method->isInstanceMethod();
      if (language_ptr)
        *language_ptr = eLanguageTypeObjC;
      if (language_object_name_ptr)
        language_object_name_ptr->SetCString("self");
      return true;
    } else if (CXXMethodDecl *cxx_method =
                   llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) {
      if (is_instance_method_ptr)
        *is_instance_method_ptr = cxx_method->isInstance();
      if (language_ptr)
        *language_ptr = eLanguageTypeC_plus_plus;
      if (language_object_name_ptr)
        language_object_name_ptr->SetCString("this");
      return true;
    } else if (clang::FunctionDecl *function_decl =
                   llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) {
      ClangASTMetadata *metadata =
          GetMetadata(&decl_ctx->getParentASTContext(), function_decl);
      if (metadata && metadata->HasObjectPtr()) {
        if (is_instance_method_ptr)
          *is_instance_method_ptr = true;
        if (language_ptr)
          *language_ptr = eLanguageTypeObjC;
        if (language_object_name_ptr)
          language_object_name_ptr->SetCString(metadata->GetObjectPtrName());
        return true;
      }
    }
  }
  return false;
}

clang::DeclContext *
ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
  if (dc.IsClang())
    return (clang::DeclContext *)dc.GetOpaqueDeclContext();
  return nullptr;
}

ObjCMethodDecl *
ClangASTContext::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
  if (dc.IsClang())
    return llvm::dyn_cast<clang::ObjCMethodDecl>(
        (clang::DeclContext *)dc.GetOpaqueDeclContext());
  return nullptr;
}

CXXMethodDecl *
ClangASTContext::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
  if (dc.IsClang())
    return llvm::dyn_cast<clang::CXXMethodDecl>(
        (clang::DeclContext *)dc.GetOpaqueDeclContext());
  return nullptr;
}

clang::FunctionDecl *
ClangASTContext::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
  if (dc.IsClang())
    return llvm::dyn_cast<clang::FunctionDecl>(
        (clang::DeclContext *)dc.GetOpaqueDeclContext());
  return nullptr;
}

clang::NamespaceDecl *
ClangASTContext::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
  if (dc.IsClang())
    return llvm::dyn_cast<clang::NamespaceDecl>(
        (clang::DeclContext *)dc.GetOpaqueDeclContext());
  return nullptr;
}

ClangASTMetadata *
ClangASTContext::DeclContextGetMetaData(const CompilerDeclContext &dc,
                                        const void *object) {
  clang::ASTContext *ast = DeclContextGetClangASTContext(dc);
  if (ast)
    return ClangASTContext::GetMetadata(ast, object);
  return nullptr;
}

clang::ASTContext *
ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) {
  ClangASTContext *ast =
      llvm::dyn_cast_or_null<ClangASTContext>(dc.GetTypeSystem());
  if (ast)
    return ast->getASTContext();
  return nullptr;
}

ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target)
    : ClangASTContext(target.GetArchitecture().GetTriple().getTriple().c_str()),
      m_target_wp(target.shared_from_this()),
      m_persistent_variables(new ClangPersistentVariables) {}

UserExpression *ClangASTContextForExpressions::GetUserExpression(
    llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
    Expression::ResultType desired_type,
    const EvaluateExpressionOptions &options) {
  TargetSP target_sp = m_target_wp.lock();
  if (!target_sp)
    return nullptr;

  return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
                                 desired_type, options);
}

FunctionCaller *ClangASTContextForExpressions::GetFunctionCaller(
    const CompilerType &return_type, const Address &function_address,
    const ValueList &arg_value_list, const char *name) {
  TargetSP target_sp = m_target_wp.lock();
  if (!target_sp)
    return nullptr;

  Process *process = target_sp->GetProcessSP().get();
  if (!process)
    return nullptr;

  return new ClangFunctionCaller(*process, return_type, function_address,
                                 arg_value_list, name);
}

UtilityFunction *
ClangASTContextForExpressions::GetUtilityFunction(const char *text,
                                                  const char *name) {
  TargetSP target_sp = m_target_wp.lock();
  if (!target_sp)
    return nullptr;

  return new ClangUtilityFunction(*target_sp.get(), text, name);
}

PersistentExpressionState *
ClangASTContextForExpressions::GetPersistentExpressionState() {
  return m_persistent_variables.get();
}

clang::ExternalASTMerger &
ClangASTContextForExpressions::GetMergerUnchecked() {
  lldbassert(m_scratch_ast_source_ap != nullptr);
  return m_scratch_ast_source_ap->GetMergerUnchecked();
}
