[Lldb-commits] [lldb] r280751 - *** This commit represents a complete reformatting of the LLDB source code

Kate Stone via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 6 13:58:36 PDT 2016


Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Sep  6 15:57:50 2016
@@ -17,7 +17,7 @@
 
 // Other libraries and framework includes
 
-// Clang headers like to use NDEBUG inside of them to enable/disable debug 
+// 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
@@ -103,6146 +103,6052 @@ 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;
-    }
+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;
 }
-
-typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext*> ClangASTMap;
-
-static ClangASTMap &
-GetASTMap()
-{
-    static ClangASTMap *g_map_ptr = nullptr;
-    static std::once_flag g_once_flag;
-    std::call_once(g_once_flag,  []() {
-        g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
-    });
-    return *g_map_ptr;
 }
 
-static bool
-IsOperator(const char *name, clang::OverloadedOperatorKind &op_kind)
-{
-    if (name == nullptr || name[0] == '\0')
-        return false;
+typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext *>
+    ClangASTMap;
+
+static ClangASTMap &GetASTMap() {
+  static ClangASTMap *g_map_ptr = nullptr;
+  static std::once_flag g_once_flag;
+  std::call_once(g_once_flag, []() {
+    g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
+  });
+  return *g_map_ptr;
+}
+
+static bool 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;
+  const char *post_op_name = nullptr;
 
-    bool no_space = true;
+  bool no_space = true;
 
-    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
-        return false;
+  if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+    return false;
 
-    post_op_name = name + OPERATOR_PREFIX_LENGTH;
+  post_op_name = name + OPERATOR_PREFIX_LENGTH;
 
-    if (post_op_name[0] == ' ')
-    {
-        post_op_name++;
-        no_space = false;
-    }
+  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;
+  // 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 '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_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_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_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;
+  }
 
-        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;
+  return true;
+}
 
-        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;
+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 == IK_Asm) {
+    Opts.AsmPreprocessor = 1;
+  } else if (IK == IK_ObjC || IK == IK_ObjCXX || IK == IK_PreprocessedObjC ||
+             IK == IK_PreprocessedObjCXX) {
+    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) {
+    case IK_None:
+    case IK_AST:
+    case IK_LLVM_IR:
+    case IK_RenderScript:
+      assert(!"Invalid input kind!");
+    case IK_OpenCL:
+      LangStd = LangStandard::lang_opencl;
+      break;
+    case IK_CUDA:
+    case IK_PreprocessedCuda:
+      LangStd = LangStandard::lang_cuda;
+      break;
+    case IK_Asm:
+    case IK_C:
+    case IK_PreprocessedC:
+    case IK_ObjC:
+    case IK_PreprocessedObjC:
+      LangStd = LangStandard::lang_gnu99;
+      break;
+    case IK_CXX:
+    case IK_PreprocessedCXX:
+    case IK_ObjCXX:
+    case IK_PreprocessedObjCXX:
+      LangStd = LangStandard::lang_gnucxx98;
+      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_opencl) {
+    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;
+
+  //    if (Opts.CPlusPlus)
+  //        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
+  //
+  //    if (Args.hasArg(OPT_fobjc_gc_only))
+  //        Opts.setGCMode(LangOptions::GCOnly);
+  //    else if (Args.hasArg(OPT_fobjc_gc))
+  //        Opts.setGCMode(LangOptions::HybridGC);
+  //
+  //    if (Args.hasArg(OPT_print_ivar_layout))
+  //        Opts.ObjCGCBitmapPrint = 1;
+  //
+  //    if (Args.hasArg(OPT_faltivec))
+  //        Opts.AltiVec = 1;
+  //
+  //    if (Args.hasArg(OPT_pthread))
+  //        Opts.POSIXThreads = 1;
+  //
+  //    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
+  //                                          "default");
+  //    if (Vis == "default")
+  Opts.setValueVisibilityMode(DefaultVisibility);
+  //    else if (Vis == "hidden")
+  //        Opts.setVisibilityMode(LangOptions::Hidden);
+  //    else if (Vis == "protected")
+  //        Opts.setVisibilityMode(LangOptions::Protected);
+  //    else
+  //        Diags.Report(diag::err_drv_invalid_value)
+  //        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
+
+  //    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
+
+  // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
+  // is specified, or -std is set to a conforming mode.
+  Opts.Trigraphs = !Opts.GNUMode;
+  //    if (Args.hasArg(OPT_trigraphs))
+  //        Opts.Trigraphs = 1;
+  //
+  //    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
+  //                                     OPT_fno_dollars_in_identifiers,
+  //                                     !Opts.AsmPreprocessor);
+  //    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
+  //    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
+  //    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
+  //    if (Args.hasArg(OPT_fno_lax_vector_conversions))
+  //        Opts.LaxVectorConversions = 0;
+  //    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
+  //    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
+  //    Opts.Blocks = Args.hasArg(OPT_fblocks);
+  Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
+  //    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
+  //    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
+  //    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+  //    Opts.AssumeSaneOperatorNew =
+  //    !Args.hasArg(OPT_fno_assume_sane_operator_new);
+  //    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
+  //    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
+  //    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
+  //    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
+  //    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth,
+  //    99,
+  //                                                 Diags);
+  //    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
+  //    Opts.ObjCConstantStringClass = getLastArgValue(Args,
+  //                                                   OPT_fconstant_string_class);
+  //    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
+  //    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
+  //    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
+  //    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
+  //    Opts.Static = Args.hasArg(OPT_static_define);
+  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;
+
+  //    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
+  //    switch (SSP) {
+  //        default:
+  //            Diags.Report(diag::err_drv_invalid_value)
+  //            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) <<
+  //            SSP;
+  //            break;
+  //        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
+  //        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
+  //        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
+  //    }
+}
+
+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);
+}
 
-        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;
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ClangASTContext::~ClangASTContext() { Finalize(); }
 
-        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;
+ConstString ClangASTContext::GetPluginNameStatic() {
+  return ConstString("clang");
+}
 
-        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;
+ConstString ClangASTContext::GetPluginName() {
+  return ClangASTContext::GetPluginNameStatic();
+}
 
-        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;
+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()));
+          ast_sp->m_scratch_ast_source_ap->InstallASTContext(
+              ast_sp->getASTContext());
+          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);
+    // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(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);
+    // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(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, IK_ObjCXX, GetTargetTriple());
+    //        InitializeLangOptions(*m_language_options_ap, IK_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();
+}
 
-        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;
+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();
+  }
 
-        case '~':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Tilde;
-            break;
+private:
+  Log *m_log;
+};
 
-        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;
+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();
+}
 
-        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;
+#pragma mark Basic Types
 
-        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;
+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;
+}
 
-        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;
+CompilerType
+ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
+                                                     size_t bit_size) {
+  return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
+      getASTContext(), encoding, bit_size);
+}
 
-        case ',':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Comma;
-            break;
+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;
+  }
 
-        case '(':
-            if (post_op_name[1] == ')' && post_op_name[2] == '\0')
-                op_kind = clang::OO_Call;
-            break;
+  return CompilerType();
+}
 
-        case '[':
-            if (post_op_name[1] == ']' && post_op_name[2] == '\0')
-                op_kind = clang::OO_Subscript;
-            break;
-    }
+lldb::BasicType
+ClangASTContext::GetBasicTypeEnumeration(const ConstString &name) {
+  if (name) {
+    typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+    static TypeNameToBasicTypeMap g_type_map;
+    static std::once_flag g_once_flag;
+    std::call_once(g_once_flag, []() {
+      // "void"
+      g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
+
+      // "char"
+      g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
+      g_type_map.Append(ConstString("signed char").GetCString(),
+                        eBasicTypeSignedChar);
+      g_type_map.Append(ConstString("unsigned char").GetCString(),
+                        eBasicTypeUnsignedChar);
+      g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
+      g_type_map.Append(ConstString("signed wchar_t").GetCString(),
+                        eBasicTypeSignedWChar);
+      g_type_map.Append(ConstString("unsigned wchar_t").GetCString(),
+                        eBasicTypeUnsignedWChar);
+      // "short"
+      g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
+      g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
+      g_type_map.Append(ConstString("unsigned short").GetCString(),
+                        eBasicTypeUnsignedShort);
+      g_type_map.Append(ConstString("unsigned short int").GetCString(),
+                        eBasicTypeUnsignedShort);
+
+      // "int"
+      g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
+      g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
+      g_type_map.Append(ConstString("unsigned int").GetCString(),
+                        eBasicTypeUnsignedInt);
+      g_type_map.Append(ConstString("unsigned").GetCString(),
+                        eBasicTypeUnsignedInt);
+
+      // "long"
+      g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
+      g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
+      g_type_map.Append(ConstString("unsigned long").GetCString(),
+                        eBasicTypeUnsignedLong);
+      g_type_map.Append(ConstString("unsigned long int").GetCString(),
+                        eBasicTypeUnsignedLong);
+
+      // "long long"
+      g_type_map.Append(ConstString("long long").GetCString(),
+                        eBasicTypeLongLong);
+      g_type_map.Append(ConstString("long long int").GetCString(),
+                        eBasicTypeLongLong);
+      g_type_map.Append(ConstString("unsigned long long").GetCString(),
+                        eBasicTypeUnsignedLongLong);
+      g_type_map.Append(ConstString("unsigned long long int").GetCString(),
+                        eBasicTypeUnsignedLongLong);
+
+      // "int128"
+      g_type_map.Append(ConstString("__int128_t").GetCString(),
+                        eBasicTypeInt128);
+      g_type_map.Append(ConstString("__uint128_t").GetCString(),
+                        eBasicTypeUnsignedInt128);
+
+      // Miscellaneous
+      g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
+      g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
+      g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
+      g_type_map.Append(ConstString("long double").GetCString(),
+                        eBasicTypeLongDouble);
+      g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
+      g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
+      g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
+      g_type_map.Sort();
+    });
 
-    return true;
+    return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
+  }
+  return eBasicTypeInvalid;
 }
 
-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;
+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();
 }
 
-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 == IK_Asm) {
-        Opts.AsmPreprocessor = 1;
-    } else if (IK == IK_ObjC ||
-               IK == IK_ObjCXX ||
-               IK == IK_PreprocessedObjC ||
-               IK == IK_PreprocessedObjCXX) {
-        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) {
-            case IK_None:
-            case IK_AST:
-            case IK_LLVM_IR:
-            case IK_RenderScript:
-                assert (!"Invalid input kind!");
-            case IK_OpenCL:
-                LangStd = LangStandard::lang_opencl;
-                break;
-            case IK_CUDA:
-            case IK_PreprocessedCuda:
-                LangStd = LangStandard::lang_cuda;
-                break;
-            case IK_Asm:
-            case IK_C:
-            case IK_PreprocessedC:
-            case IK_ObjC:
-            case IK_PreprocessedObjC:
-                LangStd = LangStandard::lang_gnu99;
-                break;
-            case IK_CXX:
-            case IK_PreprocessedCXX:
-            case IK_ObjCXX:
-            case IK_PreprocessedObjCXX:
-                LangStd = LangStandard::lang_gnucxx98;
-                break;
-        }
-    }
+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;
+}
 
-    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_opencl) {
-        Opts.OpenCL = 1;
-        Opts.AltiVec = 1;
-        Opts.CXXOperatorNames = 1;
-        Opts.LaxVectorConversions = 1;
-    }
+CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) {
+  return GetBasicType(getASTContext(), basic_type);
+}
 
-    // OpenCL and C++ both have bool, true, false keywords.
-    Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+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 (Opts.CPlusPlus)
-//        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
-//
-//    if (Args.hasArg(OPT_fobjc_gc_only))
-//        Opts.setGCMode(LangOptions::GCOnly);
-//    else if (Args.hasArg(OPT_fobjc_gc))
-//        Opts.setGCMode(LangOptions::HybridGC);
-//
-//    if (Args.hasArg(OPT_print_ivar_layout))
-//        Opts.ObjCGCBitmapPrint = 1;
-//
-//    if (Args.hasArg(OPT_faltivec))
-//        Opts.AltiVec = 1;
-//
-//    if (Args.hasArg(OPT_pthread))
-//        Opts.POSIXThreads = 1;
-//
-//    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
-//                                          "default");
-//    if (Vis == "default")
-        Opts.setValueVisibilityMode(DefaultVisibility);
-//    else if (Vis == "hidden")
-//        Opts.setVisibilityMode(LangOptions::Hidden);
-//    else if (Vis == "protected")
-//        Opts.setVisibilityMode(LangOptions::Protected);
-//    else
-//        Diags.Report(diag::err_drv_invalid_value)
-//        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
-
-//    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
-
-    // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
-    // is specified, or -std is set to a conforming mode.
-    Opts.Trigraphs = !Opts.GNUMode;
-//    if (Args.hasArg(OPT_trigraphs))
-//        Opts.Trigraphs = 1;
-//
-//    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
-//                                     OPT_fno_dollars_in_identifiers,
-//                                     !Opts.AsmPreprocessor);
-//    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
-//    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
-//    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
-//    if (Args.hasArg(OPT_fno_lax_vector_conversions))
-//        Opts.LaxVectorConversions = 0;
-//    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
-//    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
-//    Opts.Blocks = Args.hasArg(OPT_fblocks);
-      Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
-//    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
-//    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
-//    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
-//    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
-//    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
-//    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
-//    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
-//    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
-//    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
-//                                                 Diags);
-//    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
-//    Opts.ObjCConstantStringClass = getLastArgValue(Args,
-//                                                   OPT_fconstant_string_class);
-//    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
-//    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
-//    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
-//    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
-//    Opts.Static = Args.hasArg(OPT_static_define);
-    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;
+  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;
 
-//    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
-//    switch (SSP) {
-//        default:
-//            Diags.Report(diag::err_drv_invalid_value)
-//            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
-//            break;
-//        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
-//        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
-//        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); 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();
 
-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);
+  return CompilerType(ast, ast->getPointerType(char_type));
 }
 
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ClangASTContext::~ClangASTContext()
-{
-    Finalize();
+clang::DeclContext *
+ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) {
+  return ast->getTranslationUnitDecl();
 }
 
-ConstString
-ClangASTContext::GetPluginNameStatic()
-{
-    return ConstString("clang");
+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);
 }
 
-ConstString
-ClangASTContext::GetPluginName()
-{
-    return ClangASTContext::GetPluginNameStatic();
+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();
 }
 
-uint32_t
-ClangASTContext::GetPluginVersion()
-{
-    return 1;
+#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();
 }
 
-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);
-                }
-            }
+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.GetSize();
+  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 (template_param_infos.args[i].getKind() == TemplateArgument::Integral) {
+      template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
+          *ast,
+          ast->getTranslationUnitDecl(), // Is this the right decl context?,
+                                         // SourceLocation StartLoc,
+          SourceLocation(), SourceLocation(), depth, i, identifier_info,
+          template_param_infos.args[i].getIntegralType(), parameter_pack,
+          nullptr));
+
+    } else {
+      template_param_decls.push_back(TemplateTypeParmDecl::Create(
+          *ast,
+          ast->getTranslationUnitDecl(), // Is this the right decl context?
+          SourceLocation(), SourceLocation(), depth, i, identifier_info,
+          is_typename, parameter_pack));
+    }
+  }
+
+  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) {
+  //    /// \brief 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);
 
-            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()));
-                    ast_sp->m_scratch_ast_source_ap->InstallASTContext(ast_sp->getASTContext());
-                    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();
+  func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, &template_args,
+                                               nullptr);
 }
 
-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;
+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,
+      nullptr);
+
+  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;
 }
 
-void
-ClangASTContext::SetExternalSource (llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_ap)
-{
+ClassTemplateSpecializationDecl *
+ClangASTContext::CreateClassTemplateSpecializationDecl(
+    DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
+    const TemplateParameterInfos &template_param_infos) {
+  ASTContext *ast = getASTContext();
+  ClassTemplateSpecializationDecl *class_template_specialization_decl =
+      ClassTemplateSpecializationDecl::Create(
+          *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
+          SourceLocation(), class_template_decl, template_param_infos.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)
-    {
-        ast->setExternalSource (ast_source_ap);
-        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
-        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
-    }
+      return CompilerType(
+          ast, ast->getTagDeclType(class_template_specialization_decl));
+  }
+  return CompilerType();
 }
 
-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);
-        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(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, IK_ObjCXX, GetTargetTriple());
-//        InitializeLangOptions(*m_language_options_ap, IK_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();
+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;
 }
 
-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;
-};
+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;
+  }
 
-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;
+#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;
+}
 
-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();
+bool ClangASTContext::FieldIsBitfield(FieldDecl *field,
+                                      uint32_t &bitfield_bit_size) {
+  return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
 }
 
-#pragma mark Basic Types
+bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field,
+                                      uint32_t &bitfield_bit_size) {
+  if (ast == nullptr || field == nullptr)
+    return false;
 
-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)
+  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;
 }
 
-CompilerType
-ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, size_t bit_size)
-{
-    return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size);
+#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;
 }
 
-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;
+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!!!
+      }
     }
-    
-    return CompilerType();
+  }
+#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);
+}
 
-lldb::BasicType
-ClangASTContext::GetBasicTypeEnumeration (const ConstString &name)
-{
-    if (name)
-    {
-        typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
-        static TypeNameToBasicTypeMap g_type_map;
-        static std::once_flag g_once_flag;
-        std::call_once(g_once_flag, [](){
-            // "void"
-            g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
-            
-            // "char"
-            g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
-            g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
-            g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
-            g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
-            g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
-            g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
-            // "short"
-            g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
-            g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
-            g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
-            g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
-            
-            // "int"
-            g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
-            g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
-            g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
-            g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
-            
-            // "long"
-            g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
-            g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
-            g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
-            g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
-            
-            // "long long"
-            g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
-            g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
-            g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
-            g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
-            
-            // "int128"
-            g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
-            g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
-            
-            // Miscellaneous
-            g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
-            g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
-            g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
-            g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
-            g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
-            g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
-            g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
-            g_type_map.Sort();
-        });
-        
-        return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
-    }
-    return eBasicTypeInvalid;
+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;
 }
 
-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();
+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;
 }
 
-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;
+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;
 }
 
-CompilerType
-ClangASTContext::GetBasicType (lldb::BasicType basic_type)
-{
-    return GetBasicType (getASTContext(), basic_type);
+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;
+  }
 }
 
-CompilerType
-ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type)
-{
-    if (!ast)
-        return CompilerType();
-    lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, basic_type);
+#pragma mark Function Types
 
-    if (clang_type)
-        return CompilerType(GetASTContext(ast), clang_type);
-    return CompilerType();
+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()));
 
-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;
+  return CompilerType(this, block_type.getAsOpaquePtr());
+}
 
-            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();
-}
+#pragma mark Array Types
 
-CompilerType
-ClangASTContext::GetCStringType (bool is_const)
-{
+CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
+                                              size_t element_count,
+                                              bool is_vector) {
+  if (element_type.IsValid()) {
     ASTContext *ast = getASTContext();
-    QualType char_type(ast->CharTy);
-    
-    if (is_const)
-        char_type.addConst();
-    
-    return CompilerType (ast, ast->getPointerType(char_type));
-}
+    assert(ast != nullptr);
 
-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;
+    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("Trying to create a type for an existing name");
+    return type;
+  }
 
-    QualType type1_qual = ClangUtil::GetQualType(type1);
-    QualType type2_qual = ClangUtil::GetQualType(type2);
+  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;
 
-    if (ignore_qualifiers)
-    {
-        type1_qual = type1_qual.getUnqualifiedType();
-        type2_qual = type2_qual.getUnqualifiedType();
-    }
-    
-    return ast->getASTContext()->hasSameType (type1_qual, type2_qual);
+  return CreateStructForIdentifier(type_name, type_fields, packed);
 }
 
+#pragma mark Enumeration Types
+
 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();
+ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
+                                       const Declaration &decl,
+                                       const CompilerType &integer_clang_type) {
+  // 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 IsScoped = false;
+  //    const bool IsFixed = false;
+
+  EnumDecl *enum_decl = EnumDecl::Create(
+      *ast, decl_ctx, SourceLocation(), SourceLocation(),
+      name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
+      false,  // IsScoped
+      false,  // IsScopedUsingClassTag
+      false); // IsFixed
+
+  if (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();
 }
 
+// Disable this for now since I can't seem to get a nicely formatted float
+// out of the APFloat class without just getting the float, double or quad
+// and then using a formatted print on it which defeats the purpose. We ideally
+// would like to get perfect string values for any kind of float semantics
+// so we can support remote targets. The code below also requires a patch to
+// llvm::APInt.
+// bool
+// ClangASTContext::ConvertFloatValueToString (ASTContext *ast,
+// lldb::opaque_compiler_type_t clang_type, const uint8_t* bytes, size_t
+// byte_size, int apint_byte_order, std::string &float_str)
+//{
+//  uint32_t count = 0;
+//  bool is_complex = false;
+//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
+//  {
+//      unsigned num_bytes_per_float = byte_size / count;
+//      unsigned num_bits_per_float = num_bytes_per_float * 8;
+//
+//      float_str.clear();
+//      uint32_t i;
+//      for (i=0; i<count; i++)
+//      {
+//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float,
+//          (APInt::ByteOrder)apint_byte_order);
+//          bool is_ieee = false;
+//          APFloat ap_float(ap_int, is_ieee);
+//          char s[1024];
+//          unsigned int hex_digits = 0;
+//          bool upper_case = false;
+//
+//          if (ap_float.convertToHexString(s, hex_digits, upper_case,
+//          APFloat::rmNearestTiesToEven) > 0)
+//          {
+//              if (i > 0)
+//                  float_str.append(", ");
+//              float_str.append(s);
+//              if (i == 1 && is_complex)
+//                  float_str.append(1, 'i');
+//          }
+//      }
+//      return !float_str.empty();
+//  }
+//  return false;
+//}
+
+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;
+        }
 
-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();
-}
+        //--------------------------------------------------------------
+        // 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;
 
-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();
+        //--------------------------------------------------------------
+        // 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;
 
-#pragma mark Structure, Unions, Classes
+  ExternalASTSource *ast_source = ast->getExternalSource();
 
-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 (!ast_source)
+    return false;
 
+  if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
+    if (tag_decl->isCompleteDefinition())
+      return true;
 
-    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 (!tag_decl->hasExternalLexicalStorage())
+      return false;
 
-        if (access_type != eAccessNone)
-            decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
-    
-        if (decl_ctx)
-            decl_ctx->addDecl (decl);
+    ast_source->CompleteType(tag_decl);
 
-        return CompilerType(ast, ast->getTagDeclType(decl));
-    }
-    return CompilerType();
-}
+    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;
 
-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.GetSize();
-    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 (template_param_infos.args[i].getKind() == TemplateArgument::Integral)
-        {
-            template_param_decls.push_back (NonTypeTemplateParmDecl::Create (*ast,
-                                                                             ast->getTranslationUnitDecl(), // Is this the right decl context?, SourceLocation StartLoc,
-                                                                             SourceLocation(), 
-                                                                             SourceLocation(), 
-                                                                             depth, 
-                                                                             i,
-                                                                             identifier_info,
-                                                                             template_param_infos.args[i].getIntegralType(), 
-                                                                             parameter_pack, 
-                                                                             nullptr));
-            
-        }
-        else
-        {
-            template_param_decls.push_back (TemplateTypeParmDecl::Create (*ast, 
-                                                                          ast->getTranslationUnitDecl(), // Is this the right decl context?
-                                                                          SourceLocation(),
-                                                                          SourceLocation(),
-                                                                          depth, 
-                                                                          i,
-                                                                          identifier_info,
-                                                                          is_typename,
-                                                                          parameter_pack));
-        }
-    }
+    if (!objc_interface_decl->hasExternalLexicalStorage())
+      return false;
 
-    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)
-{
-//    /// \brief Create a function template node.
-    ASTContext *ast = getASTContext();
-    
-    llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+    ast_source->CompleteType(objc_interface_decl);
 
-    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);
+    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);
+}
 
-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,
-                                                     nullptr);
-    
-    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
-    }
+void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object,
+                                  ClangASTMetadata &metadata) {
+  ClangExternalASTSourceCommon *external_source =
+      ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
 
-    return class_template_decl;
+  if (external_source)
+    external_source->SetMetadata(object, metadata);
 }
 
+ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast,
+                                               const void *object) {
+  ClangExternalASTSourceCommon *external_source =
+      ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
 
-ClassTemplateSpecializationDecl *
-ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx,
-                                                        ClassTemplateDecl *class_template_decl,
-                                                        int kind,
-                                                        const TemplateParameterInfos &template_param_infos)
-{
-    ASTContext *ast = getASTContext();
-    ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::Create (*ast, 
-                                                                                                                   (TagDecl::TagKind)kind,
-                                                                                                                   decl_ctx,
-                                                                                                                   SourceLocation(), 
-                                                                                                                   SourceLocation(),
-                                                                                                                   class_template_decl,
-                                                                                                                   template_param_infos.args,
-                                                                                                                   nullptr);
-    
-    class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
-    
-    return class_template_specialization_decl;
+  if (external_source && external_source->HasMetadata(object))
+    return external_source->GetMetadata(object);
+  else
+    return nullptr;
 }
 
-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();
+clang::DeclContext *
+ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) {
+  return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
 }
 
-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;
+clang::DeclContext *
+ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) {
+  return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
 }
 
-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:
+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;
+}
 
-#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;
+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 false;
+    return true;
+  }
+  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;
+clang::DeclContext *
+ClangASTContext::GetDeclContextForType(const CompilerType &type) {
+  return GetDeclContextForType(ClangUtil::GetQualType(type));
 }
 
-bool
-ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
-{
-    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
-}
+clang::DeclContext *
+ClangASTContext::GetDeclContextForType(clang::QualType type) {
+  if (type.isNull())
+    return nullptr;
 
-bool
-ClangASTContext::FieldIsBitfield
-(
-    ASTContext *ast,
-    FieldDecl* field,
-    uint32_t& bitfield_bit_size
-)
-{
-    if (ast == nullptr || field == 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;
+      }
+    }
 
-    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;
+  } 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;
+      }
     }
-    return false;
-}
+  } break;
 
-bool
-ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
-{
-    if (record_decl == nullptr)
-        return false;
+  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;
+  }
 
-    if (!record_decl->field_empty())
-        return true;
+  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;
+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;
 }
 
-#pragma mark Objective C Classes
+//----------------------------------------------------------------------
+// Tests
+//----------------------------------------------------------------------
 
-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();
+bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
+  clang::QualType qual_type(GetCanonicalQualType(type));
 
-    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));
-}
+  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;
 
-static inline bool
-BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
-{
-    return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
-}
+  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;
 
-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;
-}
+  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;
 
-#pragma mark Namespace Declarations
+  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;
 
-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);        
+  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());
     }
-    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!!!
-            }
-        }
+    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());
     }
-#ifdef LLDB_CONFIGURATION_DEBUG
-    VerifyDecl(namespace_decl);
-#endif
-    return namespace_decl;
+    return true;
+  }
+  default:
+    break;
+  }
+  return false;
 }
 
-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);
-}
+bool ClangASTContext::IsRuntimeGeneratedType(
+    lldb::opaque_compiler_type_t type) {
+  clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext())
+                                     ->GetDeclContextForType(GetQualType(type));
+  if (!decl_ctx)
+    return false;
 
-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;
-}
+  if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
+    return false;
 
-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;
+  clang::ObjCInterfaceDecl *result_iface_decl =
+      llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
 
-    return nullptr;
+  ClangASTMetadata *ast_metadata =
+      ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
+  if (!ast_metadata)
+    return false;
+  return (ast_metadata->GetISAPtr() != 0);
 }
 
-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;
+bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
+  return GetQualType(type).getUnqualifiedType()->isCharType();
 }
 
-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;
+bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
+  const bool allow_completion = false;
+  return GetCompleteQualType(getASTContext(), GetQualType(type),
+                             allow_completion);
 }
 
-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;
+bool ClangASTContext::IsConst(lldb::opaque_compiler_type_t type) {
+  return GetQualType(type).isConstQualified();
 }
 
-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;
+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;
 }
 
-#pragma mark Function Types
+bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
+                                     bool *is_variadic_ptr) {
+  if (type) {
+    clang::QualType qual_type(GetCanonicalQualType(type));
 
-clang::DeclarationName
-ClangASTContext::GetDeclarationName(const char *name, const CompilerType &function_clang_type)
-{
-    if (!name || !name[0])
-        return clang::DeclarationName();
+    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;
+    }
 
-    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.
+    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;
+}
 
-    // 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();
+// 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;
 
-    
-    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;
+  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::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("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
- )
-{
-    // 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 IsScoped = false;
-    //    const bool IsFixed = false;
-    
-    EnumDecl *enum_decl = EnumDecl::Create (*ast,
-                                            decl_ctx,
-                                            SourceLocation(),
-                                            SourceLocation(),
-                                            name && name[0] ? &ast->Idents.get(name) : nullptr,
-                                            nullptr,
-                                            false,  // IsScoped
-                                            false,  // IsScopedUsingClassTag
-                                            false); // IsFixed
-    
-    
-    if (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();
-}
-
-// Disable this for now since I can't seem to get a nicely formatted float
-// out of the APFloat class without just getting the float, double or quad
-// and then using a formatted print on it which defeats the purpose. We ideally
-// would like to get perfect string values for any kind of float semantics
-// so we can support remote targets. The code below also requires a patch to
-// llvm::APInt.
-//bool
-//ClangASTContext::ConvertFloatValueToString (ASTContext *ast, lldb::opaque_compiler_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
-//{
-//  uint32_t count = 0;
-//  bool is_complex = false;
-//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
-//  {
-//      unsigned num_bytes_per_float = byte_size / count;
-//      unsigned num_bits_per_float = num_bytes_per_float * 8;
-//
-//      float_str.clear();
-//      uint32_t i;
-//      for (i=0; i<count; i++)
-//      {
-//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
-//          bool is_ieee = false;
-//          APFloat ap_float(ap_int, is_ieee);
-//          char s[1024];
-//          unsigned int hex_digits = 0;
-//          bool upper_case = false;
-//
-//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
-//          {
-//              if (i > 0)
-//                  float_str.append(", ");
-//              float_str.append(s);
-//              if (i == 1 && is_complex)
-//                  float_str.append(1, 'i');
-//          }
-//      }
-//      return !float_str.empty();
-//  }
-//  return false;
-//}
-
-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;
-        }
+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));
     }
-    if (pointee_type)
-        pointee_type->Clear();
-    return false;
+  }
+  return CompilerType();
 }
 
+bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
+  if (type) {
+    clang::QualType qual_type(GetCanonicalQualType(type));
 
-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;
-}
+    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));
 
-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;
-        }
+    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;
     }
-    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();
+    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;
     }
-    return false;
+  }
+  if (pointee_type)
+    pointee_type->Clear();
+  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;
+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();
-    return (type_class == clang::Type::Record);
+    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::IsEnumType(lldb::opaque_compiler_type_t type)
-{
-    if (!type)
-        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();
-    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;
-}
+    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);
 
-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;
-            }
-        }
+    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;
+  }
+  if (pointee_type)
+    pointee_type->Clear();
+  return false;
 }
 
-bool
-ClangASTContext::IsVoidType (lldb::opaque_compiler_type_t type)
-{
-    if (!type)
-        return false;
-    return GetCanonicalQualType(type)->isVoidType();
-}
+bool ClangASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
+                                          uint32_t &count, bool &is_complex) {
+  if (type) {
+    clang::QualType qual_type(GetCanonicalQualType(type));
 
-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;
-            }
-        }
+    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;
+      }
     }
-    class_name.clear();
-    return false;
+  }
+  count = 0;
+  is_complex = false;
+  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;
+bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
+  if (!type)
     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();
+  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;
-}
-
-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;
+  } 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;
     }
-    if (class_type_ptr)
-        class_type_ptr->Clear();
-    return false;
+  }
+  return true;
 }
 
-bool
-ClangASTContext::GetObjCClassName (const CompilerType& type, std::string &class_name)
-{
-    if (!type)
-        return false;
-
+bool ClangASTContext::IsObjCClassType(const CompilerType &type) {
+  if (type) {
     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;
-}
+    const clang::ObjCObjectPointerType *obj_pointer_type =
+        llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
 
+    if (obj_pointer_type)
+      return obj_pointer_type->isObjCClassType();
+  }
+  return false;
+}
 
-//----------------------------------------------------------------------
-// Type Completion
-//----------------------------------------------------------------------
+bool ClangASTContext::IsObjCObjectOrInterfaceType(const CompilerType &type) {
+  if (ClangUtil::IsClangType(type))
+    return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+  return false;
+}
 
-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);
+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);
 }
 
-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);
+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);
 }
 
-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));
-    
+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::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 0;
-            
-        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 0;
-        case clang::Type::TypeOf:                           return 0;
-        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;
+    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();
         }
-        default:                                            return 0;
-    }
-    return 0;
-}
+      }
+      break;
 
-
-
-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();
-        }
+    default:
+      break;
     }
-    return lldb::eLanguageTypeC;
+  }
+  return false;
 }
 
-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::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:               break;
-        case clang::Type::TypeOf:                   break;
-        case clang::Type::Decltype:                 break;
-        case clang::Type::TemplateSpecialization:   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;
-    }
-    // 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;
-}
+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;
 
-//----------------------------------------------------------------------
-// Creating related types
-//----------------------------------------------------------------------
+    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;
 
-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;
-        
+    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;
     }
-    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));
+    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;
         }
-    }
-    
-    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();
-}
+        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;
+              }
+            }
 
-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;
-}
+            if (success) {
+              if (dynamic_pointee_type)
+                dynamic_pointee_type->SetCompilerType(getASTContext(),
+                                                      pointee_qual_type);
+              return true;
+            }
+          }
+        }
+        break;
 
-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));
+      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;
         }
-    }
-    return CompilerType();
-}
+        break;
 
-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());
+      default:
+        break;
+      }
     }
-    return CompilerType();
+  }
+  if (dynamic_pointee_type)
+    dynamic_pointee_type->Clear();
+  return false;
 }
 
-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:
-                if (GetCompleteType(type))
-                {
-                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                    if (objc_class_type)
-                    {
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                        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;
-}
+bool ClangASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return false;
 
-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:
-                if (GetCompleteType(type))
-                {
-                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                    if (objc_class_type)
-                    {
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                        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);
+  return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
 }
 
-CompilerType
-ClangASTContext::GetNonReferenceType (lldb::opaque_compiler_type_t type)
-{
-    if (type)
-        return CompilerType(getASTContext(), GetQualType(type).getNonReferenceType());
-    return CompilerType();
+bool ClangASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return false;
+  return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
 }
 
-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
-        
-        // Get a uniqued clang::QualType for the typedef decl type
-        return CompilerType (clang_ast, clang_ast->getTypedefType (decl));
-    }
-    return CompilerType();
-    
+bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return false;
+  return GetCanonicalQualType(type)->isVoidType();
 }
-
-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();
+
+bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) {
+  return ClangASTContextSupportsLanguage(language);
 }
 
-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));
-        }
+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;
+      }
     }
-    return CompilerType();
+  }
+  class_name.clear();
+  return false;
 }
 
+bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
+  if (!type)
+    return false;
 
-CompilerType
-ClangASTContext::GetLValueReferenceType (lldb::opaque_compiler_type_t type)
-{
-    if (type)
-        return CompilerType(this, getASTContext()->getLValueReferenceType(GetQualType(type)).getAsOpaquePtr());
-    else
-        return CompilerType();
+  clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+  if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
+    return true;
+  return false;
 }
 
-CompilerType
-ClangASTContext::GetRValueReferenceType (lldb::opaque_compiler_type_t type)
-{
-    if (type)
-        return CompilerType(this, getASTContext()->getRValueReferenceType(GetQualType(type)).getAsOpaquePtr());
-    else
-        return CompilerType();
+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;
 }
 
-CompilerType
-ClangASTContext::AddConstModifier (lldb::opaque_compiler_type_t type)
-{
-    if (type)
-    {
-        clang::QualType result(GetQualType(type));
-        result.addConst();
-        return CompilerType (this, result.getAsOpaquePtr());
+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 CompilerType();
+    return true;
+  }
+  if (class_type_ptr)
+    class_type_ptr->Clear();
+  return false;
 }
 
-CompilerType
-ClangASTContext::AddVolatileModifier (lldb::opaque_compiler_type_t type)
-{
-    if (type)
-    {
-        clang::QualType result(GetQualType(type));
-        result.addVolatile();
-        return CompilerType (this, result.getAsOpaquePtr());
+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 CompilerType();
+  }
+  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);
 }
 
-CompilerType
-ClangASTContext::AddRestrictModifier (lldb::opaque_compiler_type_t type)
-{
-    if (type)
-    {
-        clang::QualType result(GetQualType(type));
-        result.addRestrict();
-        return CompilerType (this, result.getAsOpaquePtr());
+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 CompilerType();
-
+  }
+  return ConstString(type_name);
 }
 
-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);
+uint32_t
+ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
+                             CompilerType *pointee_or_element_clang_type) {
+  if (!type)
+    return 0;
 
-        decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+  if (pointee_or_element_clang_type)
+    pointee_or_element_clang_type->Clear();
 
-        // Get a uniqued clang::QualType for the typedef decl type
-        return CompilerType (this, clang_ast->getTypedefType (decl).getAsOpaquePtr());
+  clang::QualType qual_type(GetQualType(type));
 
+  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+  switch (type_class) {
+  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 CompilerType();
+    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;
 
-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();
-}
+  case clang::Type::DependentName:
+    return 0;
+  case clang::Type::DependentSizedExtVector:
+    return eTypeHasChildren | eTypeIsVector;
+  case clang::Type::DependentTemplateSpecialization:
+    return eTypeIsTemplate;
+  case clang::Type::Decltype:
+    return 0;
 
+  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;
 
-//----------------------------------------------------------------------
-// Create related types using the current type's AST
-//----------------------------------------------------------------------
+  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;
 
-CompilerType
-ClangASTContext::GetBasicTypeFromAST (lldb::BasicType basic_type)
-{
-    return ClangASTContext::GetBasicType(getASTContext(), basic_type);
-}
-//----------------------------------------------------------------------
-// Exploring the type
-//----------------------------------------------------------------------
+  case clang::Type::MemberPointer:
+    return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
 
-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::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::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;
-        }
-    }
+  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 0;
+  case clang::Type::TypeOf:
+    return 0;
+  case clang::Type::UnresolvedUsing:
     return 0;
-}
 
-size_t
-ClangASTContext::GetTypeBitAlign (lldb::opaque_compiler_type_t type)
-{
-    if (GetCompleteType(type))
-        return getASTContext()->getTypeAlign(GetQualType(type));
+  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;
 
-lldb::Encoding
-ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count)
-{
-    if (!type)
-        return lldb::eEncodingInvalid;
+  // 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;
 
-    count = 1;
-    clang::QualType qual_type(GetCanonicalQualType(type));
+      case clang::BuiltinType::NullPtr:
+        return eLanguageTypeC_plus_plus;
 
-    switch (qual_type->getTypeClass())
-    {
-        case clang::Type::UnaryTransform:
-            break;
+      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;
+}
 
-        case clang::Type::FunctionNoProto:
-        case clang::Type::FunctionProto:
-            break;
+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::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:
+    break;
+  case clang::Type::TypeOf:
+    break;
+  case clang::Type::Decltype:
+    break;
+  case clang::Type::TemplateSpecialization:
+    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;
+  }
+  // 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;
+}
 
-        case clang::Type::IncompleteArray:
-        case clang::Type::VariableArray:
-            break;
+//----------------------------------------------------------------------
+// Creating related types
+//----------------------------------------------------------------------
 
-        case clang::Type::ConstantArray:
-            break;
+CompilerType
+ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
+                                     uint64_t *stride) {
+  if (type) {
+    clang::QualType qual_type(GetCanonicalQualType(type));
 
-        case clang::Type::ExtVector:
-        case clang::Type::Vector:
-            // TODO: Set this to more than one???
-            break;
+    const clang::Type *array_eletype =
+        qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
 
-        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::Char16:
-                case clang::BuiltinType::Char32:
-                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::UShort:
-                case clang::BuiltinType::UInt:
-                case clang::BuiltinType::ULong:
-                case clang::BuiltinType::ULongLong:
-                case clang::BuiltinType::UInt128:
-                    return lldb::eEncodingUint;
-
-                case clang::BuiltinType::Half:
-                case clang::BuiltinType::Float:
-                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::OCLNDRange:
-                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;
-        }
+    if (!array_eletype)
+      return CompilerType();
 
-        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::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::TypeOfExpr:
-        case clang::Type::TypeOf:
-        case clang::Type::Decltype:
-        case clang::Type::TemplateSpecialization:
-        case clang::Type::Atomic:
-        case clang::Type::Adjusted:
-        case clang::Type::Pipe:
-            break;
+    CompilerType element_type(getASTContext(),
+                              array_eletype->getCanonicalTypeUnqualified());
 
-            // pointer type decayed from an array or function type.
-        case clang::Type::Decayed:
-            break;
-    }
-    count = 0;
-    return lldb::eEncodingInvalid;
+    // TODO: the real stride will be >= this value.. find the real one!
+    if (stride)
+      *stride = element_type.GetByteSize(nullptr);
+
+    return element_type;
+  }
+  return CompilerType();
 }
 
-lldb::Format
-ClangASTContext::GetFormat (lldb::opaque_compiler_type_t type)
-{
-    if (!type)
-        return lldb::eFormatDefault;
-    
+CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
+                                           uint64_t size) {
+  if (type) {
     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::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::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::TypeOfExpr:
-        case clang::Type::TypeOf:
-        case clang::Type::Decltype:
-        case clang::Type::TemplateSpecialization:
-        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;
+    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));
     }
-    // We don't know hot to display this type...
-    return lldb::eFormatBytes;
+  }
+  return CompilerType();
 }
 
-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;
+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:
+      if (GetCompleteType(type)) {
+        const clang::ObjCObjectPointerType *objc_class_type =
+            qual_type->getAsObjCInterfacePointerType();
+        if (objc_class_type) {
+          clang::ObjCInterfaceDecl *class_interface_decl =
+              objc_class_type->getInterfaceDecl();
+          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 false;
+  }
+  return num_functions;
 }
 
-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();
-                    }
-                }
+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:
+      if (GetCompleteType(type)) {
+        const clang::ObjCObjectPointerType *objc_class_type =
+            qual_type->getAsObjCInterfacePointerType();
+        if (objc_class_type) {
+          clang::ObjCInterfaceDecl *class_interface_decl =
+              objc_class_type->getInterfaceDecl();
+          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::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);
+      }
+      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;
+              }
             }
-            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;
+      }
+      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;
+    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;
     }
-    return num_children;
+  }
+
+  if (kind == eMemberFunctionKindUnknown)
+    return TypeMemberFunctionImpl();
+  else
+    return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
 }
 
 CompilerType
-ClangASTContext::GetBuiltinTypeByName (const ConstString &name)
-{
-    return GetBasicType(GetBasicTypeEnumeration(name));
+ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
+  if (type)
+    return CompilerType(getASTContext(),
+                        GetQualType(type).getNonReferenceType());
+  return CompilerType();
 }
 
-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;
-}
+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));
 
-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;
-            }
-        }
-    }
+    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
+
+    // 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();
+}
 
-#pragma mark Aggregate Types
+CompilerType
+ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
+  if (type) {
+    clang::QualType qual_type(GetQualType(type));
 
-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;
+    switch (type_class) {
+    case clang::Type::ObjCObject:
+    case clang::Type::ObjCInterface:
+      return CompilerType(getASTContext(),
+                          getASTContext()->getObjCObjectPointerType(qual_type));
 
-        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:
-            if (GetCompleteType(type))
-            {
-                const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                    
-                    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;
+    default:
+      return CompilerType(getASTContext(),
+                          getASTContext()->getPointerType(qual_type));
     }
-    return count;
+  }
+  return CompilerType();
 }
 
-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::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
+  if (type)
+    return CompilerType(this, getASTContext()
+                                  ->getLValueReferenceType(GetQualType(type))
+                                  .getAsOpaquePtr());
+  else
+    return CompilerType();
 }
 
 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:
-            if (GetCompleteType(type))
-            {
-                const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                    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;
-    }
+ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
+  if (type)
+    return CompilerType(this, getASTContext()
+                                  ->getRValueReferenceType(GetQualType(type))
+                                  .getAsOpaquePtr());
+  else
     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();
+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();
+}
 
-                    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();
+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();
+}
 
-                    if (class_interface_decl && class_interface_decl->getSuperClass())
-                        count = 1;
-                }
-            }
-            break;
+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));
 
-        case clang::Type::Typedef:
-            count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-            break;
+    clang::DeclContext *decl_ctx =
+        ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
+    if (decl_ctx == nullptr)
+      decl_ctx = getASTContext()->getTranslationUnitDecl();
 
-        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;
+    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();
+}
 
-        case clang::Type::Paren:
-            return GetNumDirectBaseClasses(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+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();
+}
 
-        default:
-            break;
-    }
-    return count;
+//----------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------
 
-uint32_t
-ClangASTContext::GetNumVirtualBaseClasses (lldb::opaque_compiler_type_t type)
-{
-    uint32_t count = 0;
+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))
-            {
-                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;
+    switch (type_class) {
+    case clang::Type::Record:
+      if (GetCompleteType(type))
+        return getASTContext()->getTypeSize(qual_type);
+      else
+        return 0;
+      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::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;
 
-        case clang::Type::Paren:
-            count = GetNumVirtualBaseClasses(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-            break;
+  count = 1;
+  clang::QualType qual_type(GetCanonicalQualType(type));
 
-        default:
-            break;
+  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::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::Char16:
+    case clang::BuiltinType::Char32:
+    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::UShort:
+    case clang::BuiltinType::UInt:
+    case clang::BuiltinType::ULong:
+    case clang::BuiltinType::ULongLong:
+    case clang::BuiltinType::UInt128:
+      return lldb::eEncodingUint;
+
+    case clang::BuiltinType::Half:
+    case clang::BuiltinType::Float:
+    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::OCLNDRange:
+    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::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::TypeOfExpr:
+  case clang::Type::TypeOf:
+  case clang::Type::Decltype:
+  case clang::Type::TemplateSpecialization:
+  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;
+  }
+  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::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;
     }
-    return count;
+    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::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::TypeOfExpr:
+  case clang::Type::TypeOf:
+  case clang::Type::Decltype:
+  case clang::Type::TemplateSpecialization:
+  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;
+  }
+  // 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;
 }
 
-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;
+uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
+                                         bool omit_empty_base_classes) {
+  if (!type)
+    return 0;
 
-        case clang::Type::ObjCObjectPointer:
-            return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
+  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;
 
-        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;
+    default:
+      break;
+    }
+    break;
 
+  case clang::Type::Complex:
+    return 0;
 
-        case clang::Type::Typedef:
-            return GetDirectBaseClassAtIndex (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), idx, bit_offset_ptr);
+  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::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::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::Paren:
-            return GetDirectBaseClassAtIndex (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, bit_offset_ptr);
+  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;
+}
 
-        default:
-            break;
-    }
-    return CompilerType();
+CompilerType ClangASTContext::GetBuiltinTypeByName(const ConstString &name) {
+  return GetBasicType(GetBasicTypeEnumeration(name));
 }
 
-CompilerType
-ClangASTContext::GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type,
-                                             size_t idx,
-                                             uint32_t *bit_offset_ptr)
-{
-    clang::QualType qual_type(GetCanonicalQualType(type));
+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();
-    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;
+    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;
+      }
+    }
+  }
+}
 
-                            }
-                            return CompilerType (this, base_class->getType().getAsOpaquePtr());
-                        }
-                    }
-                }
-            }
-            break;
+#pragma mark Aggregate Types
+
+uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return 0;
 
-        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);
+  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:
+    if (GetCompleteType(type)) {
+      const clang::ObjCObjectPointerType *objc_class_type =
+          qual_type->getAsObjCInterfacePointerType();
+      if (objc_class_type) {
+        clang::ObjCInterfaceDecl *class_interface_decl =
+            objc_class_type->getInterfaceDecl();
 
-        default:
-            break;
+        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:
+    if (GetCompleteType(type)) {
+      const clang::ObjCObjectPointerType *objc_class_type =
+          qual_type->getAsObjCInterfacePointerType();
+      if (objc_class_type) {
+        clang::ObjCInterfaceDecl *class_interface_decl =
+            objc_class_type->getInterfaceDecl();
+        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
@@ -6250,776 +6156,757 @@ ClangASTContext::GetVirtualBaseClassAtIn
 // 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 0;
-        case clang::Type::TypeOf:                   return 0;
-        case clang::Type::Decltype:                 return 0;
-        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;
+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 0;
+  case clang::Type::TypeOf:
+    return 0;
+  case clang::Type::Decltype:
+    return 0;
+  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();
 
-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);
-    uint32_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)
-                                {
-                                    Error 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 uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
-                                                            if (base_offset != UINT32_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 uint64_t base_offset = process->ReadUnsignedIntegerFromMemory(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().c_str());
-                        
-                        // 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().c_str());
-                                        
-                                        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;
-                                }
+  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);
+  uint32_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) {
+                Error 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 uint32_t base_offset =
+                                process->ReadUnsignedIntegerFromMemory(
+                                    base_offset_addr, 4, UINT32_MAX, err);
+                            if (base_offset != UINT32_MAX) {
+                              handled = true;
+                              bit_offset = base_offset * 8;
                             }
-                            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().c_str());
-                                    
-                                    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 UINT32_MAX to make sure we don't compute it twice...
-                                    bit_offset = UINT32_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 == UINT32_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;
+                      } 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 uint64_t base_offset =
+                                process->ReadUnsignedIntegerFromMemory(
+                                    base_offset_addr, base_offset_size,
+                                    UINT32_MAX, err);
+                            if (base_offset < UINT32_MAX) {
+                              handled = true;
+                              bit_offset = base_offset * 8;
                             }
+                          }
                         }
+                      }
                     }
+                  }
                 }
-            }
-            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())
-                    {
-                        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::Pointer:
-            if (idx_is_valid)
-            {
-                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();
-}
+              }
+              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().c_str());
+
+          // 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().c_str());
+
+                  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().c_str());
+
+                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 UINT32_MAX to make sure we don't compute it
+                // twice...
+                bit_offset = UINT32_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 == UINT32_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()) {
+          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::Pointer:
+    if (idx_is_valid) {
+      CompilerType pointee_clang_type(GetPointeeType(type));
 
-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;
-}
+      // 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;
+  }
 
-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;
+  return UINT32_MAX;
 }
 
 // Look for a child member (doesn't include base classes, but it does include
@@ -7046,2859 +6933,2849 @@ GetIndexForRecordChild (const clang::Rec
 // 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:
+// 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;
-        }
+// 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;
+  }
+  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;
+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));
 
-            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;
+    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;
+          }
         }
-    }
-    return UINT32_MAX;
-}
 
+        // 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;
 
-size_t
-ClangASTContext::GetNumTemplateArguments (lldb::opaque_compiler_type_t type)
-{
-    if (!type)
-        return 0;
+    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;
 
-    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();
-                }
+                return child_idx;
+              }
             }
-            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;
+
+            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;
 }
 
 CompilerType
-ClangASTContext::GetTemplateArgument (lldb::opaque_compiler_type_t type, size_t arg_idx, lldb::TemplateArgumentKind &kind)
-{
-    if (!type)
-        return CompilerType();
+ClangASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type,
+                                     size_t arg_idx,
+                                     lldb::TemplateArgumentKind &kind) {
+  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::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 && arg_idx < template_decl->getTemplateArgs().size())
-                    {
-                        const clang::TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
-                        switch (template_arg.getKind())
-                        {
-                            case clang::TemplateArgument::Null:
-                                kind = eTemplateArgumentKindNull;
-                                return CompilerType();
-                                
-                            case clang::TemplateArgument::Type:
-                                kind = eTemplateArgumentKindType;
-                                return CompilerType(getASTContext(), template_arg.getAsType());
-                                
-                            case clang::TemplateArgument::Declaration:
-                                kind = eTemplateArgumentKindDeclaration;
-                                return CompilerType();
-                                
-                            case clang::TemplateArgument::Integral:
-                                kind = eTemplateArgumentKindIntegral;
-                                return CompilerType(getASTContext(), template_arg.getIntegralType());
-                                
-                            case clang::TemplateArgument::Template:
-                                kind = eTemplateArgumentKindTemplate;
-                                return CompilerType();
-                                
-                            case clang::TemplateArgument::TemplateExpansion:
-                                kind = eTemplateArgumentKindTemplateExpansion;
-                                return CompilerType();
-                                
-                            case clang::TemplateArgument::Expression:
-                                kind = eTemplateArgumentKindExpression;
-                                return CompilerType();
-                                
-                            case clang::TemplateArgument::Pack:
-                                kind = eTemplateArgumentKindPack;
-                                return CompilerType();
-                                
-                            default:
-                                assert (!"Unhandled clang::TemplateArgument::ArgKind");
-                                break;
-                        }
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::Typedef:
-            return (CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType())).GetTemplateArgument(arg_idx, kind);
-
-        case clang::Type::Auto:
-            return (CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType())).GetTemplateArgument(arg_idx, kind);
-            
-        case clang::Type::Elaborated:
-            return (CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())).GetTemplateArgument(arg_idx, kind);
-            
-        case clang::Type::Paren:
-            return (CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar())).GetTemplateArgument(arg_idx, kind);
-            
-        default:
+  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 &&
+            arg_idx < template_decl->getTemplateArgs().size()) {
+          const clang::TemplateArgument &template_arg =
+              template_decl->getTemplateArgs()[arg_idx];
+          switch (template_arg.getKind()) {
+          case clang::TemplateArgument::Null:
+            kind = eTemplateArgumentKindNull;
+            return CompilerType();
+
+          case clang::TemplateArgument::Type:
+            kind = eTemplateArgumentKindType;
+            return CompilerType(getASTContext(), template_arg.getAsType());
+
+          case clang::TemplateArgument::Declaration:
+            kind = eTemplateArgumentKindDeclaration;
+            return CompilerType();
+
+          case clang::TemplateArgument::Integral:
+            kind = eTemplateArgumentKindIntegral;
+            return CompilerType(getASTContext(),
+                                template_arg.getIntegralType());
+
+          case clang::TemplateArgument::Template:
+            kind = eTemplateArgumentKindTemplate;
+            return CompilerType();
+
+          case clang::TemplateArgument::TemplateExpansion:
+            kind = eTemplateArgumentKindTemplateExpansion;
+            return CompilerType();
+
+          case clang::TemplateArgument::Expression:
+            kind = eTemplateArgumentKindExpression;
+            return CompilerType();
+
+          case clang::TemplateArgument::Pack:
+            kind = eTemplateArgumentKindPack;
+            return CompilerType();
+
+          default:
+            assert(!"Unhandled clang::TemplateArgument::ArgKind");
             break;
+          }
+        }
+      }
     }
-    kind = eTemplateArgumentKindNull;
-    return CompilerType ();
+    break;
+
+  case clang::Type::Typedef:
+    return (CompilerType(getASTContext(),
+                         llvm::cast<clang::TypedefType>(qual_type)
+                             ->getDecl()
+                             ->getUnderlyingType()))
+        .GetTemplateArgument(arg_idx, kind);
+
+  case clang::Type::Auto:
+    return (CompilerType(
+                getASTContext(),
+                llvm::cast<clang::AutoType>(qual_type)->getDeducedType()))
+        .GetTemplateArgument(arg_idx, kind);
+
+  case clang::Type::Elaborated:
+    return (CompilerType(
+                getASTContext(),
+                llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()))
+        .GetTemplateArgument(arg_idx, kind);
+
+  case clang::Type::Paren:
+    return (CompilerType(getASTContext(),
+                         llvm::cast<clang::ParenType>(qual_type)->desugar()))
+        .GetTemplateArgument(arg_idx, kind);
+
+  default:
+    break;
+  }
+  kind = eTemplateArgumentKindNull;
+  return CompilerType();
+}
+
+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();
 }
 
-CompilerType
-ClangASTContext::GetTypeForFormatters (void* type)
-{
-    if (type)
-        return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
-    return CompilerType();
+clang::CXXRecordDecl *
+ClangASTContext::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
+  return GetCanonicalQualType(type)->getAsCXXRecordDecl();
 }
 
-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::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::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();
+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::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::FieldDecl *field = nullptr;
 
-clang::CXXRecordDecl *
-ClangASTContext::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type)
-{
-    return GetCanonicalQualType(type)->getAsCXXRecordDecl();
-}
+  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));
 
-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;
-}
+      record_decl->addDecl(field);
 
-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);
+      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);
-                
+  } 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);
+        VerifyDecl(field);
 #endif
-            }
-        }
+      }
     }
-    return field;
+  }
+  return field;
 }
 
-void
-ClangASTContext::BuildIndirectFields (const CompilerType& type)
-{
-    if (!type)
-        return;
+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);
 
-    ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
-    if (!ast)
+      if (!record_decl)
         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);
+      record_decl->addAttr(
+          clang::PackedAttr::CreateImplicit(*ast->getASTContext()));
     }
+  }
 }
 
-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);
 
-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);
+      VerifyDecl(var_decl);
 #endif
-        }
     }
-    return var_decl;
+  }
+  return var_decl;
 }
 
+clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
+    lldb::opaque_compiler_type_t type, const char *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::CXXMethodDecl *
-ClangASTContext::AddMethodToCXXRecordType (lldb::opaque_compiler_type_t type, const char *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()));
-    
-    // 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);
-        }
+  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()));
+
+  // 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);
+  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;
-}
 
+  //    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;
+}
 
 #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;
-}
+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);
 
-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;
-    }
-}
+      if (property_decl) {
+        if (metadata)
+          ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
 
-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;
-}
+        class_interface_decl->addDecl(property_decl);
 
-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();
+        clang::Selector setter_sel, getter_sel;
 
-    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;
+        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.c_str());
+          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.c_str());
+          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;
+  }
+  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.c_str());
-                    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.c_str());
-                    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);
-                    }
-                }
+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;
 
-                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;
-}
+  clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
 
-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;
-}
+  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;
 
-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;
-}
+  selector_start++;
+  llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;
 
-bool
-ClangASTContext::GetHasExternalStorage (const CompilerType &type)
-{
-    if (ClangUtil::IsClangType(type))
-        return false;
+  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;
+  }
 
-    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+  if (selector_idents.size() == 0)
+    return nullptr;
 
-    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;
+  clang::Selector method_selector = ast->Selectors.getSelector(
+      num_selectors_with_args ? selector_idents.size() : 0,
+      selector_idents.data());
 
-        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;
+  clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
 
-        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();
+  // Populate the method decl with parameter decls
+  const clang::Type *method_type(method_qual_type.getTypePtr());
 
-                if (class_interface_decl)
-                    return class_interface_decl->hasExternalLexicalStorage () || class_interface_decl->hasExternalVisibleStorage ();
-            }
-        }
-            break;
+  if (method_type == nullptr)
+    return nullptr;
 
-        case clang::Type::Typedef:
-            return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+  const clang::FunctionProtoType *method_function_prototype(
+      llvm::dyn_cast<clang::FunctionProtoType>(method_type));
 
-        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()));
+  if (!method_function_prototype)
+    return nullptr;
 
-        case clang::Type::Paren:
-            return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+  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*/);
 
-        default:
-            break;
+  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;
+      }
     }
-    return false;
+  } 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::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;
+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;
+      }
     }
-    return false;
+
+    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();
 
-#pragma mark TagDecl
+          /// TODO This really needs to be fixed.
 
-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;
-            }
+          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;
+  }
+  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;
-                }
-            }
-        }
+bool 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));
 
-        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;
-}
+    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);
 
-bool
-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);
+          VerifyDecl(enumerator_decl);
 #endif
-                    
-                    return true;
-                }
-            }
+
+          return true;
         }
+      }
     }
-    return false;
+  }
+  return false;
 }
 
 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());
-        }
+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();
+  }
+  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();
+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::Error get_data_error;
-                if (scalar.GetAsMemoryData(dst, byte_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
-                    return byte_size;
-            }
-        }
+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::Error get_data_error;
+        if (scalar.GetAsMemoryData(dst, byte_size,
+                                   lldb_private::endian::InlHostByteOrder(),
+                                   get_data_error))
+          return byte_size;
+      }
     }
-    return 0;
+  }
+  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 lldb_private::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->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
-                        
-                        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('"');
-                data.Dump(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.
-            data.Dump(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;
-    }
-}
+void ClangASTContext::DumpValue(
+    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
+    lldb::Format format, const lldb_private::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->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "",
+                    base_class_type_name.c_str());
+
+          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('"');
+      data.Dump(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.
+    data.Dump(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 lldb_private::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));
 
-bool
-ClangASTContext::DumpTypeValue (lldb::opaque_compiler_type_t type, Stream *s,
-                                   lldb::Format format,
-                                   const lldb_private::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().c_str());
-                                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().c_str());
-                                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 data.Dump (s,
-                                  byte_offset,
-                                  format,
-                                  byte_size,
-                                  item_count,
-                                  UINT32_MAX,
-                                  LLDB_INVALID_ADDRESS,
-                                  bitfield_bit_size,
-                                  bitfield_bit_offset,
-                                  exe_scope);
-            }
-                break;
+    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().c_str());
+              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().c_str());
+              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 0;
-}
+        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 data.Dump(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);
 
+        lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(),
+                                              process->GetByteOrder(), 4);
+        buf.back() = '\0';
+        size_t bytes_read;
+        size_t total_cstr_len = 0;
+        Error 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(" \"");
+          cstr_data.Dump(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));
 
-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);
-                
-                lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), process->GetByteOrder(), 4);
-                buf.back() = '\0';
-                size_t bytes_read;
-                size_t total_cstr_len = 0;
-                Error 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 (" \"");
-                    cstr_data.Dump(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 ('"');
-            }
-        }
-    }
-}
+    llvm::SmallVector<char, 1024> buf;
+    llvm::raw_svector_ostream llvm_ostrm(buf);
 
-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);
+    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.c_str());
+        }
+      }
+    } 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.c_str());
+      }
+    }
     }
-}
-
-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.c_str());
-                    }
-                }
-            }
-                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.c_str());
-                }
-            }
-        }
-        
-        if (buf.size() > 0)
-        {
-            s->Write (buf.data(), buf.size());
-        }
+    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;
-
+void ClangASTContext::DumpTypeName(const CompilerType &type) {
+  if (ClangUtil::IsClangType(type)) {
+    clang::QualType qual_type(
+        ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
 
-            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()));
+    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;
-        }
+    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);
+  }
+}
 
-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;
-    DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser();
-    return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(record_decl, bit_size, alignment, field_offsets,
-                                                                    base_offsets, vbase_offsets);
+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;
+  DWARFASTParserClang *dwarf_ast_parser =
+      (DWARFASTParserClang *)ast->GetDWARFParser();
+  return dwarf_ast_parser->GetClangASTImporter().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());
-            }
+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();
+  }
+  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();
+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;
+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();
+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));
-                    }
-                }
-            }
+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;
+  }
+  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.
+// 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
+// The optional name is required by languages (like C++) to handle using
+// declarations
 // like:
 //
 //     void poo();
@@ -9927,288 +9804,269 @@ ClangASTContext::DeclContextFindDeclByNa
 //     }
 //
 // 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
+// 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())
+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;
-                
-                // 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;
-                            }
-                        }
-                    }
                 }
+                // Found it!
+                return level;
+              }
             }
-            ++level;
+          }
         }
+      }
+      ++level;
     }
-    return LLDB_INVALID_DECL_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;
+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::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;
-            }
-        }
+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;
+  }
+  return false;
 }
 
 clang::DeclContext *
-ClangASTContext::DeclContextGetAsDeclContext (const CompilerDeclContext &dc)
-{
-    if (dc.IsClang())
-        return (clang::DeclContext *)dc.GetOpaqueDeclContext();
-    return nullptr;
+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;
+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;
+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;
+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;
+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;
+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();
+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(
+    const char *expr, const char *expr_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, expr_prefix, language,
+                                 desired_type, options);
 }
 
-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 (const char *expr,
-                   const char *expr_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, 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);
+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);
+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();
+ClangASTContextForExpressions::GetPersistentExpressionState() {
+  return m_persistent_variables.get();
 }

Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Tue Sep  6 15:57:50 2016
@@ -22,1192 +22,1096 @@
 using namespace lldb_private;
 using namespace clang;
 
-ClangASTMetrics::Counters ClangASTMetrics::global_counters = { 0, 0, 0, 0, 0, 0 };
-ClangASTMetrics::Counters ClangASTMetrics::local_counters = { 0, 0, 0, 0, 0, 0 };
+ClangASTMetrics::Counters ClangASTMetrics::global_counters = {0, 0, 0, 0, 0, 0};
+ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0};
 
-void ClangASTMetrics::DumpCounters (Log *log, ClangASTMetrics::Counters &counters)
-{
-    log->Printf("  Number of visible Decl queries by name     : %" PRIu64, counters.m_visible_query_count);
-    log->Printf("  Number of lexical Decl queries             : %" PRIu64, counters.m_lexical_query_count);
-    log->Printf("  Number of imports initiated by LLDB        : %" PRIu64, counters.m_lldb_import_count);
-    log->Printf("  Number of imports conducted by Clang       : %" PRIu64, counters.m_clang_import_count);
-    log->Printf("  Number of Decls completed                  : %" PRIu64, counters.m_decls_completed_count);
-    log->Printf("  Number of records laid out                 : %" PRIu64, counters.m_record_layout_count);
-}
-
-void ClangASTMetrics::DumpCounters (Log *log)
-{
-    if (!log)
-        return;
-    
-    log->Printf("== ClangASTMetrics output ==");
-    log->Printf("-- Global metrics --");
-    DumpCounters (log, global_counters);
-    log->Printf("-- Local metrics --");
-    DumpCounters (log, local_counters);
-}
-
-clang::QualType
-ClangASTImporter::CopyType (clang::ASTContext *dst_ast,
-                            clang::ASTContext *src_ast,
-                            clang::QualType type)
-{
-    MinionSP minion_sp (GetMinion(dst_ast, src_ast));
-    
-    if (minion_sp)
-        return minion_sp->Import(type);
-    
-    return QualType();
+void ClangASTMetrics::DumpCounters(Log *log,
+                                   ClangASTMetrics::Counters &counters) {
+  log->Printf("  Number of visible Decl queries by name     : %" PRIu64,
+              counters.m_visible_query_count);
+  log->Printf("  Number of lexical Decl queries             : %" PRIu64,
+              counters.m_lexical_query_count);
+  log->Printf("  Number of imports initiated by LLDB        : %" PRIu64,
+              counters.m_lldb_import_count);
+  log->Printf("  Number of imports conducted by Clang       : %" PRIu64,
+              counters.m_clang_import_count);
+  log->Printf("  Number of Decls completed                  : %" PRIu64,
+              counters.m_decls_completed_count);
+  log->Printf("  Number of records laid out                 : %" PRIu64,
+              counters.m_record_layout_count);
 }
 
-lldb::opaque_compiler_type_t
-ClangASTImporter::CopyType (clang::ASTContext *dst_ast,
-                            clang::ASTContext *src_ast,
-                            lldb::opaque_compiler_type_t type)
-{
-    return CopyType (dst_ast, src_ast, QualType::getFromOpaquePtr(type)).getAsOpaquePtr();
-}
-
-CompilerType
-ClangASTImporter::CopyType (ClangASTContext &dst_ast,
-                            const CompilerType &src_type)
-{
-    clang::ASTContext *dst_clang_ast = dst_ast.getASTContext();
-    if (dst_clang_ast)
-    {
-        ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
-        if (src_ast)
-        {
-            clang::ASTContext *src_clang_ast = src_ast->getASTContext();
-            if (src_clang_ast)
-            {
-                lldb::opaque_compiler_type_t dst_clang_type = CopyType(dst_clang_ast,
-                                                                       src_clang_ast,
-                                                                       src_type.GetOpaqueQualType());
-
-                if (dst_clang_type)
-                    return CompilerType(&dst_ast, dst_clang_type);
-            }
-        }
-    }
-    return CompilerType();
+void ClangASTMetrics::DumpCounters(Log *log) {
+  if (!log)
+    return;
+
+  log->Printf("== ClangASTMetrics output ==");
+  log->Printf("-- Global metrics --");
+  DumpCounters(log, global_counters);
+  log->Printf("-- Local metrics --");
+  DumpCounters(log, local_counters);
+}
+
+clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
+                                           clang::ASTContext *src_ast,
+                                           clang::QualType type) {
+  MinionSP minion_sp(GetMinion(dst_ast, src_ast));
+
+  if (minion_sp)
+    return minion_sp->Import(type);
+
+  return QualType();
 }
 
-clang::Decl *
-ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast,
-                            clang::ASTContext *src_ast,
-                            clang::Decl *decl)
-{
-    MinionSP minion_sp;
-    
-    minion_sp = GetMinion(dst_ast, src_ast);
-    
-    if (minion_sp)
-    {
-        clang::Decl *result = minion_sp->Import(decl);
-        
-        if (!result)
-        {
-            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
-            if (log)
-            {
-                lldb::user_id_t user_id = LLDB_INVALID_UID;
-                ClangASTMetadata *metadata = GetDeclMetadata(decl);
-                if (metadata)
-                    user_id = metadata->GetUserID();
-                
-                if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
-                    log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64,
-                                decl->getDeclKindName(),
-                                named_decl->getNameAsString().c_str(),
-                                user_id);
-                else
-                    log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64,
-                                decl->getDeclKindName(),
-                                user_id);
-            }
-        }
-        
-        return result;
+lldb::opaque_compiler_type_t
+ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
+                           clang::ASTContext *src_ast,
+                           lldb::opaque_compiler_type_t type) {
+  return CopyType(dst_ast, src_ast, QualType::getFromOpaquePtr(type))
+      .getAsOpaquePtr();
+}
+
+CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast,
+                                        const CompilerType &src_type) {
+  clang::ASTContext *dst_clang_ast = dst_ast.getASTContext();
+  if (dst_clang_ast) {
+    ClangASTContext *src_ast =
+        llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
+    if (src_ast) {
+      clang::ASTContext *src_clang_ast = src_ast->getASTContext();
+      if (src_clang_ast) {
+        lldb::opaque_compiler_type_t dst_clang_type = CopyType(
+            dst_clang_ast, src_clang_ast, src_type.GetOpaqueQualType());
+
+        if (dst_clang_type)
+          return CompilerType(&dst_ast, dst_clang_type);
+      }
+    }
+  }
+  return CompilerType();
+}
+
+clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
+                                        clang::ASTContext *src_ast,
+                                        clang::Decl *decl) {
+  MinionSP minion_sp;
+
+  minion_sp = GetMinion(dst_ast, src_ast);
+
+  if (minion_sp) {
+    clang::Decl *result = minion_sp->Import(decl);
+
+    if (!result) {
+      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+      if (log) {
+        lldb::user_id_t user_id = LLDB_INVALID_UID;
+        ClangASTMetadata *metadata = GetDeclMetadata(decl);
+        if (metadata)
+          user_id = metadata->GetUserID();
+
+        if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
+          log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s "
+                      "'%s', metadata 0x%" PRIx64,
+                      decl->getDeclKindName(),
+                      named_decl->getNameAsString().c_str(), user_id);
+        else
+          log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s, "
+                      "metadata 0x%" PRIx64,
+                      decl->getDeclKindName(), user_id);
+      }
     }
-    
-    return nullptr;
+
+    return result;
+  }
+
+  return nullptr;
 }
 
-class DeclContextOverride
-{
+class DeclContextOverride {
 private:
-    struct Backup
-    {
-        clang::DeclContext *decl_context;
-        clang::DeclContext *lexical_decl_context;
-    };
-    
-    std::map<clang::Decl *, Backup> m_backups;
-    
-    void OverrideOne(clang::Decl *decl)
-    {
-        if (m_backups.find(decl) != m_backups.end())
-        {
-            return;
-        }
-            
-        m_backups[decl] = { decl->getDeclContext(), decl->getLexicalDeclContext() };
-        
-        decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl());
-        decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl());
-    }
-    
-    bool ChainPassesThrough(clang::Decl *decl,
-                            clang::DeclContext *base,
-                            clang::DeclContext *(clang::Decl::*contextFromDecl)(),
-                            clang::DeclContext *(clang::DeclContext::*contextFromContext)())
-    {
-        for (DeclContext *decl_ctx = (decl->*contextFromDecl)();
-             decl_ctx;
-             decl_ctx = (decl_ctx->*contextFromContext)())
-        {
-            if (decl_ctx == base)
-            {
-                return true;
-            }
-        }
-        
-        return false;
+  struct Backup {
+    clang::DeclContext *decl_context;
+    clang::DeclContext *lexical_decl_context;
+  };
+
+  std::map<clang::Decl *, Backup> m_backups;
+
+  void OverrideOne(clang::Decl *decl) {
+    if (m_backups.find(decl) != m_backups.end()) {
+      return;
+    }
+
+    m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()};
+
+    decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl());
+    decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl());
+  }
+
+  bool ChainPassesThrough(
+      clang::Decl *decl, clang::DeclContext *base,
+      clang::DeclContext *(clang::Decl::*contextFromDecl)(),
+      clang::DeclContext *(clang::DeclContext::*contextFromContext)()) {
+    for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx;
+         decl_ctx = (decl_ctx->*contextFromContext)()) {
+      if (decl_ctx == base) {
+        return true;
+      }
     }
-    
-    clang::Decl *GetEscapedChild(clang::Decl *decl, clang::DeclContext *base = nullptr)
-    {
-        if (base)
-        {
-            // decl's DeclContext chains must pass through base.
-            
-            if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, &clang::DeclContext::getParent) ||
-                !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, &clang::DeclContext::getLexicalParent))
-            {
-                return decl;
-            }
-        }
-        else
-        {
-            base = clang::dyn_cast<clang::DeclContext>(decl);
-            
-            if (!base)
-            {
-                return nullptr;
-            }
-        }
-        
-        if (clang::DeclContext *context = clang::dyn_cast<clang::DeclContext>(decl))
-        {
-            for (clang::Decl *decl : context->decls())
-            {
-                if (clang::Decl *escaped_child = GetEscapedChild(decl))
-                {
-                    return escaped_child;
-                }
-            }
-        }
-        
+
+    return false;
+  }
+
+  clang::Decl *GetEscapedChild(clang::Decl *decl,
+                               clang::DeclContext *base = nullptr) {
+    if (base) {
+      // decl's DeclContext chains must pass through base.
+
+      if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext,
+                              &clang::DeclContext::getParent) ||
+          !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext,
+                              &clang::DeclContext::getLexicalParent)) {
+        return decl;
+      }
+    } else {
+      base = clang::dyn_cast<clang::DeclContext>(decl);
+
+      if (!base) {
         return nullptr;
+      }
     }
-    
-    void Override(clang::Decl *decl)
-    {
-        if (clang::Decl *escaped_child = GetEscapedChild(decl))
-        {
-            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-            
-            if (log)
-                log->Printf("    [ClangASTImporter] DeclContextOverride couldn't override (%sDecl*)%p - its child (%sDecl*)%p escapes",
-                            decl->getDeclKindName(), static_cast<void*>(decl),
-                            escaped_child->getDeclKindName(), static_cast<void*>(escaped_child));
-            lldbassert(0 && "Couldn't override!");
+
+    if (clang::DeclContext *context =
+            clang::dyn_cast<clang::DeclContext>(decl)) {
+      for (clang::Decl *decl : context->decls()) {
+        if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
+          return escaped_child;
         }
-        
-        OverrideOne(decl);
+      }
     }
-    
-public:
-    DeclContextOverride()
-    {
+
+    return nullptr;
+  }
+
+  void Override(clang::Decl *decl) {
+    if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
+      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+      if (log)
+        log->Printf("    [ClangASTImporter] DeclContextOverride couldn't "
+                    "override (%sDecl*)%p - its child (%sDecl*)%p escapes",
+                    decl->getDeclKindName(), static_cast<void *>(decl),
+                    escaped_child->getDeclKindName(),
+                    static_cast<void *>(escaped_child));
+      lldbassert(0 && "Couldn't override!");
     }
-    
-    void OverrideAllDeclsFromContainingFunction(clang::Decl *decl)
-    {
-        for (DeclContext *decl_context = decl->getLexicalDeclContext();
-             decl_context;
-             decl_context = decl_context->getLexicalParent())
-        {
-            DeclContext *redecl_context = decl_context->getRedeclContext();
-            
-            if (llvm::isa<FunctionDecl>(redecl_context) &&
-                llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent()))
-            {
-                for (clang::Decl *child_decl : decl_context->decls())
-                {
-                    Override(child_decl);
-                }
-            }
+
+    OverrideOne(decl);
+  }
+
+public:
+  DeclContextOverride() {}
+
+  void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
+    for (DeclContext *decl_context = decl->getLexicalDeclContext();
+         decl_context; decl_context = decl_context->getLexicalParent()) {
+      DeclContext *redecl_context = decl_context->getRedeclContext();
+
+      if (llvm::isa<FunctionDecl>(redecl_context) &&
+          llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) {
+        for (clang::Decl *child_decl : decl_context->decls()) {
+          Override(child_decl);
         }
+      }
     }
-    
-    ~DeclContextOverride()
-    {
-        for (const std::pair<clang::Decl *, Backup> &backup : m_backups)
-        {
-            backup.first->setDeclContext(backup.second.decl_context);
-            backup.first->setLexicalDeclContext(backup.second.lexical_decl_context);
-        }
+  }
+
+  ~DeclContextOverride() {
+    for (const std::pair<clang::Decl *, Backup> &backup : m_backups) {
+      backup.first->setDeclContext(backup.second.decl_context);
+      backup.first->setLexicalDeclContext(backup.second.lexical_decl_context);
     }
+  }
 };
 
 lldb::opaque_compiler_type_t
-ClangASTImporter::DeportType (clang::ASTContext *dst_ctx,
-                              clang::ASTContext *src_ctx,
-                              lldb::opaque_compiler_type_t type)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-  
-    if (log)
-        log->Printf("    [ClangASTImporter] DeportType called on (%sType*)0x%llx from (ASTContext*)%p to (ASTContext*)%p",
-                    QualType::getFromOpaquePtr(type)->getTypeClassName(), (unsigned long long)type,
-                    static_cast<void*>(src_ctx),
-                    static_cast<void*>(dst_ctx));
-
-    MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
-    
-    if (!minion_sp)
-        return nullptr;
-    
-    std::set<NamedDecl *> decls_to_deport;
-    std::set<NamedDecl *> decls_already_deported;
-    
-    DeclContextOverride decl_context_override;
-    
-    if (const clang::TagType *tag_type = clang::QualType::getFromOpaquePtr(type)->getAs<TagType>())
-    {
-        decl_context_override.OverrideAllDeclsFromContainingFunction(tag_type->getDecl());
-    }
-    
-    minion_sp->InitDeportWorkQueues(&decls_to_deport,
-                                    &decls_already_deported);
-    
-    lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type);
-    
-    minion_sp->ExecuteDeportWorkQueues();
-    
-    if (!result)
-        return nullptr;
-    
-    return result;
+ClangASTImporter::DeportType(clang::ASTContext *dst_ctx,
+                             clang::ASTContext *src_ctx,
+                             lldb::opaque_compiler_type_t type) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+  if (log)
+    log->Printf("    [ClangASTImporter] DeportType called on (%sType*)0x%llx "
+                "from (ASTContext*)%p to (ASTContext*)%p",
+                QualType::getFromOpaquePtr(type)->getTypeClassName(),
+                (unsigned long long)type, static_cast<void *>(src_ctx),
+                static_cast<void *>(dst_ctx));
 
-}
-
-clang::Decl *
-ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx,
-                              clang::ASTContext *src_ctx,
-                              clang::Decl *decl)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  MinionSP minion_sp(GetMinion(dst_ctx, src_ctx));
 
-    if (log)
-        log->Printf("    [ClangASTImporter] DeportDecl called on (%sDecl*)%p from (ASTContext*)%p to (ASTContext*)%p",
-                    decl->getDeclKindName(), static_cast<void*>(decl),
-                    static_cast<void*>(src_ctx),
-                    static_cast<void*>(dst_ctx));
-
-    MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
+  if (!minion_sp)
+    return nullptr;
 
-    if (!minion_sp)
-        return nullptr;
+  std::set<NamedDecl *> decls_to_deport;
+  std::set<NamedDecl *> decls_already_deported;
 
-    std::set<NamedDecl *> decls_to_deport;
-    std::set<NamedDecl *> decls_already_deported;
-    
-    DeclContextOverride decl_context_override;
-    
-    decl_context_override.OverrideAllDeclsFromContainingFunction(decl);
+  DeclContextOverride decl_context_override;
 
-    minion_sp->InitDeportWorkQueues(&decls_to_deport,
-                                    &decls_already_deported);
+  if (const clang::TagType *tag_type =
+          clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) {
+    decl_context_override.OverrideAllDeclsFromContainingFunction(
+        tag_type->getDecl());
+  }
 
-    clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
+  minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported);
 
-    minion_sp->ExecuteDeportWorkQueues();
+  lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type);
 
-    if (!result)
-        return nullptr;
+  minion_sp->ExecuteDeportWorkQueues();
 
-    if (log)
-        log->Printf("    [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
-                    decl->getDeclKindName(), static_cast<void*>(decl),
-                    result->getDeclKindName(), static_cast<void*>(result));
+  if (!result)
+    return nullptr;
 
-    return result;
+  return result;
 }
 
-bool
-ClangASTImporter::CanImport(const CompilerType &type)
-{
-    if (!ClangUtil::IsClangType(type))
-        return false;
-
-    // TODO: remove external completion BOOL
-    // CompleteAndFetchChildren should get the Decl out and check for the
+clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx,
+                                          clang::ASTContext *src_ctx,
+                                          clang::Decl *decl) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+  if (log)
+    log->Printf("    [ClangASTImporter] DeportDecl called on (%sDecl*)%p from "
+                "(ASTContext*)%p to (ASTContext*)%p",
+                decl->getDeclKindName(), static_cast<void *>(decl),
+                static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx));
 
-    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)
-            {
-                if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
-                    return true;
-            }
-        }
-        break;
-
-        case clang::Type::Enum:
-        {
-            clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
-            if (enum_decl)
-            {
-                if (ResolveDeclOrigin(enum_decl, NULL, NULL))
-                    return true;
-            }
-        }
-        break;
+  MinionSP minion_sp(GetMinion(dst_ctx, src_ctx));
 
-        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 (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
-                        return true;
-                }
-            }
-        }
-        break;
+  if (!minion_sp)
+    return nullptr;
 
-        case clang::Type::Typedef:
-            return CanImport(CompilerType(
-                type.GetTypeSystem(),
-                llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
-
-        case clang::Type::Auto:
-            return CanImport(CompilerType(type.GetTypeSystem(),
-                                          llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
-
-        case clang::Type::Elaborated:
-            return CanImport(CompilerType(
-                type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
-
-        case clang::Type::Paren:
-            return CanImport(CompilerType(type.GetTypeSystem(),
-                                          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+  std::set<NamedDecl *> decls_to_deport;
+  std::set<NamedDecl *> decls_already_deported;
 
-        default:
-            break;
-    }
+  DeclContextOverride decl_context_override;
 
-    return false;
-}
+  decl_context_override.OverrideAllDeclsFromContainingFunction(decl);
 
-bool
-ClangASTImporter::Import(const CompilerType &type)
-{
-    if (!ClangUtil::IsClangType(type))
-        return false;
-    // TODO: remove external completion BOOL
-    // CompleteAndFetchChildren should get the Decl out and check for the
+  minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported);
 
-    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+  clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
 
-    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)
-            {
-                if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
-                    return CompleteAndFetchChildren(qual_type);
-            }
-        }
-        break;
+  minion_sp->ExecuteDeportWorkQueues();
 
-        case clang::Type::Enum:
-        {
-            clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
-            if (enum_decl)
-            {
-                if (ResolveDeclOrigin(enum_decl, NULL, NULL))
-                    return CompleteAndFetchChildren(qual_type);
-            }
-        }
-        break;
+  if (!result)
+    return nullptr;
 
-        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 (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
-                        return CompleteAndFetchChildren(qual_type);
-                }
-            }
-        }
-        break;
+  if (log)
+    log->Printf(
+        "    [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
+        decl->getDeclKindName(), static_cast<void *>(decl),
+        result->getDeclKindName(), static_cast<void *>(result));
 
-        case clang::Type::Typedef:
-            return Import(CompilerType(
-                type.GetTypeSystem(),
-                llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
-
-        case clang::Type::Auto:
-            return Import(CompilerType(type.GetTypeSystem(),
-                                       llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
-
-        case clang::Type::Elaborated:
-            return Import(CompilerType(type.GetTypeSystem(),
-                                       llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
-
-        case clang::Type::Paren:
-            return Import(CompilerType(type.GetTypeSystem(),
-                                       llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+  return result;
+}
 
-        default:
-            break;
-    }
+bool ClangASTImporter::CanImport(const CompilerType &type) {
+  if (!ClangUtil::IsClangType(type))
     return false;
-}
 
-bool
-ClangASTImporter::CompleteType(const CompilerType &compiler_type)
-{
-    if (!CanImport(compiler_type))
-        return false;
+  // TODO: remove external completion BOOL
+  // CompleteAndFetchChildren should get the Decl out and check for the
+
+  clang::QualType qual_type(
+      ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
 
-    if (Import(compiler_type))
-    {
-        ClangASTContext::CompleteTagDeclarationDefinition(compiler_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) {
+      if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
         return true;
     }
+  } break;
 
-    ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false);
-    return false;
-}
-
-bool
-ClangASTImporter::LayoutRecordType(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)
-{
-    RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl);
-    bool success = false;
-    base_offsets.clear();
-    vbase_offsets.clear();
-    if (pos != m_record_decl_to_layout_map.end())
-    {
-        bit_size = pos->second.bit_size;
-        alignment = pos->second.alignment;
-        field_offsets.swap(pos->second.field_offsets);
-        base_offsets.swap(pos->second.base_offsets);
-        vbase_offsets.swap(pos->second.vbase_offsets);
-        m_record_decl_to_layout_map.erase(pos);
-        success = true;
-    }
-    else
-    {
-        bit_size = 0;
-        alignment = 0;
-        field_offsets.clear();
+  case clang::Type::Enum: {
+    clang::EnumDecl *enum_decl =
+        llvm::cast<clang::EnumType>(qual_type)->getDecl();
+    if (enum_decl) {
+      if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+        return true;
     }
-    return success;
-}
+  } break;
 
-void
-ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout)
-{
-    m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+  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 (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+          return true;
+      }
+    }
+  } break;
+
+  case clang::Type::Typedef:
+    return CanImport(CompilerType(type.GetTypeSystem(),
+                                  llvm::cast<clang::TypedefType>(qual_type)
+                                      ->getDecl()
+                                      ->getUnderlyingType()
+                                      .getAsOpaquePtr()));
+
+  case clang::Type::Auto:
+    return CanImport(CompilerType(type.GetTypeSystem(),
+                                  llvm::cast<clang::AutoType>(qual_type)
+                                      ->getDeducedType()
+                                      .getAsOpaquePtr()));
+
+  case clang::Type::Elaborated:
+    return CanImport(CompilerType(type.GetTypeSystem(),
+                                  llvm::cast<clang::ElaboratedType>(qual_type)
+                                      ->getNamedType()
+                                      .getAsOpaquePtr()));
+
+  case clang::Type::Paren:
+    return CanImport(CompilerType(
+        type.GetTypeSystem(),
+        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+  default:
+    break;
+  }
+
+  return false;
 }
 
-void
-ClangASTImporter::CompleteDecl (clang::Decl *decl)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ClangASTImporter::Import(const CompilerType &type) {
+  if (!ClangUtil::IsClangType(type))
+    return false;
+  // TODO: remove external completion BOOL
+  // CompleteAndFetchChildren should get the Decl out and check for the
 
-    if (log)
-        log->Printf("    [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
-                    decl->getDeclKindName(), static_cast<void*>(decl));
+  clang::QualType qual_type(
+      ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
 
-    if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) 
-    {
-        if (!interface_decl->getDefinition())
-        {
-            interface_decl->startDefinition();
-            CompleteObjCInterfaceDecl(interface_decl);
-        }
-    }
-    else if (ObjCProtocolDecl *protocol_decl = dyn_cast<ObjCProtocolDecl>(decl)) 
-    {
-        if (!protocol_decl->getDefinition())
-            protocol_decl->startDefinition();
-    }
-    else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) 
-    {
-        if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) 
-        {
-            tag_decl->startDefinition();
-            CompleteTagDecl(tag_decl);
-            tag_decl->setCompleteDefinition(true);
-        }
-    }
-    else
-    {
-        assert (0 && "CompleteDecl called on a Decl that can't be completed");
-    }
+  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) {
+      if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+        return CompleteAndFetchChildren(qual_type);
+    }
+  } break;
+
+  case clang::Type::Enum: {
+    clang::EnumDecl *enum_decl =
+        llvm::cast<clang::EnumType>(qual_type)->getDecl();
+    if (enum_decl) {
+      if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+        return CompleteAndFetchChildren(qual_type);
+    }
+  } 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 (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+          return CompleteAndFetchChildren(qual_type);
+      }
+    }
+  } break;
+
+  case clang::Type::Typedef:
+    return Import(CompilerType(type.GetTypeSystem(),
+                               llvm::cast<clang::TypedefType>(qual_type)
+                                   ->getDecl()
+                                   ->getUnderlyingType()
+                                   .getAsOpaquePtr()));
+
+  case clang::Type::Auto:
+    return Import(CompilerType(type.GetTypeSystem(),
+                               llvm::cast<clang::AutoType>(qual_type)
+                                   ->getDeducedType()
+                                   .getAsOpaquePtr()));
+
+  case clang::Type::Elaborated:
+    return Import(CompilerType(type.GetTypeSystem(),
+                               llvm::cast<clang::ElaboratedType>(qual_type)
+                                   ->getNamedType()
+                                   .getAsOpaquePtr()));
+
+  case clang::Type::Paren:
+    return Import(CompilerType(
+        type.GetTypeSystem(),
+        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+  default:
+    break;
+  }
+  return false;
 }
 
-bool
-ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl)
-{
-    ClangASTMetrics::RegisterDeclCompletion();
-    
-    DeclOrigin decl_origin = GetDeclOrigin(decl);
-    
-    if (!decl_origin.Valid())
-        return false;
-    
-    if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
-        return false;
-    
-    MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx));
-    
-    if (minion_sp)
-        minion_sp->ImportDefinitionTo(decl, decl_origin.decl);
-        
+bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) {
+  if (!CanImport(compiler_type))
+    return false;
+
+  if (Import(compiler_type)) {
+    ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
     return true;
+  }
+
+  ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
+                                         false);
+  return false;
+}
+
+bool ClangASTImporter::LayoutRecordType(
+    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) {
+  RecordDeclToLayoutMap::iterator pos =
+      m_record_decl_to_layout_map.find(record_decl);
+  bool success = false;
+  base_offsets.clear();
+  vbase_offsets.clear();
+  if (pos != m_record_decl_to_layout_map.end()) {
+    bit_size = pos->second.bit_size;
+    alignment = pos->second.alignment;
+    field_offsets.swap(pos->second.field_offsets);
+    base_offsets.swap(pos->second.base_offsets);
+    vbase_offsets.swap(pos->second.vbase_offsets);
+    m_record_decl_to_layout_map.erase(pos);
+    success = true;
+  } else {
+    bit_size = 0;
+    alignment = 0;
+    field_offsets.clear();
+  }
+  return success;
+}
+
+void ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl,
+                                        const LayoutInfo &layout) {
+  m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
+void ClangASTImporter::CompleteDecl(clang::Decl *decl) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+  if (log)
+    log->Printf("    [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
+                decl->getDeclKindName(), static_cast<void *>(decl));
+
+  if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) {
+    if (!interface_decl->getDefinition()) {
+      interface_decl->startDefinition();
+      CompleteObjCInterfaceDecl(interface_decl);
+    }
+  } else if (ObjCProtocolDecl *protocol_decl =
+                 dyn_cast<ObjCProtocolDecl>(decl)) {
+    if (!protocol_decl->getDefinition())
+      protocol_decl->startDefinition();
+  } else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) {
+    if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) {
+      tag_decl->startDefinition();
+      CompleteTagDecl(tag_decl);
+      tag_decl->setCompleteDefinition(true);
+    }
+  } else {
+    assert(0 && "CompleteDecl called on a Decl that can't be completed");
+  }
 }
 
-bool
-ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl)
-{
-    ClangASTMetrics::RegisterDeclCompletion();
-
-    clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
-        
-    if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl))
-        return false;
-    
-    MinionSP minion_sp (GetMinion(&decl->getASTContext(), origin_ast_ctx));
-    
-    if (minion_sp)
-        minion_sp->ImportDefinitionTo(decl, origin_decl);
-        
-    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) {
+  ClangASTMetrics::RegisterDeclCompletion();
 
-    OriginMap &origins = context_md->m_origins;
+  DeclOrigin decl_origin = GetDeclOrigin(decl);
 
-    origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
-    
-    return true;
+  if (!decl_origin.Valid())
+    return false;
+
+  if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
+    return false;
+
+  MinionSP minion_sp(GetMinion(&decl->getASTContext(), decl_origin.ctx));
+
+  if (minion_sp)
+    minion_sp->ImportDefinitionTo(decl, decl_origin.decl);
+
+  return true;
 }
 
-bool
-ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl)
-{
-    ClangASTMetrics::RegisterDeclCompletion();
-    
-    DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
-    
-    if (!decl_origin.Valid())
-        return false;
-    
-    if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
-        return false;
-    
-    MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx));
-    
-    if (minion_sp)
-        minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);
+bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
+                                                 clang::TagDecl *origin_decl) {
+  ClangASTMetrics::RegisterDeclCompletion();
 
-    if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
-        RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));
+  clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
 
-    return true;
+  if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl))
+    return false;
+
+  MinionSP minion_sp(GetMinion(&decl->getASTContext(), origin_ast_ctx));
+
+  if (minion_sp)
+    minion_sp->ImportDefinitionTo(decl, origin_decl);
+
+  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+  OriginMap &origins = context_md->m_origins;
+
+  origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
+
+  return true;
 }
 
-bool
-ClangASTImporter::CompleteAndFetchChildren (clang::QualType type)
-{
-    if (!RequireCompleteType(type))
-        return false;
+bool ClangASTImporter::CompleteObjCInterfaceDecl(
+    clang::ObjCInterfaceDecl *interface_decl) {
+  ClangASTMetrics::RegisterDeclCompletion();
 
-    if (const TagType *tag_type = type->getAs<TagType>())
-    {
-        TagDecl *tag_decl = tag_type->getDecl();
+  DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
 
-        DeclOrigin decl_origin = GetDeclOrigin(tag_decl);
+  if (!decl_origin.Valid())
+    return false;
 
-        if (!decl_origin.Valid())
-            return false;
+  if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
+    return false;
 
-        MinionSP minion_sp (GetMinion(&tag_decl->getASTContext(), decl_origin.ctx));
+  MinionSP minion_sp(
+      GetMinion(&interface_decl->getASTContext(), decl_origin.ctx));
 
-        TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
+  if (minion_sp)
+    minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);
 
-        for (Decl *origin_child_decl : origin_tag_decl->decls())
-        {
-            minion_sp->Import(origin_child_decl);
-        }
+  if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
+    RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));
 
-        if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl))
-        {
-            record_decl->setHasLoadedFieldsFromExternalStorage(true);
-        }
+  return true;
+}
 
-        return true;
-    }
+bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) {
+  if (!RequireCompleteType(type))
+    return false;
 
-    if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
-    {
-        if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface())
-        {
-            DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);
+  if (const TagType *tag_type = type->getAs<TagType>()) {
+    TagDecl *tag_decl = tag_type->getDecl();
 
-            if (!decl_origin.Valid())
-                return false;
+    DeclOrigin decl_origin = GetDeclOrigin(tag_decl);
 
-            MinionSP minion_sp (GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx));
+    if (!decl_origin.Valid())
+      return false;
 
-            ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);
+    MinionSP minion_sp(GetMinion(&tag_decl->getASTContext(), decl_origin.ctx));
 
-            for (Decl *origin_child_decl : origin_interface_decl->decls())
-            {
-                minion_sp->Import(origin_child_decl);
-            }
+    TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
 
-            return true;
-        }
-        else
-        {
-            return false;
-        }
+    for (Decl *origin_child_decl : origin_tag_decl->decls()) {
+      minion_sp->Import(origin_child_decl);
     }
-    
+
+    if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) {
+      record_decl->setHasLoadedFieldsFromExternalStorage(true);
+    }
+
     return true;
-}
+  }
 
+  if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
+    if (ObjCInterfaceDecl *objc_interface_decl =
+            objc_object_type->getInterface()) {
+      DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);
 
-bool
-ClangASTImporter::RequireCompleteType (clang::QualType type)
-{
-    if (type.isNull())
+      if (!decl_origin.Valid())
         return false;
-    
-    if (const TagType *tag_type = type->getAs<TagType>())
-    {
-        TagDecl *tag_decl = tag_type->getDecl();
-
-        if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
-            return true;
-
-        return CompleteTagDecl(tag_decl);
-    }
-    if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
-    {
-        if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface())
-            return CompleteObjCInterfaceDecl(objc_interface_decl);
-        else
-            return false;
-    }
-    if (const ArrayType *array_type = type->getAsArrayTypeUnsafe())
-    {
-        return RequireCompleteType(array_type->getElementType());
-    }
-    if (const AtomicType *atomic_type = type->getAs<AtomicType>())
-    {
-        return RequireCompleteType(atomic_type->getPointeeType());
+
+      MinionSP minion_sp(
+          GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx));
+
+      ObjCInterfaceDecl *origin_interface_decl =
+          llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);
+
+      for (Decl *origin_child_decl : origin_interface_decl->decls()) {
+        minion_sp->Import(origin_child_decl);
+      }
+
+      return true;
+    } else {
+      return false;
     }
-    
-    return true;
+  }
+
+  return true;
 }
 
-ClangASTMetadata *
-ClangASTImporter::GetDeclMetadata (const clang::Decl *decl)
-{
-    DeclOrigin decl_origin = GetDeclOrigin(decl);
-    
-    if (decl_origin.Valid())
-        return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
+bool ClangASTImporter::RequireCompleteType(clang::QualType type) {
+  if (type.isNull())
+    return false;
+
+  if (const TagType *tag_type = type->getAs<TagType>()) {
+    TagDecl *tag_decl = tag_type->getDecl();
+
+    if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
+      return true;
+
+    return CompleteTagDecl(tag_decl);
+  }
+  if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
+    if (ObjCInterfaceDecl *objc_interface_decl =
+            objc_object_type->getInterface())
+      return CompleteObjCInterfaceDecl(objc_interface_decl);
     else
-        return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
+      return false;
+  }
+  if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) {
+    return RequireCompleteType(array_type->getElementType());
+  }
+  if (const AtomicType *atomic_type = type->getAs<AtomicType>()) {
+    return RequireCompleteType(atomic_type->getPointeeType());
+  }
+
+  return true;
+}
+
+ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) {
+  DeclOrigin decl_origin = GetDeclOrigin(decl);
+
+  if (decl_origin.Valid())
+    return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
+  else
+    return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
 }
 
 ClangASTImporter::DeclOrigin
-ClangASTImporter::GetDeclOrigin(const clang::Decl *decl)
-{
-    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-    
-    OriginMap &origins = context_md->m_origins;
-    
-    OriginMap::iterator iter = origins.find(decl);
-    
-    if (iter != origins.end())
-        return iter->second;
-    else
-        return DeclOrigin();
+ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) {
+  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+  OriginMap &origins = context_md->m_origins;
+
+  OriginMap::iterator iter = origins.find(decl);
+
+  if (iter != origins.end())
+    return iter->second;
+  else
+    return DeclOrigin();
 }
 
-void
-ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl)
-{
-    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-    
-    OriginMap &origins = context_md->m_origins;
-    
-    OriginMap::iterator iter = origins.find(decl);
-    
-    if (iter != origins.end())
-    {
-        iter->second.decl = original_decl;
-        iter->second.ctx = &original_decl->getASTContext();
-    }
-    else
-    {
-        origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
-    }
+void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl,
+                                     clang::Decl *original_decl) {
+  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+  OriginMap &origins = context_md->m_origins;
+
+  OriginMap::iterator iter = origins.find(decl);
+
+  if (iter != origins.end()) {
+    iter->second.decl = original_decl;
+    iter->second.ctx = &original_decl->getASTContext();
+  } else {
+    origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
+  }
 }
 
-void
-ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, 
-                                       NamespaceMapSP &namespace_map)
-{
-    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-    
-    context_md->m_namespace_maps[decl] = namespace_map;
-}
-
-ClangASTImporter::NamespaceMapSP 
-ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
-{
-    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-
-    NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
-    
-    NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
-    
-    if (iter != namespace_maps.end())
-        return iter->second;
-    else
-        return NamespaceMapSP();
+void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
+                                            NamespaceMapSP &namespace_map) {
+  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+  context_md->m_namespace_maps[decl] = namespace_map;
 }
 
-void 
-ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
-{
-    assert (decl);
-    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-
-    const DeclContext *parent_context = decl->getDeclContext();
-    const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context);
-    NamespaceMapSP parent_map;
-    
-    if (parent_namespace)
-        parent_map = GetNamespaceMap(parent_namespace);
-    
-    NamespaceMapSP new_map;
-    
-    new_map.reset(new NamespaceMap);
- 
-    if (context_md->m_map_completer)
-    {
-        std::string namespace_string = decl->getDeclName().getAsString();
-    
-        context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map);
-    }
-    
-    context_md->m_namespace_maps[decl] = new_map;
-}
-
-void 
-ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ClangASTImporter::NamespaceMapSP
+ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) {
+  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
 
-    if (log)
-        log->Printf("    [ClangASTImporter] Forgetting destination (ASTContext*)%p",
-                    static_cast<void*>(dst_ast));
+  NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
 
-    m_metadata_map.erase(dst_ast);
+  NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
+
+  if (iter != namespace_maps.end())
+    return iter->second;
+  else
+    return NamespaceMapSP();
 }
 
-void
-ClangASTImporter::ForgetSource (clang::ASTContext *dst_ast, clang::ASTContext *src_ast)
-{
-    ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast);
+void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) {
+  assert(decl);
+  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
 
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  const DeclContext *parent_context = decl->getDeclContext();
+  const NamespaceDecl *parent_namespace =
+      dyn_cast<NamespaceDecl>(parent_context);
+  NamespaceMapSP parent_map;
 
-    if (log)
-        log->Printf("    [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p",
-                    static_cast<void*>(src_ast), static_cast<void*>(dst_ast));
+  if (parent_namespace)
+    parent_map = GetNamespaceMap(parent_namespace);
 
-    if (!md)
-        return;
+  NamespaceMapSP new_map;
 
-    md->m_minions.erase(src_ast);
+  new_map.reset(new NamespaceMap);
 
-    for (OriginMap::iterator iter = md->m_origins.begin();
-         iter != md->m_origins.end();
-         )
-    {
-        if (iter->second.ctx == src_ast)
-            md->m_origins.erase(iter++);
-        else
-            ++iter;
-    }
+  if (context_md->m_map_completer) {
+    std::string namespace_string = decl->getDeclName().getAsString();
+
+    context_md->m_map_completer->CompleteNamespaceMap(
+        new_map, ConstString(namespace_string.c_str()), parent_map);
+  }
+
+  context_md->m_namespace_maps[decl] = new_map;
+}
+
+void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+  if (log)
+    log->Printf("    [ClangASTImporter] Forgetting destination (ASTContext*)%p",
+                static_cast<void *>(dst_ast));
+
+  m_metadata_map.erase(dst_ast);
 }
 
-ClangASTImporter::MapCompleter::~MapCompleter ()
-{
+void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
+                                    clang::ASTContext *src_ast) {
+  ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast);
+
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+  if (log)
+    log->Printf("    [ClangASTImporter] Forgetting source->dest "
+                "(ASTContext*)%p->(ASTContext*)%p",
+                static_cast<void *>(src_ast), static_cast<void *>(dst_ast));
+
+  if (!md)
     return;
+
+  md->m_minions.erase(src_ast);
+
+  for (OriginMap::iterator iter = md->m_origins.begin();
+       iter != md->m_origins.end();) {
+    if (iter->second.ctx == src_ast)
+      md->m_origins.erase(iter++);
+    else
+      ++iter;
+  }
 }
 
-void
-ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
-                                                std::set<clang::NamedDecl *> *decls_already_deported)
-{
-    assert(!m_decls_to_deport);
-    assert(!m_decls_already_deported);
-    
-    m_decls_to_deport = decls_to_deport;
-    m_decls_already_deported = decls_already_deported;
-}
-
-void
-ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
-{
-    assert(m_decls_to_deport);
-    assert(m_decls_already_deported);
-    
-    ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext());
-        
-    while (!m_decls_to_deport->empty())
-    {
-        NamedDecl *decl = *m_decls_to_deport->begin();
-        
-        m_decls_already_deported->insert(decl);
-        m_decls_to_deport->erase(decl);
-        
-        DeclOrigin &origin = to_context_md->m_origins[decl];
-        UNUSED_IF_ASSERT_DISABLED(origin);
-        
-        assert (origin.ctx == m_source_ctx);    // otherwise we should never have added this
-                                                // because it doesn't need to be deported
-        
-        Decl *original_decl = to_context_md->m_origins[decl].decl;
-        
-        ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl);
-        
-        if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
-        {
-            if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
-            {
-                if (original_tag_decl->isCompleteDefinition())
-                {
-                    ImportDefinitionTo(tag_decl, original_tag_decl);
-                    tag_decl->setCompleteDefinition(true);
-                }
-            }
-            
-            tag_decl->setHasExternalLexicalStorage(false);
-            tag_decl->setHasExternalVisibleStorage(false);
-        }
-        else if (ObjCContainerDecl *container_decl = dyn_cast<ObjCContainerDecl>(decl))
-        {
-            container_decl->setHasExternalLexicalStorage(false);
-            container_decl->setHasExternalVisibleStorage(false);
-        }
-        
-        to_context_md->m_origins.erase(decl);
-    }
-    
-    m_decls_to_deport = nullptr;
-    m_decls_already_deported = nullptr;
+ClangASTImporter::MapCompleter::~MapCompleter() { return; }
+
+void ClangASTImporter::Minion::InitDeportWorkQueues(
+    std::set<clang::NamedDecl *> *decls_to_deport,
+    std::set<clang::NamedDecl *> *decls_already_deported) {
+  assert(!m_decls_to_deport);
+  assert(!m_decls_already_deported);
+
+  m_decls_to_deport = decls_to_deport;
+  m_decls_already_deported = decls_already_deported;
 }
 
-void
-ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
-{
-    ASTImporter::Imported(from, to);
+void ClangASTImporter::Minion::ExecuteDeportWorkQueues() {
+  assert(m_decls_to_deport);
+  assert(m_decls_already_deported);
 
-    /*
-    if (to_objc_interface)
-        to_objc_interface->startDefinition();
- 
-    CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
-    
-    if (to_cxx_record)
-        to_cxx_record->startDefinition();
-    */
-
-    ImportDefinition(from);
-    
-    if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to))
-    {
-        if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from))
-        {
-            to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
-        }
-    }
-     
-    // If we're dealing with an Objective-C class, ensure that the inheritance has
-    // been set up correctly.  The ASTImporter may not do this correctly if the 
-    // class was originally sourced from symbols.
-    
-    if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to))
-    {
-        do
-        {
-            ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
-
-            if (to_superclass)
-                break; // we're not going to override it if it's set
-            
-            ObjCInterfaceDecl *from_objc_interface = dyn_cast<ObjCInterfaceDecl>(from);
-            
-            if (!from_objc_interface)
-                break;
-            
-            ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
-            
-            if (!from_superclass)
-                break;
-            
-            Decl *imported_from_superclass_decl = Import(from_superclass);
-                
-            if (!imported_from_superclass_decl)
-                break;
-                
-            ObjCInterfaceDecl *imported_from_superclass = dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl);
-            
-            if (!imported_from_superclass)
-                break;
-            
-            if (!to_objc_interface->hasDefinition())
-                to_objc_interface->startDefinition();
-            
-            to_objc_interface->setSuperClass(
-                    m_source_ctx->getTrivialTypeSourceInfo(m_source_ctx->getObjCInterfaceType(imported_from_superclass)));
+  ASTContextMetadataSP to_context_md =
+      m_master.GetContextMetadata(&getToContext());
+
+  while (!m_decls_to_deport->empty()) {
+    NamedDecl *decl = *m_decls_to_deport->begin();
+
+    m_decls_already_deported->insert(decl);
+    m_decls_to_deport->erase(decl);
+
+    DeclOrigin &origin = to_context_md->m_origins[decl];
+    UNUSED_IF_ASSERT_DISABLED(origin);
+
+    assert(origin.ctx ==
+           m_source_ctx); // otherwise we should never have added this
+                          // because it doesn't need to be deported
+
+    Decl *original_decl = to_context_md->m_origins[decl].decl;
+
+    ClangASTContext::GetCompleteDecl(m_source_ctx, original_decl);
+
+    if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) {
+      if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
+        if (original_tag_decl->isCompleteDefinition()) {
+          ImportDefinitionTo(tag_decl, original_tag_decl);
+          tag_decl->setCompleteDefinition(true);
         }
-        while (0);
+      }
+
+      tag_decl->setHasExternalLexicalStorage(false);
+      tag_decl->setHasExternalVisibleStorage(false);
+    } else if (ObjCContainerDecl *container_decl =
+                   dyn_cast<ObjCContainerDecl>(decl)) {
+      container_decl->setHasExternalLexicalStorage(false);
+      container_decl->setHasExternalVisibleStorage(false);
     }
+
+    to_context_md->m_origins.erase(decl);
+  }
+
+  m_decls_to_deport = nullptr;
+  m_decls_already_deported = nullptr;
 }
 
-clang::Decl *
-ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
-{
-    ClangASTMetrics::RegisterClangImport();
+void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to,
+                                                  clang::Decl *from) {
+  ASTImporter::Imported(from, to);
 
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  /*
+  if (to_objc_interface)
+      to_objc_interface->startDefinition();
 
-    lldb::user_id_t user_id = LLDB_INVALID_UID;
-    ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
-    if (metadata)
-        user_id = metadata->GetUserID();
-    
-    if (log)
-    {
-        if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from))
-        {
-            std::string name_string;
-            llvm::raw_string_ostream name_stream(name_string);
-            from_named_decl->printName(name_stream);
-            name_stream.flush();
-
-            log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64,
-                        from->getDeclKindName(), static_cast<void*>(to),
-                        name_string.c_str(), static_cast<void*>(from),
-                        user_id);
-        }
-        else
-        {
-            log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64,
-                        from->getDeclKindName(), static_cast<void*>(to),
-                        static_cast<void*>(from), user_id);
-        }
+  CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
+
+  if (to_cxx_record)
+      to_cxx_record->startDefinition();
+  */
+
+  ImportDefinition(from);
+
+  if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) {
+    if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) {
+      to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
     }
+  }
 
-    ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext());
-    ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx);
+  // If we're dealing with an Objective-C class, ensure that the inheritance has
+  // been set up correctly.  The ASTImporter may not do this correctly if the
+  // class was originally sourced from symbols.
 
-    if (from_context_md)
-    {
-        OriginMap &origins = from_context_md->m_origins;
-
-        OriginMap::iterator origin_iter = origins.find(from);
-
-        if (origin_iter != origins.end())
-        {
-            if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
-                user_id != LLDB_INVALID_UID)
-            {
-                if (origin_iter->second.ctx != &to->getASTContext())
-                    to_context_md->m_origins[to] = origin_iter->second;
-            }
-                
-            MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx);
-
-            if (direct_completer.get() != this)
-                direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
-
-            if (log)
-                log->Printf("    [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p",
-                            static_cast<void*>(origin_iter->second.decl),
-                            static_cast<void*>(origin_iter->second.ctx),
-                            static_cast<void*>(&from->getASTContext()),
-                            static_cast<void*>(&to->getASTContext()));
-        }
-        else
-        {
-            if (m_decls_to_deport && m_decls_already_deported)
-            {
-                if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
-                {
-                    RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
-                    if (from_record_decl == nullptr || from_record_decl->isInjectedClassName() == false)
-                    {
-                        NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
-
-                        if (!m_decls_already_deported->count(to_named_decl))
-                            m_decls_to_deport->insert(to_named_decl);
-                    }
-                }
-            }
-            
-            if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
-                user_id != LLDB_INVALID_UID)
-            {
-                to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
-            }
-
-            if (log)
-                log->Printf("    [ClangASTImporter] Decl has no origin information in (ASTContext*)%p",
-                            static_cast<void*>(&from->getASTContext()));
-        }
+  if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) {
+    do {
+      ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
 
-        if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to))
-        {
-            clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from);
+      if (to_superclass)
+        break; // we're not going to override it if it's set
 
-            NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
+      ObjCInterfaceDecl *from_objc_interface =
+          dyn_cast<ObjCInterfaceDecl>(from);
 
-            NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace);
+      if (!from_objc_interface)
+        break;
 
-            if (namespace_map_iter != namespace_maps.end())
-                to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second;
-        }
-    }
-    else
-    {
-        to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from);
+      ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
 
-        if (log)
-            log->Printf("    [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
-                        static_cast<void*>(from),
-                        static_cast<void*>(m_source_ctx),
-                        static_cast<void*>(&to->getASTContext()));
-    }
-
-    if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from))
-    {
-        TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);
-
-        to_tag_decl->setHasExternalLexicalStorage();
-        to_tag_decl->setMustBuildLookupTable();
-
-        if (log)
-            log->Printf("    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
-                        (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
-                        (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
-                        (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
-                        (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
-    }
-
-    if (isa<NamespaceDecl>(from))
-    {
-        NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);
-
-        m_master.BuildNamespaceMap(to_namespace_decl);
-
-        to_namespace_decl->setHasExternalVisibleStorage();
-    }
-
-    if (isa<ObjCContainerDecl>(from))
-    {
-        ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);
-
-        to_container_decl->setHasExternalLexicalStorage();
-        to_container_decl->setHasExternalVisibleStorage();
-
-        /*to_interface_decl->setExternallyCompleted();*/
-
-        if (log)
-        {
-            if (ObjCInterfaceDecl *to_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl))
-            {
-                log->Printf("    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
-                            (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
-                            (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
-                            (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
-            }
-            else
-            {
-                log->Printf("    [ClangASTImporter] To is an %sDecl - attributes %s%s",
-                            ((Decl*)to_container_decl)->getDeclKindName(),
-                            (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
-                            (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
-            }
-        }
+      if (!from_superclass)
+        break;
+
+      Decl *imported_from_superclass_decl = Import(from_superclass);
+
+      if (!imported_from_superclass_decl)
+        break;
+
+      ObjCInterfaceDecl *imported_from_superclass =
+          dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl);
+
+      if (!imported_from_superclass)
+        break;
+
+      if (!to_objc_interface->hasDefinition())
+        to_objc_interface->startDefinition();
+
+      to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo(
+          m_source_ctx->getObjCInterfaceType(imported_from_superclass)));
+    } while (0);
+  }
+}
+
+clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from,
+                                                clang::Decl *to) {
+  ClangASTMetrics::RegisterClangImport();
+
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+  lldb::user_id_t user_id = LLDB_INVALID_UID;
+  ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
+  if (metadata)
+    user_id = metadata->GetUserID();
+
+  if (log) {
+    if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
+      std::string name_string;
+      llvm::raw_string_ostream name_stream(name_string);
+      from_named_decl->printName(name_stream);
+      name_stream.flush();
+
+      log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from "
+                  "(Decl*)%p), metadata 0x%" PRIx64,
+                  from->getDeclKindName(), static_cast<void *>(to),
+                  name_string.c_str(), static_cast<void *>(from), user_id);
+    } else {
+      log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p (from "
+                  "(Decl*)%p), metadata 0x%" PRIx64,
+                  from->getDeclKindName(), static_cast<void *>(to),
+                  static_cast<void *>(from), user_id);
+    }
+  }
+
+  ASTContextMetadataSP to_context_md =
+      m_master.GetContextMetadata(&to->getASTContext());
+  ASTContextMetadataSP from_context_md =
+      m_master.MaybeGetContextMetadata(m_source_ctx);
+
+  if (from_context_md) {
+    OriginMap &origins = from_context_md->m_origins;
+
+    OriginMap::iterator origin_iter = origins.find(from);
+
+    if (origin_iter != origins.end()) {
+      if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
+          user_id != LLDB_INVALID_UID) {
+        if (origin_iter->second.ctx != &to->getASTContext())
+          to_context_md->m_origins[to] = origin_iter->second;
+      }
+
+      MinionSP direct_completer =
+          m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx);
+
+      if (direct_completer.get() != this)
+        direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
+
+      if (log)
+        log->Printf("    [ClangASTImporter] Propagated origin "
+                    "(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to "
+                    "(ASTContext*)%p",
+                    static_cast<void *>(origin_iter->second.decl),
+                    static_cast<void *>(origin_iter->second.ctx),
+                    static_cast<void *>(&from->getASTContext()),
+                    static_cast<void *>(&to->getASTContext()));
+    } else {
+      if (m_decls_to_deport && m_decls_already_deported) {
+        if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) {
+          RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
+          if (from_record_decl == nullptr ||
+              from_record_decl->isInjectedClassName() == false) {
+            NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
+
+            if (!m_decls_already_deported->count(to_named_decl))
+              m_decls_to_deport->insert(to_named_decl);
+          }
+        }
+      }
+
+      if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
+          user_id != LLDB_INVALID_UID) {
+        to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
+      }
+
+      if (log)
+        log->Printf("    [ClangASTImporter] Decl has no origin information in "
+                    "(ASTContext*)%p",
+                    static_cast<void *>(&from->getASTContext()));
+    }
+
+    if (clang::NamespaceDecl *to_namespace =
+            dyn_cast<clang::NamespaceDecl>(to)) {
+      clang::NamespaceDecl *from_namespace =
+          dyn_cast<clang::NamespaceDecl>(from);
+
+      NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
+
+      NamespaceMetaMap::iterator namespace_map_iter =
+          namespace_maps.find(from_namespace);
+
+      if (namespace_map_iter != namespace_maps.end())
+        to_context_md->m_namespace_maps[to_namespace] =
+            namespace_map_iter->second;
     }
+  } else {
+    to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
 
-    return clang::ASTImporter::Imported(from, to);
-}
+    if (log)
+      log->Printf("    [ClangASTImporter] Sourced origin "
+                  "(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
+                  static_cast<void *>(from), static_cast<void *>(m_source_ctx),
+                  static_cast<void *>(&to->getASTContext()));
+  }
 
-clang::Decl *ClangASTImporter::Minion::GetOriginalDecl (clang::Decl *To)
-{
-    ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext());
-    
-    if (!to_context_md)
-        return nullptr;
-    
-    OriginMap::iterator iter = to_context_md->m_origins.find(To);
-    
-    if (iter == to_context_md->m_origins.end())
-        return nullptr;
-    
-    return const_cast<clang::Decl*>(iter->second.decl);
+  if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) {
+    TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);
+
+    to_tag_decl->setHasExternalLexicalStorage();
+    to_tag_decl->setMustBuildLookupTable();
+
+    if (log)
+      log->Printf(
+          "    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
+          (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+          (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+          (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
+          (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
+  }
+
+  if (isa<NamespaceDecl>(from)) {
+    NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);
+
+    m_master.BuildNamespaceMap(to_namespace_decl);
+
+    to_namespace_decl->setHasExternalVisibleStorage();
+  }
+
+  if (isa<ObjCContainerDecl>(from)) {
+    ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);
+
+    to_container_decl->setHasExternalLexicalStorage();
+    to_container_decl->setHasExternalVisibleStorage();
+
+    /*to_interface_decl->setExternallyCompleted();*/
+
+    if (log) {
+      if (ObjCInterfaceDecl *to_interface_decl =
+              llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
+        log->Printf(
+            "    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
+            "%s%s%s",
+            (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+            (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+            (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+      } else {
+        log->Printf(
+            "    [ClangASTImporter] To is an %sDecl - attributes %s%s",
+            ((Decl *)to_container_decl)->getDeclKindName(),
+            (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+            (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
+      }
+    }
+  }
+
+  return clang::ASTImporter::Imported(from, to);
+}
+
+clang::Decl *ClangASTImporter::Minion::GetOriginalDecl(clang::Decl *To) {
+  ASTContextMetadataSP to_context_md =
+      m_master.GetContextMetadata(&To->getASTContext());
+
+  if (!to_context_md)
+    return nullptr;
+
+  OriginMap::iterator iter = to_context_md->m_origins.find(To);
+
+  if (iter == to_context_md->m_origins.end())
+    return nullptr;
+
+  return const_cast<clang::Decl *>(iter->second.decl);
 }

Modified: lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp (original)
+++ lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp Tue Sep  6 15:57:50 2016
@@ -13,7 +13,7 @@
 // C++ Includes
 // Other libraries and framework includes
 
-// Clang headers like to use NDEBUG inside of them to enable/disable debug 
+// 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
@@ -46,131 +46,145 @@
 using namespace clang;
 using namespace lldb_private;
 
-bool
-ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName 
-(
+bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(
     const clang::DeclContext *decl_ctx,
-    clang::DeclarationName clang_decl_name
-)
-{
-    if (m_callback_find_by_name)
-    {
-        llvm::SmallVector <clang::NamedDecl *, 3> results;
-        
-        m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results);
-        
-        SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
-        
-        return (results.size() != 0);
+    clang::DeclarationName clang_decl_name) {
+  if (m_callback_find_by_name) {
+    llvm::SmallVector<clang::NamedDecl *, 3> results;
+
+    m_callback_find_by_name(m_callback_baton, decl_ctx, clang_decl_name,
+                            &results);
+
+    SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
+
+    return (results.size() != 0);
+  }
+
+  std::string decl_name(clang_decl_name.getAsString());
+
+  switch (clang_decl_name.getNameKind()) {
+  // Normal identifiers.
+  case clang::DeclarationName::Identifier:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx,
+    // decl_name.c_str());
+    if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0) {
+      SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+      return false;
     }
-        
-    std::string decl_name (clang_decl_name.getAsString());
+    break;
 
-    switch (clang_decl_name.getNameKind()) {
-    // Normal identifiers.
-    case clang::DeclarationName::Identifier:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
-        {
-            SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-            return false;
-        }
-        break;
-
-    case clang::DeclarationName::ObjCZeroArgSelector:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::ObjCOneArgSelector:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::ObjCMultiArgSelector:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::CXXConstructorName:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-
-    case clang::DeclarationName::CXXDestructorName:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::CXXConversionFunctionName:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::CXXOperatorName:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::CXXLiteralOperatorName:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-
-    case clang::DeclarationName::CXXUsingDirective:
-        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
-        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-        return false;
-    }
+  case clang::DeclarationName::ObjCZeroArgSelector:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+
+  case clang::DeclarationName::ObjCOneArgSelector:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+
+  case clang::DeclarationName::ObjCMultiArgSelector:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+
+  case clang::DeclarationName::CXXConstructorName:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+
+  case clang::DeclarationName::CXXDestructorName:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
 
+  case clang::DeclarationName::CXXConversionFunctionName:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"CXXConversionFunctionName\", name =
+    // \"%s\")\n", decl_ctx, decl_name.c_str());
     SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
     return false;
+
+  case clang::DeclarationName::CXXOperatorName:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+
+  case clang::DeclarationName::CXXLiteralOperatorName:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+
+  case clang::DeclarationName::CXXUsingDirective:
+    // printf
+    // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx
+    // = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n",
+    // decl_ctx, decl_name.c_str());
+    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+    return false;
+  }
+
+  SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+  return false;
 }
 
-void
-ClangExternalASTSourceCallbacks::CompleteType (TagDecl *tag_decl)
-{
-    if (m_callback_tag_decl)
-        m_callback_tag_decl (m_callback_baton, tag_decl);
+void ClangExternalASTSourceCallbacks::CompleteType(TagDecl *tag_decl) {
+  if (m_callback_tag_decl)
+    m_callback_tag_decl(m_callback_baton, tag_decl);
 }
 
-void
-ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl)
-{
-    if (m_callback_objc_decl)
-        m_callback_objc_decl (m_callback_baton, objc_decl);
+void ClangExternalASTSourceCallbacks::CompleteType(
+    ObjCInterfaceDecl *objc_decl) {
+  if (m_callback_objc_decl)
+    m_callback_objc_decl(m_callback_baton, objc_decl);
 }
 
-bool
-ClangExternalASTSourceCallbacks::layoutRecordType(
+bool ClangExternalASTSourceCallbacks::layoutRecordType(
     const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
     llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
-    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
-{
-    if (m_callback_layout_record_type)
-        return m_callback_layout_record_type(m_callback_baton,
-                                             Record,
-                                             Size, 
-                                             Alignment, 
-                                             FieldOffsets, 
-                                             BaseOffsets, 
-                                             VirtualBaseOffsets);
-    
-    return false;
-}
+    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+        &VirtualBaseOffsets) {
+  if (m_callback_layout_record_type)
+    return m_callback_layout_record_type(m_callback_baton, Record, Size,
+                                         Alignment, FieldOffsets, BaseOffsets,
+                                         VirtualBaseOffsets);
 
-void
-ClangExternalASTSourceCallbacks::FindExternalLexicalDecls (const clang::DeclContext *decl_ctx,
-                                                           llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
-                                                           llvm::SmallVectorImpl<clang::Decl *> &decls)
-{
-    if (m_callback_tag_decl && decl_ctx)
-    {
-        clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(const_cast<clang::DeclContext *>(decl_ctx));
-        if (tag_decl)
-            CompleteType(tag_decl);
-    }
+  return false;
 }
 
+void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
+    const clang::DeclContext *decl_ctx,
+    llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+    llvm::SmallVectorImpl<clang::Decl *> &decls) {
+  if (m_callback_tag_decl && decl_ctx) {
+    clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(
+        const_cast<clang::DeclContext *>(decl_ctx));
+    if (tag_decl)
+      CompleteType(tag_decl);
+  }
+}

Modified: lldb/trunk/source/Symbol/ClangExternalASTSourceCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangExternalASTSourceCommon.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangExternalASTSourceCommon.cpp (original)
+++ lldb/trunk/source/Symbol/ClangExternalASTSourceCommon.cpp Tue Sep  6 15:57:50 2016
@@ -14,94 +14,79 @@ using namespace lldb_private;
 
 uint64_t g_TotalSizeOfMetadata = 0;
 
-typedef llvm::DenseMap<clang::ExternalASTSource *, ClangExternalASTSourceCommon *> ASTSourceMap;
-
-static ASTSourceMap &GetSourceMap()
-{
-    // Intentionally leaked to avoid problems with global destructors.
-    static ASTSourceMap *s_source_map = new ASTSourceMap;
-    return *s_source_map;
+typedef llvm::DenseMap<clang::ExternalASTSource *,
+                       ClangExternalASTSourceCommon *>
+    ASTSourceMap;
+
+static ASTSourceMap &GetSourceMap() {
+  // Intentionally leaked to avoid problems with global destructors.
+  static ASTSourceMap *s_source_map = new ASTSourceMap;
+  return *s_source_map;
 }
 
 ClangExternalASTSourceCommon *
-ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source)
-{
-    ASTSourceMap &source_map = GetSourceMap();
-    
-    ASTSourceMap::iterator iter = source_map.find(source);
-    
-    if (iter != source_map.end())
-    {
-        return iter->second;
-    }
-    else
-    {
-        return nullptr;
-    }
-}
-
-ClangExternalASTSourceCommon::ClangExternalASTSourceCommon() : clang::ExternalASTSource()
-{
-    g_TotalSizeOfMetadata += m_metadata.size();
-    GetSourceMap()[this] = this;
-}
-
-ClangExternalASTSourceCommon::~ClangExternalASTSourceCommon()
-{
-    GetSourceMap().erase(this);
-    g_TotalSizeOfMetadata -= m_metadata.size();
+ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source) {
+  ASTSourceMap &source_map = GetSourceMap();
+
+  ASTSourceMap::iterator iter = source_map.find(source);
+
+  if (iter != source_map.end()) {
+    return iter->second;
+  } else {
+    return nullptr;
+  }
 }
 
-ClangASTMetadata *
-ClangExternalASTSourceCommon::GetMetadata (const void *object)
-{
-    if (HasMetadata (object))
-        return &m_metadata[object];
-    else
-        return nullptr;
-}
-
-void
-ClangExternalASTSourceCommon::SetMetadata (const void *object, ClangASTMetadata &metadata)
-{
-    uint64_t orig_size = m_metadata.size();
-    m_metadata[object] = metadata;
-    uint64_t new_size = m_metadata.size();
-    g_TotalSizeOfMetadata += (new_size - orig_size);
-}
-
-bool
-ClangExternalASTSourceCommon::HasMetadata (const void *object)
-{
-    return m_metadata.find(object) != m_metadata.end();
-}
-
-void
-ClangASTMetadata::Dump (Stream *s)
-{
-    lldb::user_id_t uid = GetUserID ();
-    
-    if (uid != LLDB_INVALID_UID)
-    {
-        s->Printf ("uid=0x%" PRIx64, uid);
-    }
-    
-    uint64_t isa_ptr = GetISAPtr ();
-    if (isa_ptr != 0)
-    {
-        s->Printf ("isa_ptr=0x%" PRIx64, isa_ptr);
-    }
-    
-    const char *obj_ptr_name = GetObjectPtrName();
-    if (obj_ptr_name)
-    {
-        s->Printf ("obj_ptr_name=\"%s\" ", obj_ptr_name);
-    }
-    
-    if (m_is_dynamic_cxx)
-    {
-        s->Printf ("is_dynamic_cxx=%i ", m_is_dynamic_cxx);
-    }
-    s->EOL();
+ClangExternalASTSourceCommon::ClangExternalASTSourceCommon()
+    : clang::ExternalASTSource() {
+  g_TotalSizeOfMetadata += m_metadata.size();
+  GetSourceMap()[this] = this;
 }
 
+ClangExternalASTSourceCommon::~ClangExternalASTSourceCommon() {
+  GetSourceMap().erase(this);
+  g_TotalSizeOfMetadata -= m_metadata.size();
+}
+
+ClangASTMetadata *
+ClangExternalASTSourceCommon::GetMetadata(const void *object) {
+  if (HasMetadata(object))
+    return &m_metadata[object];
+  else
+    return nullptr;
+}
+
+void ClangExternalASTSourceCommon::SetMetadata(const void *object,
+                                               ClangASTMetadata &metadata) {
+  uint64_t orig_size = m_metadata.size();
+  m_metadata[object] = metadata;
+  uint64_t new_size = m_metadata.size();
+  g_TotalSizeOfMetadata += (new_size - orig_size);
+}
+
+bool ClangExternalASTSourceCommon::HasMetadata(const void *object) {
+  return m_metadata.find(object) != m_metadata.end();
+}
+
+void ClangASTMetadata::Dump(Stream *s) {
+  lldb::user_id_t uid = GetUserID();
+
+  if (uid != LLDB_INVALID_UID) {
+    s->Printf("uid=0x%" PRIx64, uid);
+  }
+
+  uint64_t isa_ptr = GetISAPtr();
+  if (isa_ptr != 0) {
+    s->Printf("isa_ptr=0x%" PRIx64, isa_ptr);
+  }
+
+  const char *obj_ptr_name = GetObjectPtrName();
+  if (obj_ptr_name) {
+    s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name);
+  }
+
+  if (m_is_dynamic_cxx) {
+    s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx);
+  }
+  s->EOL();
+}

Modified: lldb/trunk/source/Symbol/ClangUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangUtil.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangUtil.cpp (original)
+++ lldb/trunk/source/Symbol/ClangUtil.cpp Tue Sep  6 15:57:50 2016
@@ -15,44 +15,36 @@
 using namespace clang;
 using namespace lldb_private;
 
-bool
-ClangUtil::IsClangType(const CompilerType &ct)
-{
-    if (llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) == nullptr)
-        return false;
+bool ClangUtil::IsClangType(const CompilerType &ct) {
+  if (llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) == nullptr)
+    return false;
 
-    if (!ct.GetOpaqueQualType())
-        return false;
+  if (!ct.GetOpaqueQualType())
+    return false;
 
-    return true;
+  return true;
 }
 
-QualType
-ClangUtil::GetQualType(const CompilerType &ct)
-{
-    // Make sure we have a clang type before making a clang::QualType
-    if (!IsClangType(ct))
-        return QualType();
+QualType ClangUtil::GetQualType(const CompilerType &ct) {
+  // Make sure we have a clang type before making a clang::QualType
+  if (!IsClangType(ct))
+    return QualType();
 
-    return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+  return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
 }
 
-QualType
-ClangUtil::GetCanonicalQualType(const CompilerType &ct)
-{
-    if (!IsClangType(ct))
-        return QualType();
+QualType ClangUtil::GetCanonicalQualType(const CompilerType &ct) {
+  if (!IsClangType(ct))
+    return QualType();
 
-    return GetQualType(ct).getCanonicalType();
+  return GetQualType(ct).getCanonicalType();
 }
 
-CompilerType
-ClangUtil::RemoveFastQualifiers(const CompilerType &ct)
-{
-    if (!IsClangType(ct))
-        return ct;
-
-    QualType qual_type(GetQualType(ct));
-    qual_type.removeLocalFastQualifiers();
-    return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
+CompilerType ClangUtil::RemoveFastQualifiers(const CompilerType &ct) {
+  if (!IsClangType(ct))
+    return ct;
+
+  QualType qual_type(GetQualType(ct));
+  qual_type.removeLocalFastQualifiers();
+  return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
 }




More information about the lldb-commits mailing list