Add OpenCL images as clang builtin types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170428 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index f3fa135..b04b830 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -874,6 +874,15 @@
   InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
   InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
   InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
+
+  if (LangOpts.OpenCL) { 
+    InitBuiltinType(OCLImage1dTy, BuiltinType::OCLImage1d);
+    InitBuiltinType(OCLImage1dArrayTy, BuiltinType::OCLImage1dArray);
+    InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer);
+    InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d);
+    InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray);
+    InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d);
+  }
   
   // Builtin type for __objc_yes and __objc_no
   ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?
@@ -1412,6 +1421,16 @@
       Width = Target->getPointerWidth(0); 
       Align = Target->getPointerAlign(0);
       break;
+    case BuiltinType::OCLImage1d:
+    case BuiltinType::OCLImage1dArray:
+    case BuiltinType::OCLImage1dBuffer:
+    case BuiltinType::OCLImage2d:
+    case BuiltinType::OCLImage2dArray:
+    case BuiltinType::OCLImage3d:
+      // Currently these types are pointers to opaque types.
+      Width = Target->getPointerWidth(0);
+      Align = Target->getPointerAlign(0);
+      break;
     }
     break;
   case Type::ObjCObjectPointer:
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 566a389..65907f9 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1,3574 +1,3580 @@
-//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implements C++ name mangling according to the Itanium C++ ABI,
-// which is used in GCC 3.2 and newer (and many compilers that are
-// ABI-compatible with GCC):
-//
-//   http://www.codesourcery.com/public/cxx-abi/abi.html
-//
-//===----------------------------------------------------------------------===//
-#include "clang/AST/Mangle.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/ABI.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-
-#define MANGLE_CHECKER 0
-
-#if MANGLE_CHECKER
-#include <cxxabi.h>
-#endif
-
-using namespace clang;
-
-namespace {
-
-/// \brief Retrieve the declaration context that should be used when mangling 
-/// the given declaration.
-static const DeclContext *getEffectiveDeclContext(const Decl *D) {
-  // The ABI assumes that lambda closure types that occur within 
-  // default arguments live in the context of the function. However, due to
-  // the way in which Clang parses and creates function declarations, this is
-  // not the case: the lambda closure type ends up living in the context 
-  // where the function itself resides, because the function declaration itself
-  // had not yet been created. Fix the context here.
-  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
-    if (RD->isLambda())
-      if (ParmVarDecl *ContextParam
-            = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
-        return ContextParam->getDeclContext();
-  }
-  
-  return D->getDeclContext();
-}
-
-static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
-  return getEffectiveDeclContext(cast<Decl>(DC));
-}
-  
-static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) {
-  const DeclContext *DC = dyn_cast<DeclContext>(ND);
-  if (!DC)
-    DC = getEffectiveDeclContext(ND);
-  while (!DC->isNamespace() && !DC->isTranslationUnit()) {
-    const DeclContext *Parent = getEffectiveDeclContext(cast<Decl>(DC));
-    if (isa<FunctionDecl>(Parent))
-      return dyn_cast<CXXRecordDecl>(DC);
-    DC = Parent;
-  }
-  return 0;
-}
-
-static const FunctionDecl *getStructor(const FunctionDecl *fn) {
-  if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate())
-    return ftd->getTemplatedDecl();
-
-  return fn;
-}
-
-static const NamedDecl *getStructor(const NamedDecl *decl) {
-  const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl);
-  return (fn ? getStructor(fn) : decl);
-}
-                                                    
-static const unsigned UnknownArity = ~0U;
-
-class ItaniumMangleContext : public MangleContext {
-  llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
-  unsigned Discriminator;
-  llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
-  
-public:
-  explicit ItaniumMangleContext(ASTContext &Context,
-                                DiagnosticsEngine &Diags)
-    : MangleContext(Context, Diags) { }
-
-  uint64_t getAnonymousStructId(const TagDecl *TD) {
-    std::pair<llvm::DenseMap<const TagDecl *,
-      uint64_t>::iterator, bool> Result =
-      AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
-    return Result.first->second;
-  }
-
-  void startNewFunction() {
-    MangleContext::startNewFunction();
-    mangleInitDiscriminator();
-  }
-
-  /// @name Mangler Entry Points
-  /// @{
-
-  bool shouldMangleDeclName(const NamedDecl *D);
-  void mangleName(const NamedDecl *D, raw_ostream &);
-  void mangleThunk(const CXXMethodDecl *MD,
-                   const ThunkInfo &Thunk,
-                   raw_ostream &);
-  void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
-                          const ThisAdjustment &ThisAdjustment,
-                          raw_ostream &);
-  void mangleReferenceTemporary(const VarDecl *D,
-                                raw_ostream &);
-  void mangleCXXVTable(const CXXRecordDecl *RD,
-                       raw_ostream &);
-  void mangleCXXVTT(const CXXRecordDecl *RD,
-                    raw_ostream &);
-  void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
-                           const CXXRecordDecl *Type,
-                           raw_ostream &);
-  void mangleCXXRTTI(QualType T, raw_ostream &);
-  void mangleCXXRTTIName(QualType T, raw_ostream &);
-  void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
-                     raw_ostream &);
-  void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
-                     raw_ostream &);
-
-  void mangleItaniumGuardVariable(const VarDecl *D, raw_ostream &);
-
-  void mangleInitDiscriminator() {
-    Discriminator = 0;
-  }
-
-  bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
-    // Lambda closure types with external linkage (indicated by a 
-    // non-zero lambda mangling number) have their own numbering scheme, so
-    // they do not need a discriminator.
-    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))
-      if (RD->isLambda() && RD->getLambdaManglingNumber() > 0)
-        return false;
-        
-    unsigned &discriminator = Uniquifier[ND];
-    if (!discriminator)
-      discriminator = ++Discriminator;
-    if (discriminator == 1)
-      return false;
-    disc = discriminator-2;
-    return true;
-  }
-  /// @}
-};
-
-/// CXXNameMangler - Manage the mangling of a single name.
-class CXXNameMangler {
-  ItaniumMangleContext &Context;
-  raw_ostream &Out;
-
-  /// The "structor" is the top-level declaration being mangled, if
-  /// that's not a template specialization; otherwise it's the pattern
-  /// for that specialization.
-  const NamedDecl *Structor;
-  unsigned StructorType;
-
-  /// SeqID - The next subsitution sequence number.
-  unsigned SeqID;
-
-  class FunctionTypeDepthState {
-    unsigned Bits;
-
-    enum { InResultTypeMask = 1 };
-
-  public:
-    FunctionTypeDepthState() : Bits(0) {}
-
-    /// The number of function types we're inside.
-    unsigned getDepth() const {
-      return Bits >> 1;
-    }
-
-    /// True if we're in the return type of the innermost function type.
-    bool isInResultType() const {
-      return Bits & InResultTypeMask;
-    }
-
-    FunctionTypeDepthState push() {
-      FunctionTypeDepthState tmp = *this;
-      Bits = (Bits & ~InResultTypeMask) + 2;
-      return tmp;
-    }
-
-    void enterResultType() {
-      Bits |= InResultTypeMask;
-    }
-
-    void leaveResultType() {
-      Bits &= ~InResultTypeMask;
-    }
-
-    void pop(FunctionTypeDepthState saved) {
-      assert(getDepth() == saved.getDepth() + 1);
-      Bits = saved.Bits;
-    }
-
-  } FunctionTypeDepth;
-
-  llvm::DenseMap<uintptr_t, unsigned> Substitutions;
-
-  ASTContext &getASTContext() const { return Context.getASTContext(); }
-
-public:
-  CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,
-                 const NamedDecl *D = 0)
-    : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),
-      SeqID(0) {
-    // These can't be mangled without a ctor type or dtor type.
-    assert(!D || (!isa<CXXDestructorDecl>(D) &&
-                  !isa<CXXConstructorDecl>(D)));
-  }
-  CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,
-                 const CXXConstructorDecl *D, CXXCtorType Type)
-    : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
-      SeqID(0) { }
-  CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,
-                 const CXXDestructorDecl *D, CXXDtorType Type)
-    : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
-      SeqID(0) { }
-
-#if MANGLE_CHECKER
-  ~CXXNameMangler() {
-    if (Out.str()[0] == '\01')
-      return;
-
-    int status = 0;
-    char *result = abi::__cxa_demangle(Out.str().str().c_str(), 0, 0, &status);
-    assert(status == 0 && "Could not demangle mangled name!");
-    free(result);
-  }
-#endif
-  raw_ostream &getStream() { return Out; }
-
-  void mangle(const NamedDecl *D, StringRef Prefix = "_Z");
-  void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
-  void mangleNumber(const llvm::APSInt &I);
-  void mangleNumber(int64_t Number);
-  void mangleFloat(const llvm::APFloat &F);
-  void mangleFunctionEncoding(const FunctionDecl *FD);
-  void mangleName(const NamedDecl *ND);
-  void mangleType(QualType T);
-  void mangleNameOrStandardSubstitution(const NamedDecl *ND);
-  
-private:
-  bool mangleSubstitution(const NamedDecl *ND);
-  bool mangleSubstitution(QualType T);
-  bool mangleSubstitution(TemplateName Template);
-  bool mangleSubstitution(uintptr_t Ptr);
-
-  void mangleExistingSubstitution(QualType type);
-  void mangleExistingSubstitution(TemplateName name);
-
-  bool mangleStandardSubstitution(const NamedDecl *ND);
-
-  void addSubstitution(const NamedDecl *ND) {
-    ND = cast<NamedDecl>(ND->getCanonicalDecl());
-
-    addSubstitution(reinterpret_cast<uintptr_t>(ND));
-  }
-  void addSubstitution(QualType T);
-  void addSubstitution(TemplateName Template);
-  void addSubstitution(uintptr_t Ptr);
-
-  void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
-                              NamedDecl *firstQualifierLookup,
-                              bool recursive = false);
-  void mangleUnresolvedName(NestedNameSpecifier *qualifier,
-                            NamedDecl *firstQualifierLookup,
-                            DeclarationName name,
-                            unsigned KnownArity = UnknownArity);
-
-  void mangleName(const TemplateDecl *TD,
-                  const TemplateArgument *TemplateArgs,
-                  unsigned NumTemplateArgs);
-  void mangleUnqualifiedName(const NamedDecl *ND) {
-    mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity);
-  }
-  void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name,
-                             unsigned KnownArity);
-  void mangleUnscopedName(const NamedDecl *ND);
-  void mangleUnscopedTemplateName(const TemplateDecl *ND);
-  void mangleUnscopedTemplateName(TemplateName);
-  void mangleSourceName(const IdentifierInfo *II);
-  void mangleLocalName(const NamedDecl *ND);
-  void mangleLambda(const CXXRecordDecl *Lambda);
-  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
-                        bool NoFunction=false);
-  void mangleNestedName(const TemplateDecl *TD,
-                        const TemplateArgument *TemplateArgs,
-                        unsigned NumTemplateArgs);
-  void manglePrefix(NestedNameSpecifier *qualifier);
-  void manglePrefix(const DeclContext *DC, bool NoFunction=false);
-  void manglePrefix(QualType type);
-  void mangleTemplatePrefix(const TemplateDecl *ND);
-  void mangleTemplatePrefix(TemplateName Template);
-  void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
-  void mangleQualifiers(Qualifiers Quals);
-  void mangleRefQualifier(RefQualifierKind RefQualifier);
-
-  void mangleObjCMethodName(const ObjCMethodDecl *MD);
-
-  // Declare manglers for every type class.
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define NON_CANONICAL_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
-
-  void mangleType(const TagType*);
-  void mangleType(TemplateName);
-  void mangleBareFunctionType(const FunctionType *T,
-                              bool MangleReturnType);
-  void mangleNeonVectorType(const VectorType *T);
-
-  void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value);
-  void mangleMemberExpr(const Expr *base, bool isArrow,
-                        NestedNameSpecifier *qualifier,
-                        NamedDecl *firstQualifierLookup,
-                        DeclarationName name,
-                        unsigned knownArity);
-  void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
-  void mangleCXXCtorType(CXXCtorType T);
-  void mangleCXXDtorType(CXXDtorType T);
-
-  void mangleTemplateArgs(const ASTTemplateArgumentListInfo &TemplateArgs);
-  void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs);
-  void mangleTemplateArgs(const TemplateArgumentList &AL);
-  void mangleTemplateArg(TemplateArgument A);
-
-  void mangleTemplateParameter(unsigned Index);
-
-  void mangleFunctionParam(const ParmVarDecl *parm);
-};
-
-}
-
-static bool isInCLinkageSpecification(const Decl *D) {
-  D = D->getCanonicalDecl();
-  for (const DeclContext *DC = getEffectiveDeclContext(D);
-       !DC->isTranslationUnit(); DC = getEffectiveParentContext(DC)) {
-    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
-      return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
-  }
-
-  return false;
-}
-
-bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
-  // In C, functions with no attributes never need to be mangled. Fastpath them.
-  if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
-    return false;
-
-  // Any decl can be declared with __asm("foo") on it, and this takes precedence
-  // over all other naming in the .o file.
-  if (D->hasAttr<AsmLabelAttr>())
-    return true;
-
-  // Clang's "overloadable" attribute extension to C/C++ implies name mangling
-  // (always) as does passing a C++ member function and a function
-  // whose name is not a simple identifier.
-  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||
-             !FD->getDeclName().isIdentifier()))
-    return true;
-
-  // Otherwise, no mangling is done outside C++ mode.
-  if (!getASTContext().getLangOpts().CPlusPlus)
-    return false;
-
-  // Variables at global scope with non-internal linkage are not mangled
-  if (!FD) {
-    const DeclContext *DC = getEffectiveDeclContext(D);
-    // Check for extern variable declared locally.
-    if (DC->isFunctionOrMethod() && D->hasLinkage())
-      while (!DC->isNamespace() && !DC->isTranslationUnit())
-        DC = getEffectiveParentContext(DC);
-    if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)
-      return false;
-  }
-
-  // Class members are always mangled.
-  if (getEffectiveDeclContext(D)->isRecord())
-    return true;
-
-  // C functions and "main" are not mangled.
-  if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
-    return false;
-
-  return true;
-}
-
-void CXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
-  // Any decl can be declared with __asm("foo") on it, and this takes precedence
-  // over all other naming in the .o file.
-  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
-    // If we have an asm name, then we use it as the mangling.
-
-    // Adding the prefix can cause problems when one file has a "foo" and
-    // another has a "\01foo". That is known to happen on ELF with the
-    // tricks normally used for producing aliases (PR9177). Fortunately the
-    // llvm mangler on ELF is a nop, so we can just avoid adding the \01
-    // marker.  We also avoid adding the marker if this is an alias for an
-    // LLVM intrinsic.
-    StringRef UserLabelPrefix =
-      getASTContext().getTargetInfo().getUserLabelPrefix();
-    if (!UserLabelPrefix.empty() && !ALA->getLabel().startswith("llvm."))
-      Out << '\01';  // LLVM IR Marker for __asm("foo")
-
-    Out << ALA->getLabel();
-    return;
-  }
-
-  // <mangled-name> ::= _Z <encoding>
-  //            ::= <data name>
-  //            ::= <special-name>
-  Out << Prefix;
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    mangleFunctionEncoding(FD);
-  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
-    mangleName(VD);
-  else
-    mangleName(cast<FieldDecl>(D));
-}
-
-void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
-  // <encoding> ::= <function name> <bare-function-type>
-  mangleName(FD);
-
-  // Don't mangle in the type if this isn't a decl we should typically mangle.
-  if (!Context.shouldMangleDeclName(FD))
-    return;
-
-  // Whether the mangling of a function type includes the return type depends on
-  // the context and the nature of the function. The rules for deciding whether
-  // the return type is included are:
-  //
-  //   1. Template functions (names or types) have return types encoded, with
-  //   the exceptions listed below.
-  //   2. Function types not appearing as part of a function name mangling,
-  //   e.g. parameters, pointer types, etc., have return type encoded, with the
-  //   exceptions listed below.
-  //   3. Non-template function names do not have return types encoded.
-  //
-  // The exceptions mentioned in (1) and (2) above, for which the return type is
-  // never included, are
-  //   1. Constructors.
-  //   2. Destructors.
-  //   3. Conversion operator functions, e.g. operator int.
-  bool MangleReturnType = false;
-  if (FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate()) {
-    if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
-          isa<CXXConversionDecl>(FD)))
-      MangleReturnType = true;
-
-    // Mangle the type of the primary template.
-    FD = PrimaryTemplate->getTemplatedDecl();
-  }
-
-  mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), 
-                         MangleReturnType);
-}
-
-static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
-  while (isa<LinkageSpecDecl>(DC)) {
-    DC = getEffectiveParentContext(DC);
-  }
-
-  return DC;
-}
-
-/// isStd - Return whether a given namespace is the 'std' namespace.
-static bool isStd(const NamespaceDecl *NS) {
-  if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS))
-                                ->isTranslationUnit())
-    return false;
-  
-  const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
-  return II && II->isStr("std");
-}
-
-// isStdNamespace - Return whether a given decl context is a toplevel 'std'
-// namespace.
-static bool isStdNamespace(const DeclContext *DC) {
-  if (!DC->isNamespace())
-    return false;
-
-  return isStd(cast<NamespaceDecl>(DC));
-}
-
-static const TemplateDecl *
-isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
-  // Check if we have a function template.
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
-    if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
-      TemplateArgs = FD->getTemplateSpecializationArgs();
-      return TD;
-    }
-  }
-
-  // Check if we have a class template.
-  if (const ClassTemplateSpecializationDecl *Spec =
-        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
-    TemplateArgs = &Spec->getTemplateArgs();
-    return Spec->getSpecializedTemplate();
-  }
-
-  return 0;
-}
-
-static bool isLambda(const NamedDecl *ND) {
-  const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
-  if (!Record)
-    return false;
-  
-  return Record->isLambda();
-}
-
-void CXXNameMangler::mangleName(const NamedDecl *ND) {
-  //  <name> ::= <nested-name>
-  //         ::= <unscoped-name>
-  //         ::= <unscoped-template-name> <template-args>
-  //         ::= <local-name>
-  //
-  const DeclContext *DC = getEffectiveDeclContext(ND);
-
-  // If this is an extern variable declared locally, the relevant DeclContext
-  // is that of the containing namespace, or the translation unit.
-  // FIXME: This is a hack; extern variables declared locally should have
-  // a proper semantic declaration context!
-  if (isa<FunctionDecl>(DC) && ND->hasLinkage() && !isLambda(ND))
-    while (!DC->isNamespace() && !DC->isTranslationUnit())
-      DC = getEffectiveParentContext(DC);
-  else if (GetLocalClassDecl(ND)) {
-    mangleLocalName(ND);
-    return;
-  }
-
-  DC = IgnoreLinkageSpecDecls(DC);
-
-  if (DC->isTranslationUnit() || isStdNamespace(DC)) {
-    // Check if we have a template.
-    const TemplateArgumentList *TemplateArgs = 0;
-    if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
-      mangleUnscopedTemplateName(TD);
-      mangleTemplateArgs(*TemplateArgs);
-      return;
-    }
-
-    mangleUnscopedName(ND);
-    return;
-  }
-
-  if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) {
-    mangleLocalName(ND);
-    return;
-  }
-
-  mangleNestedName(ND, DC);
-}
-void CXXNameMangler::mangleName(const TemplateDecl *TD,
-                                const TemplateArgument *TemplateArgs,
-                                unsigned NumTemplateArgs) {
-  const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD));
-
-  if (DC->isTranslationUnit() || isStdNamespace(DC)) {
-    mangleUnscopedTemplateName(TD);
-    mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
-  } else {
-    mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
-  }
-}
-
-void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {
-  //  <unscoped-name> ::= <unqualified-name>
-  //                  ::= St <unqualified-name>   # ::std::
-
-  if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND))))
-    Out << "St";
-
-  mangleUnqualifiedName(ND);
-}
-
-void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {
-  //     <unscoped-template-name> ::= <unscoped-name>
-  //                              ::= <substitution>
-  if (mangleSubstitution(ND))
-    return;
-
-  // <template-template-param> ::= <template-param>
-  if (const TemplateTemplateParmDecl *TTP
-                                     = dyn_cast<TemplateTemplateParmDecl>(ND)) {
-    mangleTemplateParameter(TTP->getIndex());
-    return;
-  }
-
-  mangleUnscopedName(ND->getTemplatedDecl());
-  addSubstitution(ND);
-}
-
-void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) {
-  //     <unscoped-template-name> ::= <unscoped-name>
-  //                              ::= <substitution>
-  if (TemplateDecl *TD = Template.getAsTemplateDecl())
-    return mangleUnscopedTemplateName(TD);
-  
-  if (mangleSubstitution(Template))
-    return;
-
-  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
-  assert(Dependent && "Not a dependent template name?");
-  if (const IdentifierInfo *Id = Dependent->getIdentifier())
-    mangleSourceName(Id);
-  else
-    mangleOperatorName(Dependent->getOperator(), UnknownArity);
-  
-  addSubstitution(Template);
-}
-
-void CXXNameMangler::mangleFloat(const llvm::APFloat &f) {
-  // ABI:
-  //   Floating-point literals are encoded using a fixed-length
-  //   lowercase hexadecimal string corresponding to the internal
-  //   representation (IEEE on Itanium), high-order bytes first,
-  //   without leading zeroes. For example: "Lf bf800000 E" is -1.0f
-  //   on Itanium.
-  // The 'without leading zeroes' thing seems to be an editorial
-  // mistake; see the discussion on cxx-abi-dev beginning on
-  // 2012-01-16.
-
-  // Our requirements here are just barely weird enough to justify
-  // using a custom algorithm instead of post-processing APInt::toString().
-
-  llvm::APInt valueBits = f.bitcastToAPInt();
-  unsigned numCharacters = (valueBits.getBitWidth() + 3) / 4;
-  assert(numCharacters != 0);
-
-  // Allocate a buffer of the right number of characters.
-  llvm::SmallVector<char, 20> buffer;
-  buffer.set_size(numCharacters);
-
-  // Fill the buffer left-to-right.
-  for (unsigned stringIndex = 0; stringIndex != numCharacters; ++stringIndex) {
-    // The bit-index of the next hex digit.
-    unsigned digitBitIndex = 4 * (numCharacters - stringIndex - 1);
-
-    // Project out 4 bits starting at 'digitIndex'.
-    llvm::integerPart hexDigit
-      = valueBits.getRawData()[digitBitIndex / llvm::integerPartWidth];
-    hexDigit >>= (digitBitIndex % llvm::integerPartWidth);
-    hexDigit &= 0xF;
-
-    // Map that over to a lowercase hex digit.
-    static const char charForHex[16] = {
-      '0', '1', '2', '3', '4', '5', '6', '7',
-      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-    };
-    buffer[stringIndex] = charForHex[hexDigit];
-  }
-
-  Out.write(buffer.data(), numCharacters);
-}
-
-void CXXNameMangler::mangleNumber(const llvm::APSInt &Value) {
-  if (Value.isSigned() && Value.isNegative()) {
-    Out << 'n';
-    Value.abs().print(Out, /*signed*/ false);
-  } else {
-    Value.print(Out, /*signed*/ false);
-  }
-}
-
-void CXXNameMangler::mangleNumber(int64_t Number) {
-  //  <number> ::= [n] <non-negative decimal integer>
-  if (Number < 0) {
-    Out << 'n';
-    Number = -Number;
-  }
-
-  Out << Number;
-}
-
-void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) {
-  //  <call-offset>  ::= h <nv-offset> _
-  //                 ::= v <v-offset> _
-  //  <nv-offset>    ::= <offset number>        # non-virtual base override
-  //  <v-offset>     ::= <offset number> _ <virtual offset number>
-  //                      # virtual base override, with vcall offset
-  if (!Virtual) {
-    Out << 'h';
-    mangleNumber(NonVirtual);
-    Out << '_';
-    return;
-  }
-
-  Out << 'v';
-  mangleNumber(NonVirtual);
-  Out << '_';
-  mangleNumber(Virtual);
-  Out << '_';
-}
-
-void CXXNameMangler::manglePrefix(QualType type) {
-  if (const TemplateSpecializationType *TST =
-        type->getAs<TemplateSpecializationType>()) {
-    if (!mangleSubstitution(QualType(TST, 0))) {
-      mangleTemplatePrefix(TST->getTemplateName());
-        
-      // FIXME: GCC does not appear to mangle the template arguments when
-      // the template in question is a dependent template name. Should we
-      // emulate that badness?
-      mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
-      addSubstitution(QualType(TST, 0));
-    }
-  } else if (const DependentTemplateSpecializationType *DTST
-               = type->getAs<DependentTemplateSpecializationType>()) {
-    TemplateName Template
-      = getASTContext().getDependentTemplateName(DTST->getQualifier(), 
-                                                 DTST->getIdentifier());
-    mangleTemplatePrefix(Template);
-
-    // FIXME: GCC does not appear to mangle the template arguments when
-    // the template in question is a dependent template name. Should we
-    // emulate that badness?
-    mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
-  } else {
-    // We use the QualType mangle type variant here because it handles
-    // substitutions.
-    mangleType(type);
-  }
-}
-
-/// Mangle everything prior to the base-unresolved-name in an unresolved-name.
-///
-/// \param firstQualifierLookup - the entity found by unqualified lookup
-///   for the first name in the qualifier, if this is for a member expression
-/// \param recursive - true if this is being called recursively,
-///   i.e. if there is more prefix "to the right".
-void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
-                                            NamedDecl *firstQualifierLookup,
-                                            bool recursive) {
-
-  // x, ::x
-  // <unresolved-name> ::= [gs] <base-unresolved-name>
-
-  // T::x / decltype(p)::x
-  // <unresolved-name> ::= sr <unresolved-type> <base-unresolved-name>
-
-  // T::N::x /decltype(p)::N::x
-  // <unresolved-name> ::= srN <unresolved-type> <unresolved-qualifier-level>+ E
-  //                       <base-unresolved-name>
-
-  // A::x, N::y, A<T>::z; "gs" means leading "::"
-  // <unresolved-name> ::= [gs] sr <unresolved-qualifier-level>+ E
-  //                       <base-unresolved-name>
-
-  switch (qualifier->getKind()) {
-  case NestedNameSpecifier::Global:
-    Out << "gs";
-
-    // We want an 'sr' unless this is the entire NNS.
-    if (recursive)
-      Out << "sr";
-
-    // We never want an 'E' here.
-    return;
-
-  case NestedNameSpecifier::Namespace:
-    if (qualifier->getPrefix())
-      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
-                             /*recursive*/ true);
-    else
-      Out << "sr";
-    mangleSourceName(qualifier->getAsNamespace()->getIdentifier());
-    break;
-  case NestedNameSpecifier::NamespaceAlias:
-    if (qualifier->getPrefix())
-      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
-                             /*recursive*/ true);
-    else
-      Out << "sr";
-    mangleSourceName(qualifier->getAsNamespaceAlias()->getIdentifier());
-    break;
-
-  case NestedNameSpecifier::TypeSpec:
-  case NestedNameSpecifier::TypeSpecWithTemplate: {
-    const Type *type = qualifier->getAsType();
-
-    // We only want to use an unresolved-type encoding if this is one of:
-    //   - a decltype
-    //   - a template type parameter
-    //   - a template template parameter with arguments
-    // In all of these cases, we should have no prefix.
-    if (qualifier->getPrefix()) {
-      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
-                             /*recursive*/ true);
-    } else {
-      // Otherwise, all the cases want this.
-      Out << "sr";
-    }
-
-    // Only certain other types are valid as prefixes;  enumerate them.
-    switch (type->getTypeClass()) {
-    case Type::Builtin:
-    case Type::Complex:
-    case Type::Pointer:
-    case Type::BlockPointer:
-    case Type::LValueReference:
-    case Type::RValueReference:
-    case Type::MemberPointer:
-    case Type::ConstantArray:
-    case Type::IncompleteArray:
-    case Type::VariableArray:
-    case Type::DependentSizedArray:
-    case Type::DependentSizedExtVector:
-    case Type::Vector:
-    case Type::ExtVector:
-    case Type::FunctionProto:
-    case Type::FunctionNoProto:
-    case Type::Enum:
-    case Type::Paren:
-    case Type::Elaborated:
-    case Type::Attributed:
-    case Type::Auto:
-    case Type::PackExpansion:
-    case Type::ObjCObject:
-    case Type::ObjCInterface:
-    case Type::ObjCObjectPointer:
-    case Type::Atomic:
-      llvm_unreachable("type is illegal as a nested name specifier");
-
-    case Type::SubstTemplateTypeParmPack:
-      // FIXME: not clear how to mangle this!
-      // template <class T...> class A {
-      //   template <class U...> void foo(decltype(T::foo(U())) x...);
-      // };
-      Out << "_SUBSTPACK_";
-      break;
-
-    // <unresolved-type> ::= <template-param>
-    //                   ::= <decltype>
-    //                   ::= <template-template-param> <template-args>
-    // (this last is not official yet)
-    case Type::TypeOfExpr:
-    case Type::TypeOf:
-    case Type::Decltype:
-    case Type::TemplateTypeParm:
-    case Type::UnaryTransform:
-    case Type::SubstTemplateTypeParm:
-    unresolvedType:
-      assert(!qualifier->getPrefix());
-
-      // We only get here recursively if we're followed by identifiers.
-      if (recursive) Out << 'N';
-
-      // This seems to do everything we want.  It's not really
-      // sanctioned for a substituted template parameter, though.
-      mangleType(QualType(type, 0));
-
-      // We never want to print 'E' directly after an unresolved-type,
-      // so we return directly.
-      return;
-
-    case Type::Typedef:
-      mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier());
-      break;
-
-    case Type::UnresolvedUsing:
-      mangleSourceName(cast<UnresolvedUsingType>(type)->getDecl()
-                         ->getIdentifier());
-      break;
-
-    case Type::Record:
-      mangleSourceName(cast<RecordType>(type)->getDecl()->getIdentifier());
-      break;
-
-    case Type::TemplateSpecialization: {
-      const TemplateSpecializationType *tst
-        = cast<TemplateSpecializationType>(type);
-      TemplateName name = tst->getTemplateName();
-      switch (name.getKind()) {
-      case TemplateName::Template:
-      case TemplateName::QualifiedTemplate: {
-        TemplateDecl *temp = name.getAsTemplateDecl();
-
-        // If the base is a template template parameter, this is an
-        // unresolved type.
-        assert(temp && "no template for template specialization type");
-        if (isa<TemplateTemplateParmDecl>(temp)) goto unresolvedType;
-
-        mangleSourceName(temp->getIdentifier());
-        break;
-      }
-
-      case TemplateName::OverloadedTemplate:
-      case TemplateName::DependentTemplate:
-        llvm_unreachable("invalid base for a template specialization type");
-
-      case TemplateName::SubstTemplateTemplateParm: {
-        SubstTemplateTemplateParmStorage *subst
-          = name.getAsSubstTemplateTemplateParm();
-        mangleExistingSubstitution(subst->getReplacement());
-        break;
-      }
-
-      case TemplateName::SubstTemplateTemplateParmPack: {
-        // FIXME: not clear how to mangle this!
-        // template <template <class U> class T...> class A {
-        //   template <class U...> void foo(decltype(T<U>::foo) x...);
-        // };
-        Out << "_SUBSTPACK_";
-        break;
-      }
-      }
-
-      mangleTemplateArgs(tst->getArgs(), tst->getNumArgs());
-      break;
-    }
-
-    case Type::InjectedClassName:
-      mangleSourceName(cast<InjectedClassNameType>(type)->getDecl()
-                         ->getIdentifier());
-      break;
-
-    case Type::DependentName:
-      mangleSourceName(cast<DependentNameType>(type)->getIdentifier());
-      break;
-
-    case Type::DependentTemplateSpecialization: {
-      const DependentTemplateSpecializationType *tst
-        = cast<DependentTemplateSpecializationType>(type);
-      mangleSourceName(tst->getIdentifier());
-      mangleTemplateArgs(tst->getArgs(), tst->getNumArgs());
-      break;
-    }
-    }
-    break;
-  }
-
-  case NestedNameSpecifier::Identifier:
-    // Member expressions can have these without prefixes.
-    if (qualifier->getPrefix()) {
-      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
-                             /*recursive*/ true);
-    } else if (firstQualifierLookup) {
-
-      // Try to make a proper qualifier out of the lookup result, and
-      // then just recurse on that.
-      NestedNameSpecifier *newQualifier;
-      if (TypeDecl *typeDecl = dyn_cast<TypeDecl>(firstQualifierLookup)) {
-        QualType type = getASTContext().getTypeDeclType(typeDecl);
-
-        // Pretend we had a different nested name specifier.
-        newQualifier = NestedNameSpecifier::Create(getASTContext(),
-                                                   /*prefix*/ 0,
-                                                   /*template*/ false,
-                                                   type.getTypePtr());
-      } else if (NamespaceDecl *nspace =
-                   dyn_cast<NamespaceDecl>(firstQualifierLookup)) {
-        newQualifier = NestedNameSpecifier::Create(getASTContext(),
-                                                   /*prefix*/ 0,
-                                                   nspace);
-      } else if (NamespaceAliasDecl *alias =
-                   dyn_cast<NamespaceAliasDecl>(firstQualifierLookup)) {
-        newQualifier = NestedNameSpecifier::Create(getASTContext(),
-                                                   /*prefix*/ 0,
-                                                   alias);
-      } else {
-        // No sensible mangling to do here.
-        newQualifier = 0;
-      }
-
-      if (newQualifier)
-        return mangleUnresolvedPrefix(newQualifier, /*lookup*/ 0, recursive);
-
-    } else {
-      Out << "sr";
-    }
-
-    mangleSourceName(qualifier->getAsIdentifier());
-    break;
-  }
-
-  // If this was the innermost part of the NNS, and we fell out to
-  // here, append an 'E'.
-  if (!recursive)
-    Out << 'E';
-}
-
-/// Mangle an unresolved-name, which is generally used for names which
-/// weren't resolved to specific entities.
-void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier,
-                                          NamedDecl *firstQualifierLookup,
-                                          DeclarationName name,
-                                          unsigned knownArity) {
-  if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup);
-  mangleUnqualifiedName(0, name, knownArity);
-}
-
-static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {
-  assert(RD->isAnonymousStructOrUnion() &&
-         "Expected anonymous struct or union!");
-  
-  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-       I != E; ++I) {
-    if (I->getIdentifier())
-      return *I;
-    
-    if (const RecordType *RT = I->getType()->getAs<RecordType>())
-      if (const FieldDecl *NamedDataMember = 
-          FindFirstNamedDataMember(RT->getDecl()))
-        return NamedDataMember;
-    }
-
-  // We didn't find a named data member.
-  return 0;
-}
-
-void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
-                                           DeclarationName Name,
-                                           unsigned KnownArity) {
-  //  <unqualified-name> ::= <operator-name>
-  //                     ::= <ctor-dtor-name>
-  //                     ::= <source-name>
-  switch (Name.getNameKind()) {
-  case DeclarationName::Identifier: {
-    if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
-      // We must avoid conflicts between internally- and externally-
-      // linked variable and function declaration names in the same TU:
-      //   void test() { extern void foo(); }
-      //   static void foo();
-      // This naming convention is the same as that followed by GCC,
-      // though it shouldn't actually matter.
-      if (ND && ND->getLinkage() == InternalLinkage &&
-          getEffectiveDeclContext(ND)->isFileContext())
-        Out << 'L';
-
-      mangleSourceName(II);
-      break;
-    }
-
-    // Otherwise, an anonymous entity.  We must have a declaration.
-    assert(ND && "mangling empty name without declaration");
-
-    if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
-      if (NS->isAnonymousNamespace()) {
-        // This is how gcc mangles these names.
-        Out << "12_GLOBAL__N_1";
-        break;
-      }
-    }
-
-    if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
-      // We must have an anonymous union or struct declaration.
-      const RecordDecl *RD = 
-        cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl());
-      
-      // Itanium C++ ABI 5.1.2:
-      //
-      //   For the purposes of mangling, the name of an anonymous union is
-      //   considered to be the name of the first named data member found by a
-      //   pre-order, depth-first, declaration-order walk of the data members of
-      //   the anonymous union. If there is no such data member (i.e., if all of
-      //   the data members in the union are unnamed), then there is no way for
-      //   a program to refer to the anonymous union, and there is therefore no
-      //   need to mangle its name.
-      const FieldDecl *FD = FindFirstNamedDataMember(RD);
-
-      // It's actually possible for various reasons for us to get here
-      // with an empty anonymous struct / union.  Fortunately, it
-      // doesn't really matter what name we generate.
-      if (!FD) break;
-      assert(FD->getIdentifier() && "Data member name isn't an identifier!");
-      
-      mangleSourceName(FD->getIdentifier());
-      break;
-    }
-    
-    // We must have an anonymous struct.
-    const TagDecl *TD = cast<TagDecl>(ND);
-    if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
-      assert(TD->getDeclContext() == D->getDeclContext() &&
-             "Typedef should not be in another decl context!");
-      assert(D->getDeclName().getAsIdentifierInfo() &&
-             "Typedef was not named!");
-      mangleSourceName(D->getDeclName().getAsIdentifierInfo());
-      break;
-    }
-
-    // <unnamed-type-name> ::= <closure-type-name>
-    // 
-    // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
-    // <lambda-sig> ::= <parameter-type>+   # Parameter types or 'v' for 'void'.
-    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
-      if (Record->isLambda() && Record->getLambdaManglingNumber()) {
-        mangleLambda(Record);
-        break;
-      }
-    }
-
-    int UnnamedMangle = Context.getASTContext().getUnnamedTagManglingNumber(TD);
-    if (UnnamedMangle != -1) {
-      Out << "Ut";
-      if (UnnamedMangle != 0)
-        Out << llvm::utostr(UnnamedMangle - 1);
-      Out << '_';
-      break;
-    }
-
-    // Get a unique id for the anonymous struct.
-    uint64_t AnonStructId = Context.getAnonymousStructId(TD);
-
-    // Mangle it as a source name in the form
-    // [n] $_<id>
-    // where n is the length of the string.
-    SmallString<8> Str;
-    Str += "$_";
-    Str += llvm::utostr(AnonStructId);
-
-    Out << Str.size();
-    Out << Str.str();
-    break;
-  }
-
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-    llvm_unreachable("Can't mangle Objective-C selector names here!");
-
-  case DeclarationName::CXXConstructorName:
-    if (ND == Structor)
-      // If the named decl is the C++ constructor we're mangling, use the type
-      // we were given.
-      mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
-    else
-      // Otherwise, use the complete constructor name. This is relevant if a
-      // class with a constructor is declared within a constructor.
-      mangleCXXCtorType(Ctor_Complete);
-    break;
-
-  case DeclarationName::CXXDestructorName:
-    if (ND == Structor)
-      // If the named decl is the C++ destructor we're mangling, use the type we
-      // were given.
-      mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
-    else
-      // Otherwise, use the complete destructor name. This is relevant if a
-      // class with a destructor is declared within a destructor.
-      mangleCXXDtorType(Dtor_Complete);
-    break;
-
-  case DeclarationName::CXXConversionFunctionName:
-    // <operator-name> ::= cv <type>    # (cast)
-    Out << "cv";
-    mangleType(Name.getCXXNameType());
-    break;
-
-  case DeclarationName::CXXOperatorName: {
-    unsigned Arity;
-    if (ND) {
-      Arity = cast<FunctionDecl>(ND)->getNumParams();
-
-      // If we have a C++ member function, we need to include the 'this' pointer.
-      // FIXME: This does not make sense for operators that are static, but their
-      // names stay the same regardless of the arity (operator new for instance).
-      if (isa<CXXMethodDecl>(ND))
-        Arity++;
-    } else
-      Arity = KnownArity;
-
-    mangleOperatorName(Name.getCXXOverloadedOperator(), Arity);
-    break;
-  }
-
-  case DeclarationName::CXXLiteralOperatorName:
-    // FIXME: This mangling is not yet official.
-    Out << "li";
-    mangleSourceName(Name.getCXXLiteralIdentifier());
-    break;
-
-  case DeclarationName::CXXUsingDirective:
-    llvm_unreachable("Can't mangle a using directive name!");
-  }
-}
-
-void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
-  // <source-name> ::= <positive length number> <identifier>
-  // <number> ::= [n] <non-negative decimal integer>
-  // <identifier> ::= <unqualified source code identifier>
-  Out << II->getLength() << II->getName();
-}
-
-void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
-                                      const DeclContext *DC,
-                                      bool NoFunction) {
-  // <nested-name> 
-  //   ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
-  //   ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> 
-  //       <template-args> E
-
-  Out << 'N';
-  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND)) {
-    mangleQualifiers(Qualifiers::fromCVRMask(Method->getTypeQualifiers()));
-    mangleRefQualifier(Method->getRefQualifier());
-  }
-  
-  // Check if we have a template.
-  const TemplateArgumentList *TemplateArgs = 0;
-  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
-    mangleTemplatePrefix(TD);
-    mangleTemplateArgs(*TemplateArgs);
-  }
-  else {
-    manglePrefix(DC, NoFunction);
-    mangleUnqualifiedName(ND);
-  }
-
-  Out << 'E';
-}
-void CXXNameMangler::mangleNestedName(const TemplateDecl *TD,
-                                      const TemplateArgument *TemplateArgs,
-                                      unsigned NumTemplateArgs) {
-  // <nested-name> ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
-
-  Out << 'N';
-
-  mangleTemplatePrefix(TD);
-  mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
-
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
-  // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
-  //              := Z <function encoding> E s [<discriminator>]
-  // <local-name> := Z <function encoding> E d [ <parameter number> ] 
-  //                 _ <entity name>
-  // <discriminator> := _ <non-negative number>
-  const DeclContext *DC = getEffectiveDeclContext(ND);
-  if (isa<ObjCMethodDecl>(DC) && isa<FunctionDecl>(ND)) {
-    // Don't add objc method name mangling to locally declared function
-    mangleUnqualifiedName(ND);
-    return;
-  }
-
-  Out << 'Z';
-
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
-   mangleObjCMethodName(MD);
-  } else if (const CXXRecordDecl *RD = GetLocalClassDecl(ND)) {
-    mangleFunctionEncoding(cast<FunctionDecl>(getEffectiveDeclContext(RD)));
-    Out << 'E';
-
-    // The parameter number is omitted for the last parameter, 0 for the 
-    // second-to-last parameter, 1 for the third-to-last parameter, etc. The 
-    // <entity name> will of course contain a <closure-type-name>: Its 
-    // numbering will be local to the particular argument in which it appears
-    // -- other default arguments do not affect its encoding.
-    bool SkipDiscriminator = false;
-    if (RD->isLambda()) {
-      if (const ParmVarDecl *Parm
-                 = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl())) {
-        if (const FunctionDecl *Func
-              = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
-          Out << 'd';
-          unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex();
-          if (Num > 1)
-            mangleNumber(Num - 2);
-          Out << '_';
-          SkipDiscriminator = true;
-        }
-      }
-    }
-    
-    // Mangle the name relative to the closest enclosing function.
-    if (ND == RD) // equality ok because RD derived from ND above
-      mangleUnqualifiedName(ND);
-    else
-      mangleNestedName(ND, DC, true /*NoFunction*/);
-
-    if (!SkipDiscriminator) {
-      unsigned disc;
-      if (Context.getNextDiscriminator(RD, disc)) {
-        if (disc < 10)
-          Out << '_' << disc;
-        else
-          Out << "__" << disc << '_';
-      }
-    }
-    
-    return;
-  }
-  else
-    mangleFunctionEncoding(cast<FunctionDecl>(DC));
-
-  Out << 'E';
-  mangleUnqualifiedName(ND);
-}
-
-void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
-  // If the context of a closure type is an initializer for a class member 
-  // (static or nonstatic), it is encoded in a qualified name with a final 
-  // <prefix> of the form:
-  //
-  //   <data-member-prefix> := <member source-name> M
-  //
-  // Technically, the data-member-prefix is part of the <prefix>. However,
-  // since a closure type will always be mangled with a prefix, it's easier
-  // to emit that last part of the prefix here.
-  if (Decl *Context = Lambda->getLambdaContextDecl()) {
-    if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
-        Context->getDeclContext()->isRecord()) {
-      if (const IdentifierInfo *Name
-            = cast<NamedDecl>(Context)->getIdentifier()) {
-        mangleSourceName(Name);
-        Out << 'M';            
-      }
-    }
-  }
-
-  Out << "Ul";
-  const FunctionProtoType *Proto = Lambda->getLambdaTypeInfo()->getType()->
-                                   getAs<FunctionProtoType>();
-  mangleBareFunctionType(Proto, /*MangleReturnType=*/false);        
-  Out << "E";
-  
-  // The number is omitted for the first closure type with a given 
-  // <lambda-sig> in a given context; it is n-2 for the nth closure type 
-  // (in lexical order) with that same <lambda-sig> and context.
-  //
-  // The AST keeps track of the number for us.
-  unsigned Number = Lambda->getLambdaManglingNumber();
-  assert(Number > 0 && "Lambda should be mangled as an unnamed class");
-  if (Number > 1)
-    mangleNumber(Number - 2);
-  Out << '_';  
-}
-
-void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
-  switch (qualifier->getKind()) {
-  case NestedNameSpecifier::Global:
-    // nothing
-    return;
-
-  case NestedNameSpecifier::Namespace:
-    mangleName(qualifier->getAsNamespace());
-    return;
-
-  case NestedNameSpecifier::NamespaceAlias:
-    mangleName(qualifier->getAsNamespaceAlias()->getNamespace());
-    return;
-
-  case NestedNameSpecifier::TypeSpec:
-  case NestedNameSpecifier::TypeSpecWithTemplate:
-    manglePrefix(QualType(qualifier->getAsType(), 0));
-    return;
-
-  case NestedNameSpecifier::Identifier:
-    // Member expressions can have these without prefixes, but that
-    // should end up in mangleUnresolvedPrefix instead.
-    assert(qualifier->getPrefix());
-    manglePrefix(qualifier->getPrefix());
-
-    mangleSourceName(qualifier->getAsIdentifier());
-    return;
-  }
-
-  llvm_unreachable("unexpected nested name specifier");
-}
-
-void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
-  //  <prefix> ::= <prefix> <unqualified-name>
-  //           ::= <template-prefix> <template-args>
-  //           ::= <template-param>
-  //           ::= # empty
-  //           ::= <substitution>
-
-  DC = IgnoreLinkageSpecDecls(DC);
-
-  if (DC->isTranslationUnit())
-    return;
-
-  if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
-    manglePrefix(getEffectiveParentContext(DC), NoFunction);    
-    SmallString<64> Name;
-    llvm::raw_svector_ostream NameStream(Name);
-    Context.mangleBlock(Block, NameStream);
-    NameStream.flush();
-    Out << Name.size() << Name;
-    return;
-  }
-  
-  const NamedDecl *ND = cast<NamedDecl>(DC);  
-  if (mangleSubstitution(ND))
-    return;
-  
-  // Check if we have a template.
-  const TemplateArgumentList *TemplateArgs = 0;
-  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
-    mangleTemplatePrefix(TD);
-    mangleTemplateArgs(*TemplateArgs);
-  }
-  else if(NoFunction && (isa<FunctionDecl>(ND) || isa<ObjCMethodDecl>(ND)))
-    return;
-  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
-    mangleObjCMethodName(Method);
-  else {
-    manglePrefix(getEffectiveDeclContext(ND), NoFunction);
-    mangleUnqualifiedName(ND);
-  }
-
-  addSubstitution(ND);
-}
-
-void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
-  // <template-prefix> ::= <prefix> <template unqualified-name>
-  //                   ::= <template-param>
-  //                   ::= <substitution>
-  if (TemplateDecl *TD = Template.getAsTemplateDecl())
-    return mangleTemplatePrefix(TD);
-
-  if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName())
-    manglePrefix(Qualified->getQualifier());
-  
-  if (OverloadedTemplateStorage *Overloaded
-                                      = Template.getAsOverloadedTemplate()) {
-    mangleUnqualifiedName(0, (*Overloaded->begin())->getDeclName(), 
-                          UnknownArity);
-    return;
-  }
-   
-  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
-  assert(Dependent && "Unknown template name kind?");
-  manglePrefix(Dependent->getQualifier());
-  mangleUnscopedTemplateName(Template);
-}
-
-void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
-  // <template-prefix> ::= <prefix> <template unqualified-name>
-  //                   ::= <template-param>
-  //                   ::= <substitution>
-  // <template-template-param> ::= <template-param>
-  //                               <substitution>
-
-  if (mangleSubstitution(ND))
-    return;
-
-  // <template-template-param> ::= <template-param>
-  if (const TemplateTemplateParmDecl *TTP
-                                     = dyn_cast<TemplateTemplateParmDecl>(ND)) {
-    mangleTemplateParameter(TTP->getIndex());
-    return;
-  }
-
-  manglePrefix(getEffectiveDeclContext(ND));
-  mangleUnqualifiedName(ND->getTemplatedDecl());
-  addSubstitution(ND);
-}
-
-/// Mangles a template name under the production <type>.  Required for
-/// template template arguments.
-///   <type> ::= <class-enum-type>
-///          ::= <template-param>
-///          ::= <substitution>
-void CXXNameMangler::mangleType(TemplateName TN) {
-  if (mangleSubstitution(TN))
-    return;
-      
-  TemplateDecl *TD = 0;
-
-  switch (TN.getKind()) {
-  case TemplateName::QualifiedTemplate:
-    TD = TN.getAsQualifiedTemplateName()->getTemplateDecl();
-    goto HaveDecl;
-
-  case TemplateName::Template:
-    TD = TN.getAsTemplateDecl();
-    goto HaveDecl;
-
-  HaveDecl:
-    if (isa<TemplateTemplateParmDecl>(TD))
-      mangleTemplateParameter(cast<TemplateTemplateParmDecl>(TD)->getIndex());
-    else
-      mangleName(TD);
-    break;
-
-  case TemplateName::OverloadedTemplate:
-    llvm_unreachable("can't mangle an overloaded template name as a <type>");
-
-  case TemplateName::DependentTemplate: {
-    const DependentTemplateName *Dependent = TN.getAsDependentTemplateName();
-    assert(Dependent->isIdentifier());
-
-    // <class-enum-type> ::= <name>
-    // <name> ::= <nested-name>
-    mangleUnresolvedPrefix(Dependent->getQualifier(), 0);
-    mangleSourceName(Dependent->getIdentifier());
-    break;
-  }
-
-  case TemplateName::SubstTemplateTemplateParm: {
-    // Substituted template parameters are mangled as the substituted
-    // template.  This will check for the substitution twice, which is
-    // fine, but we have to return early so that we don't try to *add*
-    // the substitution twice.
-    SubstTemplateTemplateParmStorage *subst
-      = TN.getAsSubstTemplateTemplateParm();
-    mangleType(subst->getReplacement());
-    return;
-  }
-
-  case TemplateName::SubstTemplateTemplateParmPack: {
-    // FIXME: not clear how to mangle this!
-    // template <template <class> class T...> class A {
-    //   template <template <class> class U...> void foo(B<T,U> x...);
-    // };
-    Out << "_SUBSTPACK_";
-    break;
-  }
-  }
-
-  addSubstitution(TN);
-}
-
-void
-CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
-  switch (OO) {
-  // <operator-name> ::= nw     # new
-  case OO_New: Out << "nw"; break;
-  //              ::= na        # new[]
-  case OO_Array_New: Out << "na"; break;
-  //              ::= dl        # delete
-  case OO_Delete: Out << "dl"; break;
-  //              ::= da        # delete[]
-  case OO_Array_Delete: Out << "da"; break;
-  //              ::= ps        # + (unary)
-  //              ::= pl        # + (binary or unknown)
-  case OO_Plus:
-    Out << (Arity == 1? "ps" : "pl"); break;
-  //              ::= ng        # - (unary)
-  //              ::= mi        # - (binary or unknown)
-  case OO_Minus:
-    Out << (Arity == 1? "ng" : "mi"); break;
-  //              ::= ad        # & (unary)
-  //              ::= an        # & (binary or unknown)
-  case OO_Amp:
-    Out << (Arity == 1? "ad" : "an"); break;
-  //              ::= de        # * (unary)
-  //              ::= ml        # * (binary or unknown)
-  case OO_Star:
-    // Use binary when unknown.
-    Out << (Arity == 1? "de" : "ml"); break;
-  //              ::= co        # ~
-  case OO_Tilde: Out << "co"; break;
-  //              ::= dv        # /
-  case OO_Slash: Out << "dv"; break;
-  //              ::= rm        # %
-  case OO_Percent: Out << "rm"; break;
-  //              ::= or        # |
-  case OO_Pipe: Out << "or"; break;
-  //              ::= eo        # ^
-  case OO_Caret: Out << "eo"; break;
-  //              ::= aS        # =
-  case OO_Equal: Out << "aS"; break;
-  //              ::= pL        # +=
-  case OO_PlusEqual: Out << "pL"; break;
-  //              ::= mI        # -=
-  case OO_MinusEqual: Out << "mI"; break;
-  //              ::= mL        # *=
-  case OO_StarEqual: Out << "mL"; break;
-  //              ::= dV        # /=
-  case OO_SlashEqual: Out << "dV"; break;
-  //              ::= rM        # %=
-  case OO_PercentEqual: Out << "rM"; break;
-  //              ::= aN        # &=
-  case OO_AmpEqual: Out << "aN"; break;
-  //              ::= oR        # |=
-  case OO_PipeEqual: Out << "oR"; break;
-  //              ::= eO        # ^=
-  case OO_CaretEqual: Out << "eO"; break;
-  //              ::= ls        # <<
-  case OO_LessLess: Out << "ls"; break;
-  //              ::= rs        # >>
-  case OO_GreaterGreater: Out << "rs"; break;
-  //              ::= lS        # <<=
-  case OO_LessLessEqual: Out << "lS"; break;
-  //              ::= rS        # >>=
-  case OO_GreaterGreaterEqual: Out << "rS"; break;
-  //              ::= eq        # ==
-  case OO_EqualEqual: Out << "eq"; break;
-  //              ::= ne        # !=
-  case OO_ExclaimEqual: Out << "ne"; break;
-  //              ::= lt        # <
-  case OO_Less: Out << "lt"; break;
-  //              ::= gt        # >
-  case OO_Greater: Out << "gt"; break;
-  //              ::= le        # <=
-  case OO_LessEqual: Out << "le"; break;
-  //              ::= ge        # >=
-  case OO_GreaterEqual: Out << "ge"; break;
-  //              ::= nt        # !
-  case OO_Exclaim: Out << "nt"; break;
-  //              ::= aa        # &&
-  case OO_AmpAmp: Out << "aa"; break;
-  //              ::= oo        # ||
-  case OO_PipePipe: Out << "oo"; break;
-  //              ::= pp        # ++
-  case OO_PlusPlus: Out << "pp"; break;
-  //              ::= mm        # --
-  case OO_MinusMinus: Out << "mm"; break;
-  //              ::= cm        # ,
-  case OO_Comma: Out << "cm"; break;
-  //              ::= pm        # ->*
-  case OO_ArrowStar: Out << "pm"; break;
-  //              ::= pt        # ->
-  case OO_Arrow: Out << "pt"; break;
-  //              ::= cl        # ()
-  case OO_Call: Out << "cl"; break;
-  //              ::= ix        # []
-  case OO_Subscript: Out << "ix"; break;
-
-  //              ::= qu        # ?
-  // The conditional operator can't be overloaded, but we still handle it when
-  // mangling expressions.
-  case OO_Conditional: Out << "qu"; break;
-
-  case OO_None:
-  case NUM_OVERLOADED_OPERATORS:
-    llvm_unreachable("Not an overloaded operator");
-  }
-}
-
-void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
-  // <CV-qualifiers> ::= [r] [V] [K]    # restrict (C99), volatile, const
-  if (Quals.hasRestrict())
-    Out << 'r';
-  if (Quals.hasVolatile())
-    Out << 'V';
-  if (Quals.hasConst())
-    Out << 'K';
-
-  if (Quals.hasAddressSpace()) {
-    // Extension:
-    //
-    //   <type> ::= U <address-space-number>
-    // 
-    // where <address-space-number> is a source name consisting of 'AS' 
-    // followed by the address space <number>.
-    SmallString<64> ASString;
-    ASString = "AS" + llvm::utostr_32(Quals.getAddressSpace());
-    Out << 'U' << ASString.size() << ASString;
-  }
-  
-  StringRef LifetimeName;
-  switch (Quals.getObjCLifetime()) {
-  // Objective-C ARC Extension:
-  //
-  //   <type> ::= U "__strong"
-  //   <type> ::= U "__weak"
-  //   <type> ::= U "__autoreleasing"
-  case Qualifiers::OCL_None:
-    break;
-    
-  case Qualifiers::OCL_Weak:
-    LifetimeName = "__weak";
-    break;
-    
-  case Qualifiers::OCL_Strong:
-    LifetimeName = "__strong";
-    break;
-    
-  case Qualifiers::OCL_Autoreleasing:
-    LifetimeName = "__autoreleasing";
-    break;
-    
-  case Qualifiers::OCL_ExplicitNone:
-    // The __unsafe_unretained qualifier is *not* mangled, so that
-    // __unsafe_unretained types in ARC produce the same manglings as the
-    // equivalent (but, naturally, unqualified) types in non-ARC, providing
-    // better ABI compatibility.
-    //
-    // It's safe to do this because unqualified 'id' won't show up
-    // in any type signatures that need to be mangled.
-    break;
-  }
-  if (!LifetimeName.empty())
-    Out << 'U' << LifetimeName.size() << LifetimeName;
-}
-
-void CXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
-  // <ref-qualifier> ::= R                # lvalue reference
-  //                 ::= O                # rvalue-reference
-  // Proposal to Itanium C++ ABI list on 1/26/11
-  switch (RefQualifier) {
-  case RQ_None:
-    break;
-      
-  case RQ_LValue:
-    Out << 'R';
-    break;
-      
-  case RQ_RValue:
-    Out << 'O';
-    break;
-  }
-}
-
-void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
-  Context.mangleObjCMethodName(MD, Out);
-}
-
-void CXXNameMangler::mangleType(QualType T) {
-  // If our type is instantiation-dependent but not dependent, we mangle
-  // it as it was written in the source, removing any top-level sugar. 
-  // Otherwise, use the canonical type.
-  //
-  // FIXME: This is an approximation of the instantiation-dependent name 
-  // mangling rules, since we should really be using the type as written and
-  // augmented via semantic analysis (i.e., with implicit conversions and
-  // default template arguments) for any instantiation-dependent type. 
-  // Unfortunately, that requires several changes to our AST:
-  //   - Instantiation-dependent TemplateSpecializationTypes will need to be 
-  //     uniqued, so that we can handle substitutions properly
-  //   - Default template arguments will need to be represented in the
-  //     TemplateSpecializationType, since they need to be mangled even though
-  //     they aren't written.
-  //   - Conversions on non-type template arguments need to be expressed, since
-  //     they can affect the mangling of sizeof/alignof.
-  if (!T->isInstantiationDependentType() || T->isDependentType())
-    T = T.getCanonicalType();
-  else {
-    // Desugar any types that are purely sugar.
-    do {
-      // Don't desugar through template specialization types that aren't
-      // type aliases. We need to mangle the template arguments as written.
-      if (const TemplateSpecializationType *TST 
-                                      = dyn_cast<TemplateSpecializationType>(T))
-        if (!TST->isTypeAlias())
-          break;
-
-      QualType Desugared 
-        = T.getSingleStepDesugaredType(Context.getASTContext());
-      if (Desugared == T)
-        break;
-      
-      T = Desugared;
-    } while (true);
-  }
-  SplitQualType split = T.split();
-  Qualifiers quals = split.Quals;
-  const Type *ty = split.Ty;
-
-  bool isSubstitutable = quals || !isa<BuiltinType>(T);
-  if (isSubstitutable && mangleSubstitution(T))
-    return;
-
-  // If we're mangling a qualified array type, push the qualifiers to
-  // the element type.
-  if (quals && isa<ArrayType>(T)) {
-    ty = Context.getASTContext().getAsArrayType(T);
-    quals = Qualifiers();
-
-    // Note that we don't update T: we want to add the
-    // substitution at the original type.
-  }
-
-  if (quals) {
-    mangleQualifiers(quals);
-    // Recurse:  even if the qualified type isn't yet substitutable,
-    // the unqualified type might be.
-    mangleType(QualType(ty, 0));
-  } else {
-    switch (ty->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define NON_CANONICAL_TYPE(CLASS, PARENT) \
-    case Type::CLASS: \
-      llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
-      return;
-#define TYPE(CLASS, PARENT) \
-    case Type::CLASS: \
-      mangleType(static_cast<const CLASS##Type*>(ty)); \
-      break;
-#include "clang/AST/TypeNodes.def"
-    }
-  }
-
-  // Add the substitution.
-  if (isSubstitutable)
-    addSubstitution(T);
-}
-
-void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
-  if (!mangleStandardSubstitution(ND))
-    mangleName(ND);
-}
-
-void CXXNameMangler::mangleType(const BuiltinType *T) {
-  //  <type>         ::= <builtin-type>
-  //  <builtin-type> ::= v  # void
-  //                 ::= w  # wchar_t
-  //                 ::= b  # bool
-  //                 ::= c  # char
-  //                 ::= a  # signed char
-  //                 ::= h  # unsigned char
-  //                 ::= s  # short
-  //                 ::= t  # unsigned short
-  //                 ::= i  # int
-  //                 ::= j  # unsigned int
-  //                 ::= l  # long
-  //                 ::= m  # unsigned long
-  //                 ::= x  # long long, __int64
-  //                 ::= y  # unsigned long long, __int64
-  //                 ::= n  # __int128
-  // UNSUPPORTED:    ::= o  # unsigned __int128
-  //                 ::= f  # float
-  //                 ::= d  # double
-  //                 ::= e  # long double, __float80
-  // UNSUPPORTED:    ::= g  # __float128
-  // UNSUPPORTED:    ::= Dd # IEEE 754r decimal floating point (64 bits)
-  // UNSUPPORTED:    ::= De # IEEE 754r decimal floating point (128 bits)
-  // UNSUPPORTED:    ::= Df # IEEE 754r decimal floating point (32 bits)
-  //                 ::= Dh # IEEE 754r half-precision floating point (16 bits)
-  //                 ::= Di # char32_t
-  //                 ::= Ds # char16_t
-  //                 ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
-  //                 ::= u <source-name>    # vendor extended type
-  switch (T->getKind()) {
-  case BuiltinType::Void: Out << 'v'; break;
-  case BuiltinType::Bool: Out << 'b'; break;
-  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
-  case BuiltinType::UChar: Out << 'h'; break;
-  case BuiltinType::UShort: Out << 't'; break;
-  case BuiltinType::UInt: Out << 'j'; break;
-  case BuiltinType::ULong: Out << 'm'; break;
-  case BuiltinType::ULongLong: Out << 'y'; break;
-  case BuiltinType::UInt128: Out << 'o'; break;
-  case BuiltinType::SChar: Out << 'a'; break;
-  case BuiltinType::WChar_S:
-  case BuiltinType::WChar_U: Out << 'w'; break;
-  case BuiltinType::Char16: Out << "Ds"; break;
-  case BuiltinType::Char32: Out << "Di"; break;
-  case BuiltinType::Short: Out << 's'; break;
-  case BuiltinType::Int: Out << 'i'; break;
-  case BuiltinType::Long: Out << 'l'; break;
-  case BuiltinType::LongLong: Out << 'x'; break;
-  case BuiltinType::Int128: Out << 'n'; break;
-  case BuiltinType::Half: Out << "Dh"; break;
-  case BuiltinType::Float: Out << 'f'; break;
-  case BuiltinType::Double: Out << 'd'; break;
-  case BuiltinType::LongDouble: Out << 'e'; break;
-  case BuiltinType::NullPtr: Out << "Dn"; break;
-
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-  case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-  case BuiltinType::Dependent:
-    llvm_unreachable("mangling a placeholder type");
-  case BuiltinType::ObjCId: Out << "11objc_object"; break;
-  case BuiltinType::ObjCClass: Out << "10objc_class"; break;
-  case BuiltinType::ObjCSel: Out << "13objc_selector"; break;
-  }
-}
-
-// <type>          ::= <function-type>
-// <function-type> ::= [<CV-qualifiers>] F [Y]
-//                      <bare-function-type> [<ref-qualifier>] E
-// (Proposal to cxx-abi-dev, 2012-05-11)
-void CXXNameMangler::mangleType(const FunctionProtoType *T) {
-  // Mangle CV-qualifiers, if present.  These are 'this' qualifiers,
-  // e.g. "const" in "int (A::*)() const".
-  mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals()));
-
-  Out << 'F';
-
-  // FIXME: We don't have enough information in the AST to produce the 'Y'
-  // encoding for extern "C" function types.
-  mangleBareFunctionType(T, /*MangleReturnType=*/true);
-
-  // Mangle the ref-qualifier, if present.
-  mangleRefQualifier(T->getRefQualifier());
-
-  Out << 'E';
-}
-void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
-  llvm_unreachable("Can't mangle K&R function prototypes");
-}
-void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
-                                            bool MangleReturnType) {
-  // We should never be mangling something without a prototype.
-  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
-
-  // Record that we're in a function type.  See mangleFunctionParam
-  // for details on what we're trying to achieve here.
-  FunctionTypeDepthState saved = FunctionTypeDepth.push();
-
-  // <bare-function-type> ::= <signature type>+
-  if (MangleReturnType) {
-    FunctionTypeDepth.enterResultType();
-    mangleType(Proto->getResultType());
-    FunctionTypeDepth.leaveResultType();
-  }
-
-  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
-    //   <builtin-type> ::= v   # void
-    Out << 'v';
-
-    FunctionTypeDepth.pop(saved);
-    return;
-  }
-
-  for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
-                                         ArgEnd = Proto->arg_type_end();
-       Arg != ArgEnd; ++Arg)
-    mangleType(Context.getASTContext().getSignatureParameterType(*Arg));
-
-  FunctionTypeDepth.pop(saved);
-
-  // <builtin-type>      ::= z  # ellipsis
-  if (Proto->isVariadic())
-    Out << 'z';
-}
-
-// <type>            ::= <class-enum-type>
-// <class-enum-type> ::= <name>
-void CXXNameMangler::mangleType(const UnresolvedUsingType *T) {
-  mangleName(T->getDecl());
-}
-
-// <type>            ::= <class-enum-type>
-// <class-enum-type> ::= <name>
-void CXXNameMangler::mangleType(const EnumType *T) {
-  mangleType(static_cast<const TagType*>(T));
-}
-void CXXNameMangler::mangleType(const RecordType *T) {
-  mangleType(static_cast<const TagType*>(T));
-}
-void CXXNameMangler::mangleType(const TagType *T) {
-  mangleName(T->getDecl());
-}
-
-// <type>       ::= <array-type>
-// <array-type> ::= A <positive dimension number> _ <element type>
-//              ::= A [<dimension expression>] _ <element type>
-void CXXNameMangler::mangleType(const ConstantArrayType *T) {
-  Out << 'A' << T->getSize() << '_';
-  mangleType(T->getElementType());
-}
-void CXXNameMangler::mangleType(const VariableArrayType *T) {
-  Out << 'A';
-  // decayed vla types (size 0) will just be skipped.
-  if (T->getSizeExpr())
-    mangleExpression(T->getSizeExpr());
-  Out << '_';
-  mangleType(T->getElementType());
-}
-void CXXNameMangler::mangleType(const DependentSizedArrayType *T) {
-  Out << 'A';
-  mangleExpression(T->getSizeExpr());
-  Out << '_';
-  mangleType(T->getElementType());
-}
-void CXXNameMangler::mangleType(const IncompleteArrayType *T) {
-  Out << "A_";
-  mangleType(T->getElementType());
-}
-
-// <type>                   ::= <pointer-to-member-type>
-// <pointer-to-member-type> ::= M <class type> <member type>
-void CXXNameMangler::mangleType(const MemberPointerType *T) {
-  Out << 'M';
-  mangleType(QualType(T->getClass(), 0));
-  QualType PointeeType = T->getPointeeType();
-  if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
-    mangleType(FPT);
-    
-    // Itanium C++ ABI 5.1.8:
-    //
-    //   The type of a non-static member function is considered to be different,
-    //   for the purposes of substitution, from the type of a namespace-scope or
-    //   static member function whose type appears similar. The types of two
-    //   non-static member functions are considered to be different, for the
-    //   purposes of substitution, if the functions are members of different
-    //   classes. In other words, for the purposes of substitution, the class of 
-    //   which the function is a member is considered part of the type of 
-    //   function.
-
-    // Given that we already substitute member function pointers as a
-    // whole, the net effect of this rule is just to unconditionally
-    // suppress substitution on the function type in a member pointer.
-    // We increment the SeqID here to emulate adding an entry to the
-    // substitution table.
-    ++SeqID;
-  } else
-    mangleType(PointeeType);
-}
-
-// <type>           ::= <template-param>
-void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
-  mangleTemplateParameter(T->getIndex());
-}
-
-// <type>           ::= <template-param>
-void CXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T) {
-  // FIXME: not clear how to mangle this!
-  // template <class T...> class A {
-  //   template <class U...> void foo(T(*)(U) x...);
-  // };
-  Out << "_SUBSTPACK_";
-}
-
-// <type> ::= P <type>   # pointer-to
-void CXXNameMangler::mangleType(const PointerType *T) {
-  Out << 'P';
-  mangleType(T->getPointeeType());
-}
-void CXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
-  Out << 'P';
-  mangleType(T->getPointeeType());
-}
-
-// <type> ::= R <type>   # reference-to
-void CXXNameMangler::mangleType(const LValueReferenceType *T) {
-  Out << 'R';
-  mangleType(T->getPointeeType());
-}
-
-// <type> ::= O <type>   # rvalue reference-to (C++0x)
-void CXXNameMangler::mangleType(const RValueReferenceType *T) {
-  Out << 'O';
-  mangleType(T->getPointeeType());
-}
-
-// <type> ::= C <type>   # complex pair (C 2000)
-void CXXNameMangler::mangleType(const ComplexType *T) {
-  Out << 'C';
-  mangleType(T->getElementType());
-}
-
-// ARM's ABI for Neon vector types specifies that they should be mangled as
-// if they are structs (to match ARM's initial implementation).  The
-// vector type must be one of the special types predefined by ARM.
-void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
-  QualType EltType = T->getElementType();
-  assert(EltType->isBuiltinType() && "Neon vector element not a BuiltinType");
-  const char *EltName = 0;
-  if (T->getVectorKind() == VectorType::NeonPolyVector) {
-    switch (cast<BuiltinType>(EltType)->getKind()) {
-    case BuiltinType::SChar:     EltName = "poly8_t"; break;
-    case BuiltinType::Short:     EltName = "poly16_t"; break;
-    default: llvm_unreachable("unexpected Neon polynomial vector element type");
-    }
-  } else {
-    switch (cast<BuiltinType>(EltType)->getKind()) {
-    case BuiltinType::SChar:     EltName = "int8_t"; break;
-    case BuiltinType::UChar:     EltName = "uint8_t"; break;
-    case BuiltinType::Short:     EltName = "int16_t"; break;
-    case BuiltinType::UShort:    EltName = "uint16_t"; break;
-    case BuiltinType::Int:       EltName = "int32_t"; break;
-    case BuiltinType::UInt:      EltName = "uint32_t"; break;
-    case BuiltinType::LongLong:  EltName = "int64_t"; break;
-    case BuiltinType::ULongLong: EltName = "uint64_t"; break;
-    case BuiltinType::Float:     EltName = "float32_t"; break;
-    default: llvm_unreachable("unexpected Neon vector element type");
-    }
-  }
-  const char *BaseName = 0;
-  unsigned BitSize = (T->getNumElements() *
-                      getASTContext().getTypeSize(EltType));
-  if (BitSize == 64)
-    BaseName = "__simd64_";
-  else {
-    assert(BitSize == 128 && "Neon vector type not 64 or 128 bits");
-    BaseName = "__simd128_";
-  }
-  Out << strlen(BaseName) + strlen(EltName);
-  Out << BaseName << EltName;
-}
-
-// GNU extension: vector types
-// <type>                  ::= <vector-type>
-// <vector-type>           ::= Dv <positive dimension number> _
-//                                    <extended element type>
-//                         ::= Dv [<dimension expression>] _ <element type>
-// <extended element type> ::= <element type>
-//                         ::= p # AltiVec vector pixel
-//                         ::= b # Altivec vector bool
-void CXXNameMangler::mangleType(const VectorType *T) {
-  if ((T->getVectorKind() == VectorType::NeonVector ||
-       T->getVectorKind() == VectorType::NeonPolyVector)) {
-    mangleNeonVectorType(T);
-    return;
-  }
-  Out << "Dv" << T->getNumElements() << '_';
-  if (T->getVectorKind() == VectorType::AltiVecPixel)
-    Out << 'p';
-  else if (T->getVectorKind() == VectorType::AltiVecBool)
-    Out << 'b';
-  else
-    mangleType(T->getElementType());
-}
-void CXXNameMangler::mangleType(const ExtVectorType *T) {
-  mangleType(static_cast<const VectorType*>(T));
-}
-void CXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
-  Out << "Dv";
-  mangleExpression(T->getSizeExpr());
-  Out << '_';
-  mangleType(T->getElementType());
-}
-
-void CXXNameMangler::mangleType(const PackExpansionType *T) {
-  // <type>  ::= Dp <type>          # pack expansion (C++0x)
-  Out << "Dp";
-  mangleType(T->getPattern());
-}
-
-void CXXNameMangler::mangleType(const ObjCInterfaceType *T) {
-  mangleSourceName(T->getDecl()->getIdentifier());
-}
-
-void CXXNameMangler::mangleType(const ObjCObjectType *T) {
-  // We don't allow overloading by different protocol qualification,
-  // so mangling them isn't necessary.
-  mangleType(T->getBaseType());
-}
-
-void CXXNameMangler::mangleType(const BlockPointerType *T) {
-  Out << "U13block_pointer";
-  mangleType(T->getPointeeType());
-}
-
-void CXXNameMangler::mangleType(const InjectedClassNameType *T) {
-  // Mangle injected class name types as if the user had written the
-  // specialization out fully.  It may not actually be possible to see
-  // this mangling, though.
-  mangleType(T->getInjectedSpecializationType());
-}
-
-void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
-  if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) {
-    mangleName(TD, T->getArgs(), T->getNumArgs());
-  } else {
-    if (mangleSubstitution(QualType(T, 0)))
-      return;
-    
-    mangleTemplatePrefix(T->getTemplateName());
-    
-    // FIXME: GCC does not appear to mangle the template arguments when
-    // the template in question is a dependent template name. Should we
-    // emulate that badness?
-    mangleTemplateArgs(T->getArgs(), T->getNumArgs());
-    addSubstitution(QualType(T, 0));
-  }
-}
-
-void CXXNameMangler::mangleType(const DependentNameType *T) {
-  // Typename types are always nested
-  Out << 'N';
-  manglePrefix(T->getQualifier());
-  mangleSourceName(T->getIdentifier());    
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
-  // Dependently-scoped template types are nested if they have a prefix.
-  Out << 'N';
-
-  // TODO: avoid making this TemplateName.
-  TemplateName Prefix =
-    getASTContext().getDependentTemplateName(T->getQualifier(),
-                                             T->getIdentifier());
-  mangleTemplatePrefix(Prefix);
-
-  // FIXME: GCC does not appear to mangle the template arguments when
-  // the template in question is a dependent template name. Should we
-  // emulate that badness?
-  mangleTemplateArgs(T->getArgs(), T->getNumArgs());    
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleType(const TypeOfType *T) {
-  // FIXME: this is pretty unsatisfactory, but there isn't an obvious
-  // "extension with parameters" mangling.
-  Out << "u6typeof";
-}
-
-void CXXNameMangler::mangleType(const TypeOfExprType *T) {
-  // FIXME: this is pretty unsatisfactory, but there isn't an obvious
-  // "extension with parameters" mangling.
-  Out << "u6typeof";
-}
-
-void CXXNameMangler::mangleType(const DecltypeType *T) {
-  Expr *E = T->getUnderlyingExpr();
-
-  // type ::= Dt <expression> E  # decltype of an id-expression
-  //                             #   or class member access
-  //      ::= DT <expression> E  # decltype of an expression
-
-  // This purports to be an exhaustive list of id-expressions and
-  // class member accesses.  Note that we do not ignore parentheses;
-  // parentheses change the semantics of decltype for these
-  // expressions (and cause the mangler to use the other form).
-  if (isa<DeclRefExpr>(E) ||
-      isa<MemberExpr>(E) ||
-      isa<UnresolvedLookupExpr>(E) ||
-      isa<DependentScopeDeclRefExpr>(E) ||
-      isa<CXXDependentScopeMemberExpr>(E) ||
-      isa<UnresolvedMemberExpr>(E))
-    Out << "Dt";
-  else
-    Out << "DT";
-  mangleExpression(E);
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleType(const UnaryTransformType *T) {
-  // If this is dependent, we need to record that. If not, we simply
-  // mangle it as the underlying type since they are equivalent.
-  if (T->isDependentType()) {
-    Out << 'U';
-    
-    switch (T->getUTTKind()) {
-      case UnaryTransformType::EnumUnderlyingType:
-        Out << "3eut";
-        break;
-    }
-  }
-
-  mangleType(T->getUnderlyingType());
-}
-
-void CXXNameMangler::mangleType(const AutoType *T) {
-  QualType D = T->getDeducedType();
-  // <builtin-type> ::= Da  # dependent auto
-  if (D.isNull())
-    Out << "Da";
-  else
-    mangleType(D);
-}
-
-void CXXNameMangler::mangleType(const AtomicType *T) {
-  // <type> ::= U <source-name> <type>	# vendor extended type qualifier
-  // (Until there's a standardized mangling...)
-  Out << "U7_Atomic";
-  mangleType(T->getValueType());
-}
-
-void CXXNameMangler::mangleIntegerLiteral(QualType T,
-                                          const llvm::APSInt &Value) {
-  //  <expr-primary> ::= L <type> <value number> E # integer literal
-  Out << 'L';
-
-  mangleType(T);
-  if (T->isBooleanType()) {
-    // Boolean values are encoded as 0/1.
-    Out << (Value.getBoolValue() ? '1' : '0');
-  } else {
-    mangleNumber(Value);
-  }
-  Out << 'E';
-
-}
-
-/// Mangles a member expression.
-void CXXNameMangler::mangleMemberExpr(const Expr *base,
-                                      bool isArrow,
-                                      NestedNameSpecifier *qualifier,
-                                      NamedDecl *firstQualifierLookup,
-                                      DeclarationName member,
-                                      unsigned arity) {
-  // <expression> ::= dt <expression> <unresolved-name>
-  //              ::= pt <expression> <unresolved-name>
-  if (base) {
-    if (base->isImplicitCXXThis()) {
-      // Note: GCC mangles member expressions to the implicit 'this' as
-      // *this., whereas we represent them as this->. The Itanium C++ ABI
-      // does not specify anything here, so we follow GCC.
-      Out << "dtdefpT";
-    } else {
-      Out << (isArrow ? "pt" : "dt");
-      mangleExpression(base);
-    }
-  }
-  mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity);
-}
-
-/// Look at the callee of the given call expression and determine if
-/// it's a parenthesized id-expression which would have triggered ADL
-/// otherwise.
-static bool isParenthesizedADLCallee(const CallExpr *call) {
-  const Expr *callee = call->getCallee();
-  const Expr *fn = callee->IgnoreParens();
-
-  // Must be parenthesized.  IgnoreParens() skips __extension__ nodes,
-  // too, but for those to appear in the callee, it would have to be
-  // parenthesized.
-  if (callee == fn) return false;
-
-  // Must be an unresolved lookup.
-  const UnresolvedLookupExpr *lookup = dyn_cast<UnresolvedLookupExpr>(fn);
-  if (!lookup) return false;
-
-  assert(!lookup->requiresADL());
-
-  // Must be an unqualified lookup.
-  if (lookup->getQualifier()) return false;
-
-  // Must not have found a class member.  Note that if one is a class
-  // member, they're all class members.
-  if (lookup->getNumDecls() > 0 &&
-      (*lookup->decls_begin())->isCXXClassMember())
-    return false;
-
-  // Otherwise, ADL would have been triggered.
-  return true;
-}
-
-void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
-  // <expression> ::= <unary operator-name> <expression>
-  //              ::= <binary operator-name> <expression> <expression>
-  //              ::= <trinary operator-name> <expression> <expression> <expression>
-  //              ::= cv <type> expression           # conversion with one argument
-  //              ::= cv <type> _ <expression>* E # conversion with a different number of arguments
-  //              ::= st <type>                      # sizeof (a type)
-  //              ::= at <type>                      # alignof (a type)
-  //              ::= <template-param>
-  //              ::= <function-param>
-  //              ::= sr <type> <unqualified-name>                   # dependent name
-  //              ::= sr <type> <unqualified-name> <template-args>   # dependent template-id
-  //              ::= ds <expression> <expression>                   # expr.*expr
-  //              ::= sZ <template-param>                            # size of a parameter pack
-  //              ::= sZ <function-param>    # size of a function parameter pack
-  //              ::= <expr-primary>
-  // <expr-primary> ::= L <type> <value number> E    # integer literal
-  //                ::= L <type <value float> E      # floating literal
-  //                ::= L <mangled-name> E           # external name
-  //                ::= fpT                          # 'this' expression
-  QualType ImplicitlyConvertedToType;
-  
-recurse:
-  switch (E->getStmtClass()) {
-  case Expr::NoStmtClass:
-#define ABSTRACT_STMT(Type)
-#define EXPR(Type, Base)
-#define STMT(Type, Base) \
-  case Expr::Type##Class:
-#include "clang/AST/StmtNodes.inc"
-    // fallthrough
-
-  // These all can only appear in local or variable-initialization
-  // contexts and so should never appear in a mangling.
-  case Expr::AddrLabelExprClass:
-  case Expr::DesignatedInitExprClass:
-  case Expr::ImplicitValueInitExprClass:
-  case Expr::ParenListExprClass:
-  case Expr::LambdaExprClass:
-    llvm_unreachable("unexpected statement kind");
-
-  // FIXME: invent manglings for all these.
-  case Expr::BlockExprClass:
-  case Expr::CXXPseudoDestructorExprClass:
-  case Expr::ChooseExprClass:
-  case Expr::CompoundLiteralExprClass:
-  case Expr::ExtVectorElementExprClass:
-  case Expr::GenericSelectionExprClass:
-  case Expr::ObjCEncodeExprClass:
-  case Expr::ObjCIsaExprClass:
-  case Expr::ObjCIvarRefExprClass:
-  case Expr::ObjCMessageExprClass:
-  case Expr::ObjCPropertyRefExprClass:
-  case Expr::ObjCProtocolExprClass:
-  case Expr::ObjCSelectorExprClass:
-  case Expr::ObjCStringLiteralClass:
-  case Expr::ObjCBoxedExprClass:
-  case Expr::ObjCArrayLiteralClass:
-  case Expr::ObjCDictionaryLiteralClass:
-  case Expr::ObjCSubscriptRefExprClass:
-  case Expr::ObjCIndirectCopyRestoreExprClass:
-  case Expr::OffsetOfExprClass:
-  case Expr::PredefinedExprClass:
-  case Expr::ShuffleVectorExprClass:
-  case Expr::StmtExprClass:
-  case Expr::UnaryTypeTraitExprClass:
-  case Expr::BinaryTypeTraitExprClass:
-  case Expr::TypeTraitExprClass:
-  case Expr::ArrayTypeTraitExprClass:
-  case Expr::ExpressionTraitExprClass:
-  case Expr::VAArgExprClass:
-  case Expr::CXXUuidofExprClass:
-  case Expr::CUDAKernelCallExprClass:
-  case Expr::AsTypeExprClass:
-  case Expr::PseudoObjectExprClass:
-  case Expr::AtomicExprClass:
-  {
-    // As bad as this diagnostic is, it's better than crashing.
-    DiagnosticsEngine &Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                     "cannot yet mangle expression type %0");
-    Diags.Report(E->getExprLoc(), DiagID)
-      << E->getStmtClassName() << E->getSourceRange();
-    break;
-  }
-
-  // Even gcc-4.5 doesn't mangle this.
-  case Expr::BinaryConditionalOperatorClass: {
-    DiagnosticsEngine &Diags = Context.getDiags();
-    unsigned DiagID =
-      Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                "?: operator with omitted middle operand cannot be mangled");
-    Diags.Report(E->getExprLoc(), DiagID)
-      << E->getStmtClassName() << E->getSourceRange();
-    break;
-  }
-
-  // These are used for internal purposes and cannot be meaningfully mangled.
-  case Expr::OpaqueValueExprClass:
-    llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");
-
-  case Expr::InitListExprClass: {
-    // Proposal by Jason Merrill, 2012-01-03
-    Out << "il";
-    const InitListExpr *InitList = cast<InitListExpr>(E);
-    for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
-      mangleExpression(InitList->getInit(i));
-    Out << "E";
-    break;
-  }
-
-  case Expr::CXXDefaultArgExprClass:
-    mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr(), Arity);
-    break;
-
-  case Expr::SubstNonTypeTemplateParmExprClass:
-    mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),
-                     Arity);
-    break;
-
-  case Expr::UserDefinedLiteralClass:
-    // We follow g++'s approach of mangling a UDL as a call to the literal
-    // operator.
-  case Expr::CXXMemberCallExprClass: // fallthrough
-  case Expr::CallExprClass: {
-    const CallExpr *CE = cast<CallExpr>(E);
-
-    // <expression> ::= cp <simple-id> <expression>* E
-    // We use this mangling only when the call would use ADL except
-    // for being parenthesized.  Per discussion with David
-    // Vandervoorde, 2011.04.25.
-    if (isParenthesizedADLCallee(CE)) {
-      Out << "cp";
-      // The callee here is a parenthesized UnresolvedLookupExpr with
-      // no qualifier and should always get mangled as a <simple-id>
-      // anyway.
-
-    // <expression> ::= cl <expression>* E
-    } else {
-      Out << "cl";
-    }
-
-    mangleExpression(CE->getCallee(), CE->getNumArgs());
-    for (unsigned I = 0, N = CE->getNumArgs(); I != N; ++I)
-      mangleExpression(CE->getArg(I));
-    Out << 'E';
-    break;
-  }
-
-  case Expr::CXXNewExprClass: {
-    const CXXNewExpr *New = cast<CXXNewExpr>(E);
-    if (New->isGlobalNew()) Out << "gs";
-    Out << (New->isArray() ? "na" : "nw");
-    for (CXXNewExpr::const_arg_iterator I = New->placement_arg_begin(),
-           E = New->placement_arg_end(); I != E; ++I)
-      mangleExpression(*I);
-    Out << '_';
-    mangleType(New->getAllocatedType());
-    if (New->hasInitializer()) {
-      // Proposal by Jason Merrill, 2012-01-03
-      if (New->getInitializationStyle() == CXXNewExpr::ListInit)
-        Out << "il";
-      else
-        Out << "pi";
-      const Expr *Init = New->getInitializer();
-      if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
-        // Directly inline the initializers.
-        for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
-                                                  E = CCE->arg_end();
-             I != E; ++I)
-          mangleExpression(*I);
-      } else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
-        for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
-          mangleExpression(PLE->getExpr(i));
-      } else if (New->getInitializationStyle() == CXXNewExpr::ListInit &&
-                 isa<InitListExpr>(Init)) {
-        // Only take InitListExprs apart for list-initialization.
-        const InitListExpr *InitList = cast<InitListExpr>(Init);
-        for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
-          mangleExpression(InitList->getInit(i));
-      } else
-        mangleExpression(Init);
-    }
-    Out << 'E';
-    break;
-  }
-
-  case Expr::MemberExprClass: {
-    const MemberExpr *ME = cast<MemberExpr>(E);
-    mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), 0, ME->getMemberDecl()->getDeclName(),
-                     Arity);
-    break;
-  }
-
-  case Expr::UnresolvedMemberExprClass: {
-    const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
-    mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), 0, ME->getMemberName(),
-                     Arity);
-    if (ME->hasExplicitTemplateArgs())
-      mangleTemplateArgs(ME->getExplicitTemplateArgs());
-    break;
-  }
-
-  case Expr::CXXDependentScopeMemberExprClass: {
-    const CXXDependentScopeMemberExpr *ME
-      = cast<CXXDependentScopeMemberExpr>(E);
-    mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), ME->getFirstQualifierFoundInScope(),
-                     ME->getMember(), Arity);
-    if (ME->hasExplicitTemplateArgs())
-      mangleTemplateArgs(ME->getExplicitTemplateArgs());
-    break;
-  }
-
-  case Expr::UnresolvedLookupExprClass: {
-    const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
-    mangleUnresolvedName(ULE->getQualifier(), 0, ULE->getName(), Arity);
-
-    // All the <unresolved-name> productions end in a
-    // base-unresolved-name, where <template-args> are just tacked
-    // onto the end.
-    if (ULE->hasExplicitTemplateArgs())
-      mangleTemplateArgs(ULE->getExplicitTemplateArgs());
-    break;
-  }
-
-  case Expr::CXXUnresolvedConstructExprClass: {
-    const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);
-    unsigned N = CE->arg_size();
-
-    Out << "cv";
-    mangleType(CE->getType());
-    if (N != 1) Out << '_';
-    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));
-    if (N != 1) Out << 'E';
-    break;
-  }
-
-  case Expr::CXXTemporaryObjectExprClass:
-  case Expr::CXXConstructExprClass: {
-    const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
-    unsigned N = CE->getNumArgs();
-
-    // Proposal by Jason Merrill, 2012-01-03
-    if (CE->isListInitialization())
-      Out << "tl";
-    else
-      Out << "cv";
-    mangleType(CE->getType());
-    if (N != 1) Out << '_';
-    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));
-    if (N != 1) Out << 'E';
-    break;
-  }
-
-  case Expr::CXXScalarValueInitExprClass:
-    Out <<"cv";
-    mangleType(E->getType());
-    Out <<"_E";
-    break;
-
-  case Expr::CXXNoexceptExprClass:
-    Out << "nx";
-    mangleExpression(cast<CXXNoexceptExpr>(E)->getOperand());
-    break;
-
-  case Expr::UnaryExprOrTypeTraitExprClass: {
-    const UnaryExprOrTypeTraitExpr *SAE = cast<UnaryExprOrTypeTraitExpr>(E);
-    
-    if (!SAE->isInstantiationDependent()) {
-      // Itanium C++ ABI:
-      //   If the operand of a sizeof or alignof operator is not 
-      //   instantiation-dependent it is encoded as an integer literal 
-      //   reflecting the result of the operator.
-      //
-      //   If the result of the operator is implicitly converted to a known 
-      //   integer type, that type is used for the literal; otherwise, the type 
-      //   of std::size_t or std::ptrdiff_t is used.
-      QualType T = (ImplicitlyConvertedToType.isNull() || 
-                    !ImplicitlyConvertedToType->isIntegerType())? SAE->getType()
-                                                    : ImplicitlyConvertedToType;
-      llvm::APSInt V = SAE->EvaluateKnownConstInt(Context.getASTContext());
-      mangleIntegerLiteral(T, V);
-      break;
-    }
-    
-    switch(SAE->getKind()) {
-    case UETT_SizeOf:
-      Out << 's';
-      break;
-    case UETT_AlignOf:
-      Out << 'a';
-      break;
-    case UETT_VecStep:
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                     "cannot yet mangle vec_step expression");
-      Diags.Report(DiagID);
-      return;
-    }
-    if (SAE->isArgumentType()) {
-      Out << 't';
-      mangleType(SAE->getArgumentType());
-    } else {
-      Out << 'z';
-      mangleExpression(SAE->getArgumentExpr());
-    }
-    break;
-  }
-
-  case Expr::CXXThrowExprClass: {
-    const CXXThrowExpr *TE = cast<CXXThrowExpr>(E);
-
-    // Proposal from David Vandervoorde, 2010.06.30
-    if (TE->getSubExpr()) {
-      Out << "tw";
-      mangleExpression(TE->getSubExpr());
-    } else {
-      Out << "tr";
-    }
-    break;
-  }
-
-  case Expr::CXXTypeidExprClass: {
-    const CXXTypeidExpr *TIE = cast<CXXTypeidExpr>(E);
-
-    // Proposal from David Vandervoorde, 2010.06.30
-    if (TIE->isTypeOperand()) {
-      Out << "ti";
-      mangleType(TIE->getTypeOperand());
-    } else {
-      Out << "te";
-      mangleExpression(TIE->getExprOperand());
-    }
-    break;
-  }
-
-  case Expr::CXXDeleteExprClass: {
-    const CXXDeleteExpr *DE = cast<CXXDeleteExpr>(E);
-
-    // Proposal from David Vandervoorde, 2010.06.30
-    if (DE->isGlobalDelete()) Out << "gs";
-    Out << (DE->isArrayForm() ? "da" : "dl");
-    mangleExpression(DE->getArgument());
-    break;
-  }
-
-  case Expr::UnaryOperatorClass: {
-    const UnaryOperator *UO = cast<UnaryOperator>(E);
-    mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
-                       /*Arity=*/1);
-    mangleExpression(UO->getSubExpr());
-    break;
-  }
-
-  case Expr::ArraySubscriptExprClass: {
-    const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(E);
-
-    // Array subscript is treated as a syntactically weird form of
-    // binary operator.
-    Out << "ix";
-    mangleExpression(AE->getLHS());
-    mangleExpression(AE->getRHS());
-    break;
-  }
-
-  case Expr::CompoundAssignOperatorClass: // fallthrough
-  case Expr::BinaryOperatorClass: {
-    const BinaryOperator *BO = cast<BinaryOperator>(E);
-    if (BO->getOpcode() == BO_PtrMemD)
-      Out << "ds";
-    else
-      mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
-                         /*Arity=*/2);
-    mangleExpression(BO->getLHS());
-    mangleExpression(BO->getRHS());
-    break;
-  }
-
-  case Expr::ConditionalOperatorClass: {
-    const ConditionalOperator *CO = cast<ConditionalOperator>(E);
-    mangleOperatorName(OO_Conditional, /*Arity=*/3);
-    mangleExpression(CO->getCond());
-    mangleExpression(CO->getLHS(), Arity);
-    mangleExpression(CO->getRHS(), Arity);
-    break;
-  }
-
-  case Expr::ImplicitCastExprClass: {
-    ImplicitlyConvertedToType = E->getType();
-    E = cast<ImplicitCastExpr>(E)->getSubExpr();
-    goto recurse;
-  }
-      
-  case Expr::ObjCBridgedCastExprClass: {
-    // Mangle ownership casts as a vendor extended operator __bridge, 
-    // __bridge_transfer, or __bridge_retain.
-    StringRef Kind = cast<ObjCBridgedCastExpr>(E)->getBridgeKindName();
-    Out << "v1U" << Kind.size() << Kind;
-  }
-  // Fall through to mangle the cast itself.
-      
-  case Expr::CStyleCastExprClass:
-  case Expr::CXXStaticCastExprClass:
-  case Expr::CXXDynamicCastExprClass:
-  case Expr::CXXReinterpretCastExprClass:
-  case Expr::CXXConstCastExprClass:
-  case Expr::CXXFunctionalCastExprClass: {
-    const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E);
-    Out << "cv";
-    mangleType(ECE->getType());
-    mangleExpression(ECE->getSubExpr());
-    break;
-  }
-
-  case Expr::CXXOperatorCallExprClass: {
-    const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);
-    unsigned NumArgs = CE->getNumArgs();
-    mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs);
-    // Mangle the arguments.
-    for (unsigned i = 0; i != NumArgs; ++i)
-      mangleExpression(CE->getArg(i));
-    break;
-  }
-
-  case Expr::ParenExprClass:
-    mangleExpression(cast<ParenExpr>(E)->getSubExpr(), Arity);
-    break;
-
-  case Expr::DeclRefExprClass: {
-    const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
-
-    switch (D->getKind()) {
-    default:
-      //  <expr-primary> ::= L <mangled-name> E # external name
-      Out << 'L';
-      mangle(D, "_Z");
-      Out << 'E';
-      break;
-
-    case Decl::ParmVar:
-      mangleFunctionParam(cast<ParmVarDecl>(D));
-      break;
-
-    case Decl::EnumConstant: {
-      const EnumConstantDecl *ED = cast<EnumConstantDecl>(D);
-      mangleIntegerLiteral(ED->getType(), ED->getInitVal());
-      break;
-    }
-
-    case Decl::NonTypeTemplateParm: {
-      const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);
-      mangleTemplateParameter(PD->getIndex());
-      break;
-    }
-
-    }
-
-    break;
-  }
-
-  case Expr::SubstNonTypeTemplateParmPackExprClass:
-    // FIXME: not clear how to mangle this!
-    // template <unsigned N...> class A {
-    //   template <class U...> void foo(U (&x)[N]...);
-    // };
-    Out << "_SUBSTPACK_";
-    break;
-
-  case Expr::FunctionParmPackExprClass: {
-    // FIXME: not clear how to mangle this!
-    const FunctionParmPackExpr *FPPE = cast<FunctionParmPackExpr>(E);
-    Out << "v110_SUBSTPACK";
-    mangleFunctionParam(FPPE->getParameterPack());
-    break;
-  }
-
-  case Expr::DependentScopeDeclRefExprClass: {
-    const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
-    mangleUnresolvedName(DRE->getQualifier(), 0, DRE->getDeclName(), Arity);
-
-    // All the <unresolved-name> productions end in a
-    // base-unresolved-name, where <template-args> are just tacked
-    // onto the end.
-    if (DRE->hasExplicitTemplateArgs())
-      mangleTemplateArgs(DRE->getExplicitTemplateArgs());
-    break;
-  }
-
-  case Expr::CXXBindTemporaryExprClass:
-    mangleExpression(cast<CXXBindTemporaryExpr>(E)->getSubExpr());
-    break;
-
-  case Expr::ExprWithCleanupsClass:
-    mangleExpression(cast<ExprWithCleanups>(E)->getSubExpr(), Arity);
-    break;
-
-  case Expr::FloatingLiteralClass: {
-    const FloatingLiteral *FL = cast<FloatingLiteral>(E);
-    Out << 'L';
-    mangleType(FL->getType());
-    mangleFloat(FL->getValue());
-    Out << 'E';
-    break;
-  }
-
-  case Expr::CharacterLiteralClass:
-    Out << 'L';
-    mangleType(E->getType());
-    Out << cast<CharacterLiteral>(E)->getValue();
-    Out << 'E';
-    break;
-
-  // FIXME. __objc_yes/__objc_no are mangled same as true/false
-  case Expr::ObjCBoolLiteralExprClass:
-    Out << "Lb";
-    Out << (cast<ObjCBoolLiteralExpr>(E)->getValue() ? '1' : '0');
-    Out << 'E';
-    break;
-  
-  case Expr::CXXBoolLiteralExprClass:
-    Out << "Lb";
-    Out << (cast<CXXBoolLiteralExpr>(E)->getValue() ? '1' : '0');
-    Out << 'E';
-    break;
-
-  case Expr::IntegerLiteralClass: {
-    llvm::APSInt Value(cast<IntegerLiteral>(E)->getValue());
-    if (E->getType()->isSignedIntegerType())
-      Value.setIsSigned(true);
-    mangleIntegerLiteral(E->getType(), Value);
-    break;
-  }
-
-  case Expr::ImaginaryLiteralClass: {
-    const ImaginaryLiteral *IE = cast<ImaginaryLiteral>(E);
-    // Mangle as if a complex literal.
-    // Proposal from David Vandevoorde, 2010.06.30.
-    Out << 'L';
-    mangleType(E->getType());
-    if (const FloatingLiteral *Imag =
-          dyn_cast<FloatingLiteral>(IE->getSubExpr())) {
-      // Mangle a floating-point zero of the appropriate type.
-      mangleFloat(llvm::APFloat(Imag->getValue().getSemantics()));
-      Out << '_';
-      mangleFloat(Imag->getValue());
-    } else {
-      Out << "0_";
-      llvm::APSInt Value(cast<IntegerLiteral>(IE->getSubExpr())->getValue());
-      if (IE->getSubExpr()->getType()->isSignedIntegerType())
-        Value.setIsSigned(true);
-      mangleNumber(Value);
-    }
-    Out << 'E';
-    break;
-  }
-
-  case Expr::StringLiteralClass: {
-    // Revised proposal from David Vandervoorde, 2010.07.15.
-    Out << 'L';
-    assert(isa<ConstantArrayType>(E->getType()));
-    mangleType(E->getType());
-    Out << 'E';
-    break;
-  }
-
-  case Expr::GNUNullExprClass:
-    // FIXME: should this really be mangled the same as nullptr?
-    // fallthrough
-
-  case Expr::CXXNullPtrLiteralExprClass: {
-    // Proposal from David Vandervoorde, 2010.06.30, as
-    // modified by ABI list discussion.
-    Out << "LDnE";
-    break;
-  }
-      
-  case Expr::PackExpansionExprClass:
-    Out << "sp";
-    mangleExpression(cast<PackExpansionExpr>(E)->getPattern());
-    break;
-      
-  case Expr::SizeOfPackExprClass: {
-    Out << "sZ";
-    const NamedDecl *Pack = cast<SizeOfPackExpr>(E)->getPack();
-    if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack))
-      mangleTemplateParameter(TTP->getIndex());
-    else if (const NonTypeTemplateParmDecl *NTTP
-                = dyn_cast<NonTypeTemplateParmDecl>(Pack))
-      mangleTemplateParameter(NTTP->getIndex());
-    else if (const TemplateTemplateParmDecl *TempTP
-                                    = dyn_cast<TemplateTemplateParmDecl>(Pack))
-      mangleTemplateParameter(TempTP->getIndex());
-    else
-      mangleFunctionParam(cast<ParmVarDecl>(Pack));
-    break;
-  }
-      
-  case Expr::MaterializeTemporaryExprClass: {
-    mangleExpression(cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr());
-    break;
-  }
-      
-  case Expr::CXXThisExprClass:
-    Out << "fpT";
-    break;
-  }
-}
-
-/// Mangle an expression which refers to a parameter variable.
-///
-/// <expression>     ::= <function-param>
-/// <function-param> ::= fp <top-level CV-qualifiers> _      # L == 0, I == 0
-/// <function-param> ::= fp <top-level CV-qualifiers>
-///                      <parameter-2 non-negative number> _ # L == 0, I > 0
-/// <function-param> ::= fL <L-1 non-negative number>
-///                      p <top-level CV-qualifiers> _       # L > 0, I == 0
-/// <function-param> ::= fL <L-1 non-negative number>
-///                      p <top-level CV-qualifiers>
-///                      <I-1 non-negative number> _         # L > 0, I > 0
-///
-/// L is the nesting depth of the parameter, defined as 1 if the
-/// parameter comes from the innermost function prototype scope
-/// enclosing the current context, 2 if from the next enclosing
-/// function prototype scope, and so on, with one special case: if
-/// we've processed the full parameter clause for the innermost
-/// function type, then L is one less.  This definition conveniently
-/// makes it irrelevant whether a function's result type was written
-/// trailing or leading, but is otherwise overly complicated; the
-/// numbering was first designed without considering references to
-/// parameter in locations other than return types, and then the
-/// mangling had to be generalized without changing the existing
-/// manglings.
-///
-/// I is the zero-based index of the parameter within its parameter
-/// declaration clause.  Note that the original ABI document describes
-/// this using 1-based ordinals.
-void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) {
-  unsigned parmDepth = parm->getFunctionScopeDepth();
-  unsigned parmIndex = parm->getFunctionScopeIndex();
-
-  // Compute 'L'.
-  // parmDepth does not include the declaring function prototype.
-  // FunctionTypeDepth does account for that.
-  assert(parmDepth < FunctionTypeDepth.getDepth());
-  unsigned nestingDepth = FunctionTypeDepth.getDepth() - parmDepth;
-  if (FunctionTypeDepth.isInResultType())
-    nestingDepth--;
-
-  if (nestingDepth == 0) {
-    Out << "fp";
-  } else {
-    Out << "fL" << (nestingDepth - 1) << 'p';
-  }
-
-  // Top-level qualifiers.  We don't have to worry about arrays here,
-  // because parameters declared as arrays should already have been
-  // transformed to have pointer type. FIXME: apparently these don't
-  // get mangled if used as an rvalue of a known non-class type?
-  assert(!parm->getType()->isArrayType()
-         && "parameter's type is still an array type?");
-  mangleQualifiers(parm->getType().getQualifiers());
-
-  // Parameter index.
-  if (parmIndex != 0) {
-    Out << (parmIndex - 1);
-  }
-  Out << '_';
-}
-
-void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
-  // <ctor-dtor-name> ::= C1  # complete object constructor
-  //                  ::= C2  # base object constructor
-  //                  ::= C3  # complete object allocating constructor
-  //
-  switch (T) {
-  case Ctor_Complete:
-    Out << "C1";
-    break;
-  case Ctor_Base:
-    Out << "C2";
-    break;
-  case Ctor_CompleteAllocating:
-    Out << "C3";
-    break;
-  }
-}
-
-void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
-  // <ctor-dtor-name> ::= D0  # deleting destructor
-  //                  ::= D1  # complete object destructor
-  //                  ::= D2  # base object destructor
-  //
-  switch (T) {
-  case Dtor_Deleting:
-    Out << "D0";
-    break;
-  case Dtor_Complete:
-    Out << "D1";
-    break;
-  case Dtor_Base:
-    Out << "D2";
-    break;
-  }
-}
-
-void CXXNameMangler::mangleTemplateArgs(
-                          const ASTTemplateArgumentListInfo &TemplateArgs) {
-  // <template-args> ::= I <template-arg>+ E
-  Out << 'I';
-  for (unsigned i = 0, e = TemplateArgs.NumTemplateArgs; i != e; ++i)
-    mangleTemplateArg(TemplateArgs.getTemplateArgs()[i].getArgument());
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &AL) {
-  // <template-args> ::= I <template-arg>+ E
-  Out << 'I';
-  for (unsigned i = 0, e = AL.size(); i != e; ++i)
-    mangleTemplateArg(AL[i]);
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,
-                                        unsigned NumTemplateArgs) {
-  // <template-args> ::= I <template-arg>+ E
-  Out << 'I';
-  for (unsigned i = 0; i != NumTemplateArgs; ++i)
-    mangleTemplateArg(TemplateArgs[i]);
-  Out << 'E';
-}
-
-void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
-  // <template-arg> ::= <type>              # type or template
-  //                ::= X <expression> E    # expression
-  //                ::= <expr-primary>      # simple expressions
-  //                ::= J <template-arg>* E # argument pack
-  //                ::= sp <expression>     # pack expansion of (C++0x)  
-  if (!A.isInstantiationDependent() || A.isDependent())
-    A = Context.getASTContext().getCanonicalTemplateArgument(A);
-  
-  switch (A.getKind()) {
-  case TemplateArgument::Null:
-    llvm_unreachable("Cannot mangle NULL template argument");
-      
-  case TemplateArgument::Type:
-    mangleType(A.getAsType());
-    break;
-  case TemplateArgument::Template:
-    // This is mangled as <type>.
-    mangleType(A.getAsTemplate());
-    break;
-  case TemplateArgument::TemplateExpansion:
-    // <type>  ::= Dp <type>          # pack expansion (C++0x)
-    Out << "Dp";
-    mangleType(A.getAsTemplateOrTemplatePattern());
-    break;
-  case TemplateArgument::Expression: {
-    // It's possible to end up with a DeclRefExpr here in certain
-    // dependent cases, in which case we should mangle as a
-    // declaration.
-    const Expr *E = A.getAsExpr()->IgnoreParens();
-    if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
-      const ValueDecl *D = DRE->getDecl();
-      if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) {
-        Out << "L";
-        mangle(D, "_Z");
-        Out << 'E';
-        break;
-      }
-    }
-    
-    Out << 'X';
-    mangleExpression(E);
-    Out << 'E';
-    break;
-  }
-  case TemplateArgument::Integral:
-    mangleIntegerLiteral(A.getIntegralType(), A.getAsIntegral());
-    break;
-  case TemplateArgument::Declaration: {
-    //  <expr-primary> ::= L <mangled-name> E # external name
-    // Clang produces AST's where pointer-to-member-function expressions
-    // and pointer-to-function expressions are represented as a declaration not
-    // an expression. We compensate for it here to produce the correct mangling.
-    ValueDecl *D = A.getAsDecl();
-    bool compensateMangling = !A.isDeclForReferenceParam();
-    if (compensateMangling) {
-      Out << 'X';
-      mangleOperatorName(OO_Amp, 1);
-    }
-
-    Out << 'L';
-    // References to external entities use the mangled name; if the name would
-    // not normally be manged then mangle it as unqualified.
-    //
-    // FIXME: The ABI specifies that external names here should have _Z, but
-    // gcc leaves this off.
-    if (compensateMangling)
-      mangle(D, "_Z");
-    else
-      mangle(D, "Z");
-    Out << 'E';
-
-    if (compensateMangling)
-      Out << 'E';
-
-    break;
-  }
-  case TemplateArgument::NullPtr: {
-    //  <expr-primary> ::= L <type> 0 E
-    Out << 'L';
-    mangleType(A.getNullPtrType());
-    Out << "0E";
-    break;
-  }
-  case TemplateArgument::Pack: {
-    // Note: proposal by Mike Herrick on 12/20/10
-    Out << 'J';
-    for (TemplateArgument::pack_iterator PA = A.pack_begin(), 
-                                      PAEnd = A.pack_end();
-         PA != PAEnd; ++PA)
-      mangleTemplateArg(*PA);
-    Out << 'E';
-  }
-  }
-}
-
-void CXXNameMangler::mangleTemplateParameter(unsigned Index) {
-  // <template-param> ::= T_    # first template parameter
-  //                  ::= T <parameter-2 non-negative number> _
-  if (Index == 0)
-    Out << "T_";
-  else
-    Out << 'T' << (Index - 1) << '_';
-}
-
-void CXXNameMangler::mangleExistingSubstitution(QualType type) {
-  bool result = mangleSubstitution(type);
-  assert(result && "no existing substitution for type");
-  (void) result;
-}
-
-void CXXNameMangler::mangleExistingSubstitution(TemplateName tname) {
-  bool result = mangleSubstitution(tname);
-  assert(result && "no existing substitution for template name");
-  (void) result;
-}
-
-// <substitution> ::= S <seq-id> _
-//                ::= S_
-bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
-  // Try one of the standard substitutions first.
-  if (mangleStandardSubstitution(ND))
-    return true;
-
-  ND = cast<NamedDecl>(ND->getCanonicalDecl());
-  return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));
-}
-
-/// \brief Determine whether the given type has any qualifiers that are
-/// relevant for substitutions.
-static bool hasMangledSubstitutionQualifiers(QualType T) {
-  Qualifiers Qs = T.getQualifiers();
-  return Qs.getCVRQualifiers() || Qs.hasAddressSpace();
-}
-
-bool CXXNameMangler::mangleSubstitution(QualType T) {
-  if (!hasMangledSubstitutionQualifiers(T)) {
-    if (const RecordType *RT = T->getAs<RecordType>())
-      return mangleSubstitution(RT->getDecl());
-  }
-
-  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
-
-  return mangleSubstitution(TypePtr);
-}
-
-bool CXXNameMangler::mangleSubstitution(TemplateName Template) {
-  if (TemplateDecl *TD = Template.getAsTemplateDecl())
-    return mangleSubstitution(TD);
-  
-  Template = Context.getASTContext().getCanonicalTemplateName(Template);
-  return mangleSubstitution(
-                      reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));
-}
-
-bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
-  llvm::DenseMap<uintptr_t, unsigned>::iterator I = Substitutions.find(Ptr);
-  if (I == Substitutions.end())
-    return false;
-
-  unsigned SeqID = I->second;
-  if (SeqID == 0)
-    Out << "S_";
-  else {
-    SeqID--;
-
-    // <seq-id> is encoded in base-36, using digits and upper case letters.
-    char Buffer[10];
-    char *BufferPtr = llvm::array_endof(Buffer);
-
-    if (SeqID == 0) *--BufferPtr = '0';
-
-    while (SeqID) {
-      assert(BufferPtr > Buffer && "Buffer overflow!");
-
-      char c = static_cast<char>(SeqID % 36);
-
-      *--BufferPtr =  (c < 10 ? '0' + c : 'A' + c - 10);
-      SeqID /= 36;
-    }
-
-    Out << 'S'
-        << StringRef(BufferPtr, llvm::array_endof(Buffer)-BufferPtr)
-        << '_';
-  }
-
-  return true;
-}
-
-static bool isCharType(QualType T) {
-  if (T.isNull())
-    return false;
-
-  return T->isSpecificBuiltinType(BuiltinType::Char_S) ||
-    T->isSpecificBuiltinType(BuiltinType::Char_U);
-}
-
-/// isCharSpecialization - Returns whether a given type is a template
-/// specialization of a given name with a single argument of type char.
-static bool isCharSpecialization(QualType T, const char *Name) {
-  if (T.isNull())
-    return false;
-
-  const RecordType *RT = T->getAs<RecordType>();
-  if (!RT)
-    return false;
-
-  const ClassTemplateSpecializationDecl *SD =
-    dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
-  if (!SD)
-    return false;
-
-  if (!isStdNamespace(getEffectiveDeclContext(SD)))
-    return false;
-
-  const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
-  if (TemplateArgs.size() != 1)
-    return false;
-
-  if (!isCharType(TemplateArgs[0].getAsType()))
-    return false;
-
-  return SD->getIdentifier()->getName() == Name;
-}
-
-template <std::size_t StrLen>
-static bool isStreamCharSpecialization(const ClassTemplateSpecializationDecl*SD,
-                                       const char (&Str)[StrLen]) {
-  if (!SD->getIdentifier()->isStr(Str))
-    return false;
-
-  const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
-  if (TemplateArgs.size() != 2)
-    return false;
-
-  if (!isCharType(TemplateArgs[0].getAsType()))
-    return false;
-
-  if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
-    return false;
-
-  return true;
-}
-
-bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
-  // <substitution> ::= St # ::std::
-  if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
-    if (isStd(NS)) {
-      Out << "St";
-      return true;
-    }
-  }
-
-  if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
-    if (!isStdNamespace(getEffectiveDeclContext(TD)))
-      return false;
-
-    // <substitution> ::= Sa # ::std::allocator
-    if (TD->getIdentifier()->isStr("allocator")) {
-      Out << "Sa";
-      return true;
-    }
-
-    // <<substitution> ::= Sb # ::std::basic_string
-    if (TD->getIdentifier()->isStr("basic_string")) {
-      Out << "Sb";
-      return true;
-    }
-  }
-
-  if (const ClassTemplateSpecializationDecl *SD =
-        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
-    if (!isStdNamespace(getEffectiveDeclContext(SD)))
-      return false;
-
-    //    <substitution> ::= Ss # ::std::basic_string<char,
-    //                            ::std::char_traits<char>,
-    //                            ::std::allocator<char> >
-    if (SD->getIdentifier()->isStr("basic_string")) {
-      const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
-
-      if (TemplateArgs.size() != 3)
-        return false;
-
-      if (!isCharType(TemplateArgs[0].getAsType()))
-        return false;
-
-      if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
-        return false;
-
-      if (!isCharSpecialization(TemplateArgs[2].getAsType(), "allocator"))
-        return false;
-
-      Out << "Ss";
-      return true;
-    }
-
-    //    <substitution> ::= Si # ::std::basic_istream<char,
-    //                            ::std::char_traits<char> >
-    if (isStreamCharSpecialization(SD, "basic_istream")) {
-      Out << "Si";
-      return true;
-    }
-
-    //    <substitution> ::= So # ::std::basic_ostream<char,
-    //                            ::std::char_traits<char> >
-    if (isStreamCharSpecialization(SD, "basic_ostream")) {
-      Out << "So";
-      return true;
-    }
-
-    //    <substitution> ::= Sd # ::std::basic_iostream<char,
-    //                            ::std::char_traits<char> >
-    if (isStreamCharSpecialization(SD, "basic_iostream")) {
-      Out << "Sd";
-      return true;
-    }
-  }
-  return false;
-}
-
-void CXXNameMangler::addSubstitution(QualType T) {
-  if (!hasMangledSubstitutionQualifiers(T)) {
-    if (const RecordType *RT = T->getAs<RecordType>()) {
-      addSubstitution(RT->getDecl());
-      return;
-    }
-  }
-
-  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
-  addSubstitution(TypePtr);
-}
-
-void CXXNameMangler::addSubstitution(TemplateName Template) {
-  if (TemplateDecl *TD = Template.getAsTemplateDecl())
-    return addSubstitution(TD);
-  
-  Template = Context.getASTContext().getCanonicalTemplateName(Template);
-  addSubstitution(reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));
-}
-
-void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
-  assert(!Substitutions.count(Ptr) && "Substitution already exists!");
-  Substitutions[Ptr] = SeqID++;
-}
-
-//
-
-/// \brief Mangles the name of the declaration D and emits that name to the
-/// given output stream.
-///
-/// If the declaration D requires a mangled name, this routine will emit that
-/// mangled name to \p os and return true. Otherwise, \p os will be unchanged
-/// and this routine will return false. In this case, the caller should just
-/// emit the identifier of the declaration (\c D->getIdentifier()) as its
-/// name.
-void ItaniumMangleContext::mangleName(const NamedDecl *D,
-                                      raw_ostream &Out) {
-  assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
-          "Invalid mangleName() call, argument is not a variable or function!");
-  assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
-         "Invalid mangleName() call on 'structor decl!");
-
-  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
-                                 getASTContext().getSourceManager(),
-                                 "Mangling declaration");
-
-  CXXNameMangler Mangler(*this, Out, D);
-  return Mangler.mangle(D);
-}
-
-void ItaniumMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
-                                         CXXCtorType Type,
-                                         raw_ostream &Out) {
-  CXXNameMangler Mangler(*this, Out, D, Type);
-  Mangler.mangle(D);
-}
-
-void ItaniumMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
-                                         CXXDtorType Type,
-                                         raw_ostream &Out) {
-  CXXNameMangler Mangler(*this, Out, D, Type);
-  Mangler.mangle(D);
-}
-
-void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD,
-                                       const ThunkInfo &Thunk,
-                                       raw_ostream &Out) {
-  //  <special-name> ::= T <call-offset> <base encoding>
-  //                      # base is the nominal target function of thunk
-  //  <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
-  //                      # base is the nominal target function of thunk
-  //                      # first call-offset is 'this' adjustment
-  //                      # second call-offset is result adjustment
-  
-  assert(!isa<CXXDestructorDecl>(MD) &&
-         "Use mangleCXXDtor for destructor decls!");
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZT";
-  if (!Thunk.Return.isEmpty())
-    Mangler.getStream() << 'c';
-  
-  // Mangle the 'this' pointer adjustment.
-  Mangler.mangleCallOffset(Thunk.This.NonVirtual, Thunk.This.VCallOffsetOffset);
-  
-  // Mangle the return pointer adjustment if there is one.
-  if (!Thunk.Return.isEmpty())
-    Mangler.mangleCallOffset(Thunk.Return.NonVirtual,
-                             Thunk.Return.VBaseOffsetOffset);
-  
-  Mangler.mangleFunctionEncoding(MD);
-}
-
-void 
-ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
-                                         CXXDtorType Type,
-                                         const ThisAdjustment &ThisAdjustment,
-                                         raw_ostream &Out) {
-  //  <special-name> ::= T <call-offset> <base encoding>
-  //                      # base is the nominal target function of thunk
-  CXXNameMangler Mangler(*this, Out, DD, Type);
-  Mangler.getStream() << "_ZT";
-
-  // Mangle the 'this' pointer adjustment.
-  Mangler.mangleCallOffset(ThisAdjustment.NonVirtual, 
-                           ThisAdjustment.VCallOffsetOffset);
-
-  Mangler.mangleFunctionEncoding(DD);
-}
-
-/// mangleGuardVariable - Returns the mangled name for a guard variable
-/// for the passed in VarDecl.
-void ItaniumMangleContext::mangleItaniumGuardVariable(const VarDecl *D,
-                                                      raw_ostream &Out) {
-  //  <special-name> ::= GV <object name>       # Guard variable for one-time
-  //                                            # initialization
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZGV";
-  Mangler.mangleName(D);
-}
-
-void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D,
-                                                    raw_ostream &Out) {
-  // We match the GCC mangling here.
-  //  <special-name> ::= GR <object name>
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZGR";
-  Mangler.mangleName(D);
-}
-
-void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
-                                           raw_ostream &Out) {
-  // <special-name> ::= TV <type>  # virtual table
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZTV";
-  Mangler.mangleNameOrStandardSubstitution(RD);
-}
-
-void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
-                                        raw_ostream &Out) {
-  // <special-name> ::= TT <type>  # VTT structure
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZTT";
-  Mangler.mangleNameOrStandardSubstitution(RD);
-}
-
-void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
-                                               int64_t Offset,
-                                               const CXXRecordDecl *Type,
-                                               raw_ostream &Out) {
-  // <special-name> ::= TC <type> <offset number> _ <base type>
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZTC";
-  Mangler.mangleNameOrStandardSubstitution(RD);
-  Mangler.getStream() << Offset;
-  Mangler.getStream() << '_';
-  Mangler.mangleNameOrStandardSubstitution(Type);
-}
-
-void ItaniumMangleContext::mangleCXXRTTI(QualType Ty,
-                                         raw_ostream &Out) {
-  // <special-name> ::= TI <type>  # typeinfo structure
-  assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZTI";
-  Mangler.mangleType(Ty);
-}
-
-void ItaniumMangleContext::mangleCXXRTTIName(QualType Ty,
-                                             raw_ostream &Out) {
-  // <special-name> ::= TS <type>  # typeinfo name (null terminated byte string)
-  CXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "_ZTS";
-  Mangler.mangleType(Ty);
-}
-
-MangleContext *clang::createItaniumMangleContext(ASTContext &Context,
-                                                 DiagnosticsEngine &Diags) {
-  return new ItaniumMangleContext(Context, Diags);
-}
+//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- C++ -*-===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// Implements C++ name mangling according to the Itanium C++ ABI,

+// which is used in GCC 3.2 and newer (and many compilers that are

+// ABI-compatible with GCC):

+//

+//   http://www.codesourcery.com/public/cxx-abi/abi.html

+//

+//===----------------------------------------------------------------------===//

+#include "clang/AST/Mangle.h"

+#include "clang/AST/ASTContext.h"

+#include "clang/AST/Attr.h"

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

+#include "clang/AST/DeclCXX.h"

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

+#include "clang/AST/DeclTemplate.h"

+#include "clang/AST/ExprCXX.h"

+#include "clang/AST/ExprObjC.h"

+#include "clang/AST/TypeLoc.h"

+#include "clang/Basic/ABI.h"

+#include "clang/Basic/SourceManager.h"

+#include "clang/Basic/TargetInfo.h"

+#include "llvm/ADT/StringExtras.h"

+#include "llvm/Support/ErrorHandling.h"

+#include "llvm/Support/raw_ostream.h"

+

+#define MANGLE_CHECKER 0

+

+#if MANGLE_CHECKER

+#include <cxxabi.h>

+#endif

+

+using namespace clang;

+

+namespace {

+

+/// \brief Retrieve the declaration context that should be used when mangling 

+/// the given declaration.

+static const DeclContext *getEffectiveDeclContext(const Decl *D) {

+  // The ABI assumes that lambda closure types that occur within 

+  // default arguments live in the context of the function. However, due to

+  // the way in which Clang parses and creates function declarations, this is

+  // not the case: the lambda closure type ends up living in the context 

+  // where the function itself resides, because the function declaration itself

+  // had not yet been created. Fix the context here.

+  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {

+    if (RD->isLambda())

+      if (ParmVarDecl *ContextParam

+            = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))

+        return ContextParam->getDeclContext();

+  }

+  

+  return D->getDeclContext();

+}

+

+static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {

+  return getEffectiveDeclContext(cast<Decl>(DC));

+}

+  

+static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) {

+  const DeclContext *DC = dyn_cast<DeclContext>(ND);

+  if (!DC)

+    DC = getEffectiveDeclContext(ND);

+  while (!DC->isNamespace() && !DC->isTranslationUnit()) {

+    const DeclContext *Parent = getEffectiveDeclContext(cast<Decl>(DC));

+    if (isa<FunctionDecl>(Parent))

+      return dyn_cast<CXXRecordDecl>(DC);

+    DC = Parent;

+  }

+  return 0;

+}

+

+static const FunctionDecl *getStructor(const FunctionDecl *fn) {

+  if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate())

+    return ftd->getTemplatedDecl();

+

+  return fn;

+}

+

+static const NamedDecl *getStructor(const NamedDecl *decl) {

+  const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl);

+  return (fn ? getStructor(fn) : decl);

+}

+                                                    

+static const unsigned UnknownArity = ~0U;

+

+class ItaniumMangleContext : public MangleContext {

+  llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;

+  unsigned Discriminator;

+  llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;

+  

+public:

+  explicit ItaniumMangleContext(ASTContext &Context,

+                                DiagnosticsEngine &Diags)

+    : MangleContext(Context, Diags) { }

+

+  uint64_t getAnonymousStructId(const TagDecl *TD) {

+    std::pair<llvm::DenseMap<const TagDecl *,

+      uint64_t>::iterator, bool> Result =

+      AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));

+    return Result.first->second;

+  }

+

+  void startNewFunction() {

+    MangleContext::startNewFunction();

+    mangleInitDiscriminator();

+  }

+

+  /// @name Mangler Entry Points

+  /// @{

+

+  bool shouldMangleDeclName(const NamedDecl *D);

+  void mangleName(const NamedDecl *D, raw_ostream &);

+  void mangleThunk(const CXXMethodDecl *MD,

+                   const ThunkInfo &Thunk,

+                   raw_ostream &);

+  void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,

+                          const ThisAdjustment &ThisAdjustment,

+                          raw_ostream &);

+  void mangleReferenceTemporary(const VarDecl *D,

+                                raw_ostream &);

+  void mangleCXXVTable(const CXXRecordDecl *RD,

+                       raw_ostream &);

+  void mangleCXXVTT(const CXXRecordDecl *RD,

+                    raw_ostream &);

+  void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,

+                           const CXXRecordDecl *Type,

+                           raw_ostream &);

+  void mangleCXXRTTI(QualType T, raw_ostream &);

+  void mangleCXXRTTIName(QualType T, raw_ostream &);

+  void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,

+                     raw_ostream &);

+  void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,

+                     raw_ostream &);

+

+  void mangleItaniumGuardVariable(const VarDecl *D, raw_ostream &);

+

+  void mangleInitDiscriminator() {

+    Discriminator = 0;

+  }

+

+  bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {

+    // Lambda closure types with external linkage (indicated by a 

+    // non-zero lambda mangling number) have their own numbering scheme, so

+    // they do not need a discriminator.

+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))

+      if (RD->isLambda() && RD->getLambdaManglingNumber() > 0)

+        return false;

+        

+    unsigned &discriminator = Uniquifier[ND];

+    if (!discriminator)

+      discriminator = ++Discriminator;

+    if (discriminator == 1)

+      return false;

+    disc = discriminator-2;

+    return true;

+  }

+  /// @}

+};

+

+/// CXXNameMangler - Manage the mangling of a single name.

+class CXXNameMangler {

+  ItaniumMangleContext &Context;

+  raw_ostream &Out;

+

+  /// The "structor" is the top-level declaration being mangled, if

+  /// that's not a template specialization; otherwise it's the pattern

+  /// for that specialization.

+  const NamedDecl *Structor;

+  unsigned StructorType;

+

+  /// SeqID - The next subsitution sequence number.

+  unsigned SeqID;

+

+  class FunctionTypeDepthState {

+    unsigned Bits;

+

+    enum { InResultTypeMask = 1 };

+

+  public:

+    FunctionTypeDepthState() : Bits(0) {}

+

+    /// The number of function types we're inside.

+    unsigned getDepth() const {

+      return Bits >> 1;

+    }

+

+    /// True if we're in the return type of the innermost function type.

+    bool isInResultType() const {

+      return Bits & InResultTypeMask;

+    }

+

+    FunctionTypeDepthState push() {

+      FunctionTypeDepthState tmp = *this;

+      Bits = (Bits & ~InResultTypeMask) + 2;

+      return tmp;

+    }

+

+    void enterResultType() {

+      Bits |= InResultTypeMask;

+    }

+

+    void leaveResultType() {

+      Bits &= ~InResultTypeMask;

+    }

+

+    void pop(FunctionTypeDepthState saved) {

+      assert(getDepth() == saved.getDepth() + 1);

+      Bits = saved.Bits;

+    }

+

+  } FunctionTypeDepth;

+

+  llvm::DenseMap<uintptr_t, unsigned> Substitutions;

+

+  ASTContext &getASTContext() const { return Context.getASTContext(); }

+

+public:

+  CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,

+                 const NamedDecl *D = 0)

+    : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),

+      SeqID(0) {

+    // These can't be mangled without a ctor type or dtor type.

+    assert(!D || (!isa<CXXDestructorDecl>(D) &&

+                  !isa<CXXConstructorDecl>(D)));

+  }

+  CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,

+                 const CXXConstructorDecl *D, CXXCtorType Type)

+    : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),

+      SeqID(0) { }

+  CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,

+                 const CXXDestructorDecl *D, CXXDtorType Type)

+    : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),

+      SeqID(0) { }

+

+#if MANGLE_CHECKER

+  ~CXXNameMangler() {

+    if (Out.str()[0] == '\01')

+      return;

+

+    int status = 0;

+    char *result = abi::__cxa_demangle(Out.str().str().c_str(), 0, 0, &status);

+    assert(status == 0 && "Could not demangle mangled name!");

+    free(result);

+  }

+#endif

+  raw_ostream &getStream() { return Out; }

+

+  void mangle(const NamedDecl *D, StringRef Prefix = "_Z");

+  void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);

+  void mangleNumber(const llvm::APSInt &I);

+  void mangleNumber(int64_t Number);

+  void mangleFloat(const llvm::APFloat &F);

+  void mangleFunctionEncoding(const FunctionDecl *FD);

+  void mangleName(const NamedDecl *ND);

+  void mangleType(QualType T);

+  void mangleNameOrStandardSubstitution(const NamedDecl *ND);

+  

+private:

+  bool mangleSubstitution(const NamedDecl *ND);

+  bool mangleSubstitution(QualType T);

+  bool mangleSubstitution(TemplateName Template);

+  bool mangleSubstitution(uintptr_t Ptr);

+

+  void mangleExistingSubstitution(QualType type);

+  void mangleExistingSubstitution(TemplateName name);

+

+  bool mangleStandardSubstitution(const NamedDecl *ND);

+

+  void addSubstitution(const NamedDecl *ND) {

+    ND = cast<NamedDecl>(ND->getCanonicalDecl());

+

+    addSubstitution(reinterpret_cast<uintptr_t>(ND));

+  }

+  void addSubstitution(QualType T);

+  void addSubstitution(TemplateName Template);

+  void addSubstitution(uintptr_t Ptr);

+

+  void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,

+                              NamedDecl *firstQualifierLookup,

+                              bool recursive = false);

+  void mangleUnresolvedName(NestedNameSpecifier *qualifier,

+                            NamedDecl *firstQualifierLookup,

+                            DeclarationName name,

+                            unsigned KnownArity = UnknownArity);

+

+  void mangleName(const TemplateDecl *TD,

+                  const TemplateArgument *TemplateArgs,

+                  unsigned NumTemplateArgs);

+  void mangleUnqualifiedName(const NamedDecl *ND) {

+    mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity);

+  }

+  void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name,

+                             unsigned KnownArity);

+  void mangleUnscopedName(const NamedDecl *ND);

+  void mangleUnscopedTemplateName(const TemplateDecl *ND);

+  void mangleUnscopedTemplateName(TemplateName);

+  void mangleSourceName(const IdentifierInfo *II);

+  void mangleLocalName(const NamedDecl *ND);

+  void mangleLambda(const CXXRecordDecl *Lambda);

+  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,

+                        bool NoFunction=false);

+  void mangleNestedName(const TemplateDecl *TD,

+                        const TemplateArgument *TemplateArgs,

+                        unsigned NumTemplateArgs);

+  void manglePrefix(NestedNameSpecifier *qualifier);

+  void manglePrefix(const DeclContext *DC, bool NoFunction=false);

+  void manglePrefix(QualType type);

+  void mangleTemplatePrefix(const TemplateDecl *ND);

+  void mangleTemplatePrefix(TemplateName Template);

+  void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);

+  void mangleQualifiers(Qualifiers Quals);

+  void mangleRefQualifier(RefQualifierKind RefQualifier);

+

+  void mangleObjCMethodName(const ObjCMethodDecl *MD);

+

+  // Declare manglers for every type class.

+#define ABSTRACT_TYPE(CLASS, PARENT)

+#define NON_CANONICAL_TYPE(CLASS, PARENT)

+#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);

+#include "clang/AST/TypeNodes.def"

+

+  void mangleType(const TagType*);

+  void mangleType(TemplateName);

+  void mangleBareFunctionType(const FunctionType *T,

+                              bool MangleReturnType);

+  void mangleNeonVectorType(const VectorType *T);

+

+  void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value);

+  void mangleMemberExpr(const Expr *base, bool isArrow,

+                        NestedNameSpecifier *qualifier,

+                        NamedDecl *firstQualifierLookup,

+                        DeclarationName name,

+                        unsigned knownArity);

+  void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);

+  void mangleCXXCtorType(CXXCtorType T);

+  void mangleCXXDtorType(CXXDtorType T);

+

+  void mangleTemplateArgs(const ASTTemplateArgumentListInfo &TemplateArgs);

+  void mangleTemplateArgs(const TemplateArgument *TemplateArgs,

+                          unsigned NumTemplateArgs);

+  void mangleTemplateArgs(const TemplateArgumentList &AL);

+  void mangleTemplateArg(TemplateArgument A);

+

+  void mangleTemplateParameter(unsigned Index);

+

+  void mangleFunctionParam(const ParmVarDecl *parm);

+};

+

+}

+

+static bool isInCLinkageSpecification(const Decl *D) {

+  D = D->getCanonicalDecl();

+  for (const DeclContext *DC = getEffectiveDeclContext(D);

+       !DC->isTranslationUnit(); DC = getEffectiveParentContext(DC)) {

+    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))

+      return Linkage->getLanguage() == LinkageSpecDecl::lang_c;

+  }

+

+  return false;

+}

+

+bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {

+  // In C, functions with no attributes never need to be mangled. Fastpath them.

+  if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())

+    return false;

+

+  // Any decl can be declared with __asm("foo") on it, and this takes precedence

+  // over all other naming in the .o file.

+  if (D->hasAttr<AsmLabelAttr>())

+    return true;

+

+  // Clang's "overloadable" attribute extension to C/C++ implies name mangling

+  // (always) as does passing a C++ member function and a function

+  // whose name is not a simple identifier.

+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);

+  if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||

+             !FD->getDeclName().isIdentifier()))

+    return true;

+

+  // Otherwise, no mangling is done outside C++ mode.

+  if (!getASTContext().getLangOpts().CPlusPlus)

+    return false;

+

+  // Variables at global scope with non-internal linkage are not mangled

+  if (!FD) {

+    const DeclContext *DC = getEffectiveDeclContext(D);

+    // Check for extern variable declared locally.

+    if (DC->isFunctionOrMethod() && D->hasLinkage())

+      while (!DC->isNamespace() && !DC->isTranslationUnit())

+        DC = getEffectiveParentContext(DC);

+    if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)

+      return false;

+  }

+

+  // Class members are always mangled.

+  if (getEffectiveDeclContext(D)->isRecord())

+    return true;

+

+  // C functions and "main" are not mangled.

+  if ((FD && FD->isMain()) || isInCLinkageSpecification(D))

+    return false;

+

+  return true;

+}

+

+void CXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {

+  // Any decl can be declared with __asm("foo") on it, and this takes precedence

+  // over all other naming in the .o file.

+  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {

+    // If we have an asm name, then we use it as the mangling.

+

+    // Adding the prefix can cause problems when one file has a "foo" and

+    // another has a "\01foo". That is known to happen on ELF with the

+    // tricks normally used for producing aliases (PR9177). Fortunately the

+    // llvm mangler on ELF is a nop, so we can just avoid adding the \01

+    // marker.  We also avoid adding the marker if this is an alias for an

+    // LLVM intrinsic.

+    StringRef UserLabelPrefix =

+      getASTContext().getTargetInfo().getUserLabelPrefix();

+    if (!UserLabelPrefix.empty() && !ALA->getLabel().startswith("llvm."))

+      Out << '\01';  // LLVM IR Marker for __asm("foo")

+

+    Out << ALA->getLabel();

+    return;

+  }

+

+  // <mangled-name> ::= _Z <encoding>

+  //            ::= <data name>

+  //            ::= <special-name>

+  Out << Prefix;

+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))

+    mangleFunctionEncoding(FD);

+  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))

+    mangleName(VD);

+  else

+    mangleName(cast<FieldDecl>(D));

+}

+

+void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {

+  // <encoding> ::= <function name> <bare-function-type>

+  mangleName(FD);

+

+  // Don't mangle in the type if this isn't a decl we should typically mangle.

+  if (!Context.shouldMangleDeclName(FD))

+    return;

+

+  // Whether the mangling of a function type includes the return type depends on

+  // the context and the nature of the function. The rules for deciding whether

+  // the return type is included are:

+  //

+  //   1. Template functions (names or types) have return types encoded, with

+  //   the exceptions listed below.

+  //   2. Function types not appearing as part of a function name mangling,

+  //   e.g. parameters, pointer types, etc., have return type encoded, with the

+  //   exceptions listed below.

+  //   3. Non-template function names do not have return types encoded.

+  //

+  // The exceptions mentioned in (1) and (2) above, for which the return type is

+  // never included, are

+  //   1. Constructors.

+  //   2. Destructors.

+  //   3. Conversion operator functions, e.g. operator int.

+  bool MangleReturnType = false;

+  if (FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate()) {

+    if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||

+          isa<CXXConversionDecl>(FD)))

+      MangleReturnType = true;

+

+    // Mangle the type of the primary template.

+    FD = PrimaryTemplate->getTemplatedDecl();

+  }

+

+  mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), 

+                         MangleReturnType);

+}

+

+static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {

+  while (isa<LinkageSpecDecl>(DC)) {

+    DC = getEffectiveParentContext(DC);

+  }

+

+  return DC;

+}

+

+/// isStd - Return whether a given namespace is the 'std' namespace.

+static bool isStd(const NamespaceDecl *NS) {

+  if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS))

+                                ->isTranslationUnit())

+    return false;

+  

+  const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();

+  return II && II->isStr("std");

+}

+

+// isStdNamespace - Return whether a given decl context is a toplevel 'std'

+// namespace.

+static bool isStdNamespace(const DeclContext *DC) {

+  if (!DC->isNamespace())

+    return false;

+

+  return isStd(cast<NamespaceDecl>(DC));

+}

+

+static const TemplateDecl *

+isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {

+  // Check if we have a function template.

+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){

+    if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {

+      TemplateArgs = FD->getTemplateSpecializationArgs();

+      return TD;

+    }

+  }

+

+  // Check if we have a class template.

+  if (const ClassTemplateSpecializationDecl *Spec =

+        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {

+    TemplateArgs = &Spec->getTemplateArgs();

+    return Spec->getSpecializedTemplate();

+  }

+

+  return 0;

+}

+

+static bool isLambda(const NamedDecl *ND) {

+  const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);

+  if (!Record)

+    return false;

+  

+  return Record->isLambda();

+}

+

+void CXXNameMangler::mangleName(const NamedDecl *ND) {

+  //  <name> ::= <nested-name>

+  //         ::= <unscoped-name>

+  //         ::= <unscoped-template-name> <template-args>

+  //         ::= <local-name>

+  //

+  const DeclContext *DC = getEffectiveDeclContext(ND);

+

+  // If this is an extern variable declared locally, the relevant DeclContext

+  // is that of the containing namespace, or the translation unit.

+  // FIXME: This is a hack; extern variables declared locally should have

+  // a proper semantic declaration context!

+  if (isa<FunctionDecl>(DC) && ND->hasLinkage() && !isLambda(ND))

+    while (!DC->isNamespace() && !DC->isTranslationUnit())

+      DC = getEffectiveParentContext(DC);

+  else if (GetLocalClassDecl(ND)) {

+    mangleLocalName(ND);

+    return;

+  }

+

+  DC = IgnoreLinkageSpecDecls(DC);

+

+  if (DC->isTranslationUnit() || isStdNamespace(DC)) {

+    // Check if we have a template.

+    const TemplateArgumentList *TemplateArgs = 0;

+    if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {

+      mangleUnscopedTemplateName(TD);

+      mangleTemplateArgs(*TemplateArgs);

+      return;

+    }

+

+    mangleUnscopedName(ND);

+    return;

+  }

+

+  if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) {

+    mangleLocalName(ND);

+    return;

+  }

+

+  mangleNestedName(ND, DC);

+}

+void CXXNameMangler::mangleName(const TemplateDecl *TD,

+                                const TemplateArgument *TemplateArgs,

+                                unsigned NumTemplateArgs) {

+  const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD));

+

+  if (DC->isTranslationUnit() || isStdNamespace(DC)) {

+    mangleUnscopedTemplateName(TD);

+    mangleTemplateArgs(TemplateArgs, NumTemplateArgs);

+  } else {

+    mangleNestedName(TD, TemplateArgs, NumTemplateArgs);

+  }

+}

+

+void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {

+  //  <unscoped-name> ::= <unqualified-name>

+  //                  ::= St <unqualified-name>   # ::std::

+

+  if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND))))

+    Out << "St";

+

+  mangleUnqualifiedName(ND);

+}

+

+void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {

+  //     <unscoped-template-name> ::= <unscoped-name>

+  //                              ::= <substitution>

+  if (mangleSubstitution(ND))

+    return;

+

+  // <template-template-param> ::= <template-param>

+  if (const TemplateTemplateParmDecl *TTP

+                                     = dyn_cast<TemplateTemplateParmDecl>(ND)) {

+    mangleTemplateParameter(TTP->getIndex());

+    return;

+  }

+

+  mangleUnscopedName(ND->getTemplatedDecl());

+  addSubstitution(ND);

+}

+

+void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) {

+  //     <unscoped-template-name> ::= <unscoped-name>

+  //                              ::= <substitution>

+  if (TemplateDecl *TD = Template.getAsTemplateDecl())

+    return mangleUnscopedTemplateName(TD);

+  

+  if (mangleSubstitution(Template))

+    return;

+

+  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();

+  assert(Dependent && "Not a dependent template name?");

+  if (const IdentifierInfo *Id = Dependent->getIdentifier())

+    mangleSourceName(Id);

+  else

+    mangleOperatorName(Dependent->getOperator(), UnknownArity);

+  

+  addSubstitution(Template);

+}

+

+void CXXNameMangler::mangleFloat(const llvm::APFloat &f) {

+  // ABI:

+  //   Floating-point literals are encoded using a fixed-length

+  //   lowercase hexadecimal string corresponding to the internal

+  //   representation (IEEE on Itanium), high-order bytes first,

+  //   without leading zeroes. For example: "Lf bf800000 E" is -1.0f

+  //   on Itanium.

+  // The 'without leading zeroes' thing seems to be an editorial

+  // mistake; see the discussion on cxx-abi-dev beginning on

+  // 2012-01-16.

+

+  // Our requirements here are just barely weird enough to justify

+  // using a custom algorithm instead of post-processing APInt::toString().

+

+  llvm::APInt valueBits = f.bitcastToAPInt();

+  unsigned numCharacters = (valueBits.getBitWidth() + 3) / 4;

+  assert(numCharacters != 0);

+

+  // Allocate a buffer of the right number of characters.

+  llvm::SmallVector<char, 20> buffer;

+  buffer.set_size(numCharacters);

+

+  // Fill the buffer left-to-right.

+  for (unsigned stringIndex = 0; stringIndex != numCharacters; ++stringIndex) {

+    // The bit-index of the next hex digit.

+    unsigned digitBitIndex = 4 * (numCharacters - stringIndex - 1);

+

+    // Project out 4 bits starting at 'digitIndex'.

+    llvm::integerPart hexDigit

+      = valueBits.getRawData()[digitBitIndex / llvm::integerPartWidth];

+    hexDigit >>= (digitBitIndex % llvm::integerPartWidth);

+    hexDigit &= 0xF;

+

+    // Map that over to a lowercase hex digit.

+    static const char charForHex[16] = {

+      '0', '1', '2', '3', '4', '5', '6', '7',

+      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'

+    };

+    buffer[stringIndex] = charForHex[hexDigit];

+  }

+

+  Out.write(buffer.data(), numCharacters);

+}

+

+void CXXNameMangler::mangleNumber(const llvm::APSInt &Value) {

+  if (Value.isSigned() && Value.isNegative()) {

+    Out << 'n';

+    Value.abs().print(Out, /*signed*/ false);

+  } else {

+    Value.print(Out, /*signed*/ false);

+  }

+}

+

+void CXXNameMangler::mangleNumber(int64_t Number) {

+  //  <number> ::= [n] <non-negative decimal integer>

+  if (Number < 0) {

+    Out << 'n';

+    Number = -Number;

+  }

+

+  Out << Number;

+}

+

+void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) {

+  //  <call-offset>  ::= h <nv-offset> _

+  //                 ::= v <v-offset> _

+  //  <nv-offset>    ::= <offset number>        # non-virtual base override

+  //  <v-offset>     ::= <offset number> _ <virtual offset number>

+  //                      # virtual base override, with vcall offset

+  if (!Virtual) {

+    Out << 'h';

+    mangleNumber(NonVirtual);

+    Out << '_';

+    return;

+  }

+

+  Out << 'v';

+  mangleNumber(NonVirtual);

+  Out << '_';

+  mangleNumber(Virtual);

+  Out << '_';

+}

+

+void CXXNameMangler::manglePrefix(QualType type) {

+  if (const TemplateSpecializationType *TST =

+        type->getAs<TemplateSpecializationType>()) {

+    if (!mangleSubstitution(QualType(TST, 0))) {

+      mangleTemplatePrefix(TST->getTemplateName());

+        

+      // FIXME: GCC does not appear to mangle the template arguments when

+      // the template in question is a dependent template name. Should we

+      // emulate that badness?

+      mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());

+      addSubstitution(QualType(TST, 0));

+    }

+  } else if (const DependentTemplateSpecializationType *DTST

+               = type->getAs<DependentTemplateSpecializationType>()) {

+    TemplateName Template

+      = getASTContext().getDependentTemplateName(DTST->getQualifier(), 

+                                                 DTST->getIdentifier());

+    mangleTemplatePrefix(Template);

+

+    // FIXME: GCC does not appear to mangle the template arguments when

+    // the template in question is a dependent template name. Should we

+    // emulate that badness?

+    mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());

+  } else {

+    // We use the QualType mangle type variant here because it handles

+    // substitutions.

+    mangleType(type);

+  }

+}

+

+/// Mangle everything prior to the base-unresolved-name in an unresolved-name.

+///

+/// \param firstQualifierLookup - the entity found by unqualified lookup

+///   for the first name in the qualifier, if this is for a member expression

+/// \param recursive - true if this is being called recursively,

+///   i.e. if there is more prefix "to the right".

+void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,

+                                            NamedDecl *firstQualifierLookup,

+                                            bool recursive) {

+

+  // x, ::x

+  // <unresolved-name> ::= [gs] <base-unresolved-name>

+

+  // T::x / decltype(p)::x

+  // <unresolved-name> ::= sr <unresolved-type> <base-unresolved-name>

+

+  // T::N::x /decltype(p)::N::x

+  // <unresolved-name> ::= srN <unresolved-type> <unresolved-qualifier-level>+ E

+  //                       <base-unresolved-name>

+

+  // A::x, N::y, A<T>::z; "gs" means leading "::"

+  // <unresolved-name> ::= [gs] sr <unresolved-qualifier-level>+ E

+  //                       <base-unresolved-name>

+

+  switch (qualifier->getKind()) {

+  case NestedNameSpecifier::Global:

+    Out << "gs";

+

+    // We want an 'sr' unless this is the entire NNS.

+    if (recursive)

+      Out << "sr";

+

+    // We never want an 'E' here.

+    return;

+

+  case NestedNameSpecifier::Namespace:

+    if (qualifier->getPrefix())

+      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,

+                             /*recursive*/ true);

+    else

+      Out << "sr";

+    mangleSourceName(qualifier->getAsNamespace()->getIdentifier());

+    break;

+  case NestedNameSpecifier::NamespaceAlias:

+    if (qualifier->getPrefix())

+      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,

+                             /*recursive*/ true);

+    else

+      Out << "sr";

+    mangleSourceName(qualifier->getAsNamespaceAlias()->getIdentifier());

+    break;

+

+  case NestedNameSpecifier::TypeSpec:

+  case NestedNameSpecifier::TypeSpecWithTemplate: {

+    const Type *type = qualifier->getAsType();

+

+    // We only want to use an unresolved-type encoding if this is one of:

+    //   - a decltype

+    //   - a template type parameter

+    //   - a template template parameter with arguments

+    // In all of these cases, we should have no prefix.

+    if (qualifier->getPrefix()) {

+      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,

+                             /*recursive*/ true);

+    } else {

+      // Otherwise, all the cases want this.

+      Out << "sr";

+    }

+

+    // Only certain other types are valid as prefixes;  enumerate them.

+    switch (type->getTypeClass()) {

+    case Type::Builtin:

+    case Type::Complex:

+    case Type::Pointer:

+    case Type::BlockPointer:

+    case Type::LValueReference:

+    case Type::RValueReference:

+    case Type::MemberPointer:

+    case Type::ConstantArray:

+    case Type::IncompleteArray:

+    case Type::VariableArray:

+    case Type::DependentSizedArray:

+    case Type::DependentSizedExtVector:

+    case Type::Vector:

+    case Type::ExtVector:

+    case Type::FunctionProto:

+    case Type::FunctionNoProto:

+    case Type::Enum:

+    case Type::Paren:

+    case Type::Elaborated:

+    case Type::Attributed:

+    case Type::Auto:

+    case Type::PackExpansion:

+    case Type::ObjCObject:

+    case Type::ObjCInterface:

+    case Type::ObjCObjectPointer:

+    case Type::Atomic:

+      llvm_unreachable("type is illegal as a nested name specifier");

+

+    case Type::SubstTemplateTypeParmPack:

+      // FIXME: not clear how to mangle this!

+      // template <class T...> class A {

+      //   template <class U...> void foo(decltype(T::foo(U())) x...);

+      // };

+      Out << "_SUBSTPACK_";

+      break;

+

+    // <unresolved-type> ::= <template-param>

+    //                   ::= <decltype>

+    //                   ::= <template-template-param> <template-args>

+    // (this last is not official yet)

+    case Type::TypeOfExpr:

+    case Type::TypeOf:

+    case Type::Decltype:

+    case Type::TemplateTypeParm:

+    case Type::UnaryTransform:

+    case Type::SubstTemplateTypeParm:

+    unresolvedType:

+      assert(!qualifier->getPrefix());

+

+      // We only get here recursively if we're followed by identifiers.

+      if (recursive) Out << 'N';

+

+      // This seems to do everything we want.  It's not really

+      // sanctioned for a substituted template parameter, though.

+      mangleType(QualType(type, 0));

+

+      // We never want to print 'E' directly after an unresolved-type,

+      // so we return directly.

+      return;

+

+    case Type::Typedef:

+      mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier());

+      break;

+

+    case Type::UnresolvedUsing:

+      mangleSourceName(cast<UnresolvedUsingType>(type)->getDecl()

+                         ->getIdentifier());

+      break;

+

+    case Type::Record:

+      mangleSourceName(cast<RecordType>(type)->getDecl()->getIdentifier());

+      break;

+

+    case Type::TemplateSpecialization: {

+      const TemplateSpecializationType *tst

+        = cast<TemplateSpecializationType>(type);

+      TemplateName name = tst->getTemplateName();

+      switch (name.getKind()) {

+      case TemplateName::Template:

+      case TemplateName::QualifiedTemplate: {

+        TemplateDecl *temp = name.getAsTemplateDecl();

+

+        // If the base is a template template parameter, this is an

+        // unresolved type.

+        assert(temp && "no template for template specialization type");

+        if (isa<TemplateTemplateParmDecl>(temp)) goto unresolvedType;

+

+        mangleSourceName(temp->getIdentifier());

+        break;

+      }

+

+      case TemplateName::OverloadedTemplate:

+      case TemplateName::DependentTemplate:

+        llvm_unreachable("invalid base for a template specialization type");

+

+      case TemplateName::SubstTemplateTemplateParm: {

+        SubstTemplateTemplateParmStorage *subst

+          = name.getAsSubstTemplateTemplateParm();

+        mangleExistingSubstitution(subst->getReplacement());

+        break;

+      }

+

+      case TemplateName::SubstTemplateTemplateParmPack: {

+        // FIXME: not clear how to mangle this!

+        // template <template <class U> class T...> class A {

+        //   template <class U...> void foo(decltype(T<U>::foo) x...);

+        // };

+        Out << "_SUBSTPACK_";

+        break;

+      }

+      }

+

+      mangleTemplateArgs(tst->getArgs(), tst->getNumArgs());

+      break;

+    }

+

+    case Type::InjectedClassName:

+      mangleSourceName(cast<InjectedClassNameType>(type)->getDecl()

+                         ->getIdentifier());

+      break;

+

+    case Type::DependentName:

+      mangleSourceName(cast<DependentNameType>(type)->getIdentifier());

+      break;

+

+    case Type::DependentTemplateSpecialization: {

+      const DependentTemplateSpecializationType *tst

+        = cast<DependentTemplateSpecializationType>(type);

+      mangleSourceName(tst->getIdentifier());

+      mangleTemplateArgs(tst->getArgs(), tst->getNumArgs());

+      break;

+    }

+    }

+    break;

+  }

+

+  case NestedNameSpecifier::Identifier:

+    // Member expressions can have these without prefixes.

+    if (qualifier->getPrefix()) {

+      mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,

+                             /*recursive*/ true);

+    } else if (firstQualifierLookup) {

+

+      // Try to make a proper qualifier out of the lookup result, and

+      // then just recurse on that.

+      NestedNameSpecifier *newQualifier;

+      if (TypeDecl *typeDecl = dyn_cast<TypeDecl>(firstQualifierLookup)) {

+        QualType type = getASTContext().getTypeDeclType(typeDecl);

+

+        // Pretend we had a different nested name specifier.

+        newQualifier = NestedNameSpecifier::Create(getASTContext(),

+                                                   /*prefix*/ 0,

+                                                   /*template*/ false,

+                                                   type.getTypePtr());

+      } else if (NamespaceDecl *nspace =

+                   dyn_cast<NamespaceDecl>(firstQualifierLookup)) {

+        newQualifier = NestedNameSpecifier::Create(getASTContext(),

+                                                   /*prefix*/ 0,

+                                                   nspace);

+      } else if (NamespaceAliasDecl *alias =

+                   dyn_cast<NamespaceAliasDecl>(firstQualifierLookup)) {

+        newQualifier = NestedNameSpecifier::Create(getASTContext(),

+                                                   /*prefix*/ 0,

+                                                   alias);

+      } else {

+        // No sensible mangling to do here.

+        newQualifier = 0;

+      }

+

+      if (newQualifier)

+        return mangleUnresolvedPrefix(newQualifier, /*lookup*/ 0, recursive);

+

+    } else {

+      Out << "sr";

+    }

+

+    mangleSourceName(qualifier->getAsIdentifier());

+    break;

+  }

+

+  // If this was the innermost part of the NNS, and we fell out to

+  // here, append an 'E'.

+  if (!recursive)

+    Out << 'E';

+}

+

+/// Mangle an unresolved-name, which is generally used for names which

+/// weren't resolved to specific entities.

+void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier,

+                                          NamedDecl *firstQualifierLookup,

+                                          DeclarationName name,

+                                          unsigned knownArity) {

+  if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup);

+  mangleUnqualifiedName(0, name, knownArity);

+}

+

+static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {

+  assert(RD->isAnonymousStructOrUnion() &&

+         "Expected anonymous struct or union!");

+  

+  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();

+       I != E; ++I) {

+    if (I->getIdentifier())

+      return *I;

+    

+    if (const RecordType *RT = I->getType()->getAs<RecordType>())

+      if (const FieldDecl *NamedDataMember = 

+          FindFirstNamedDataMember(RT->getDecl()))

+        return NamedDataMember;

+    }

+

+  // We didn't find a named data member.

+  return 0;

+}

+

+void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,

+                                           DeclarationName Name,

+                                           unsigned KnownArity) {

+  //  <unqualified-name> ::= <operator-name>

+  //                     ::= <ctor-dtor-name>

+  //                     ::= <source-name>

+  switch (Name.getNameKind()) {

+  case DeclarationName::Identifier: {

+    if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {

+      // We must avoid conflicts between internally- and externally-

+      // linked variable and function declaration names in the same TU:

+      //   void test() { extern void foo(); }

+      //   static void foo();

+      // This naming convention is the same as that followed by GCC,

+      // though it shouldn't actually matter.

+      if (ND && ND->getLinkage() == InternalLinkage &&

+          getEffectiveDeclContext(ND)->isFileContext())

+        Out << 'L';

+

+      mangleSourceName(II);

+      break;

+    }

+

+    // Otherwise, an anonymous entity.  We must have a declaration.

+    assert(ND && "mangling empty name without declaration");

+

+    if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {

+      if (NS->isAnonymousNamespace()) {

+        // This is how gcc mangles these names.

+        Out << "12_GLOBAL__N_1";

+        break;

+      }

+    }

+

+    if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {

+      // We must have an anonymous union or struct declaration.

+      const RecordDecl *RD = 

+        cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl());

+      

+      // Itanium C++ ABI 5.1.2:

+      //

+      //   For the purposes of mangling, the name of an anonymous union is

+      //   considered to be the name of the first named data member found by a

+      //   pre-order, depth-first, declaration-order walk of the data members of

+      //   the anonymous union. If there is no such data member (i.e., if all of

+      //   the data members in the union are unnamed), then there is no way for

+      //   a program to refer to the anonymous union, and there is therefore no

+      //   need to mangle its name.

+      const FieldDecl *FD = FindFirstNamedDataMember(RD);

+

+      // It's actually possible for various reasons for us to get here

+      // with an empty anonymous struct / union.  Fortunately, it

+      // doesn't really matter what name we generate.

+      if (!FD) break;

+      assert(FD->getIdentifier() && "Data member name isn't an identifier!");

+      

+      mangleSourceName(FD->getIdentifier());

+      break;

+    }

+    

+    // We must have an anonymous struct.

+    const TagDecl *TD = cast<TagDecl>(ND);

+    if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {

+      assert(TD->getDeclContext() == D->getDeclContext() &&

+             "Typedef should not be in another decl context!");

+      assert(D->getDeclName().getAsIdentifierInfo() &&

+             "Typedef was not named!");

+      mangleSourceName(D->getDeclName().getAsIdentifierInfo());

+      break;

+    }

+

+    // <unnamed-type-name> ::= <closure-type-name>

+    // 

+    // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _

+    // <lambda-sig> ::= <parameter-type>+   # Parameter types or 'v' for 'void'.

+    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {

+      if (Record->isLambda() && Record->getLambdaManglingNumber()) {

+        mangleLambda(Record);

+        break;

+      }

+    }

+

+    int UnnamedMangle = Context.getASTContext().getUnnamedTagManglingNumber(TD);

+    if (UnnamedMangle != -1) {

+      Out << "Ut";

+      if (UnnamedMangle != 0)

+        Out << llvm::utostr(UnnamedMangle - 1);

+      Out << '_';

+      break;

+    }

+

+    // Get a unique id for the anonymous struct.

+    uint64_t AnonStructId = Context.getAnonymousStructId(TD);

+

+    // Mangle it as a source name in the form

+    // [n] $_<id>

+    // where n is the length of the string.

+    SmallString<8> Str;

+    Str += "$_";

+    Str += llvm::utostr(AnonStructId);

+

+    Out << Str.size();

+    Out << Str.str();

+    break;

+  }

+

+  case DeclarationName::ObjCZeroArgSelector:

+  case DeclarationName::ObjCOneArgSelector:

+  case DeclarationName::ObjCMultiArgSelector:

+    llvm_unreachable("Can't mangle Objective-C selector names here!");

+

+  case DeclarationName::CXXConstructorName:

+    if (ND == Structor)

+      // If the named decl is the C++ constructor we're mangling, use the type

+      // we were given.

+      mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));

+    else

+      // Otherwise, use the complete constructor name. This is relevant if a

+      // class with a constructor is declared within a constructor.

+      mangleCXXCtorType(Ctor_Complete);

+    break;

+

+  case DeclarationName::CXXDestructorName:

+    if (ND == Structor)

+      // If the named decl is the C++ destructor we're mangling, use the type we

+      // were given.

+      mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));

+    else

+      // Otherwise, use the complete destructor name. This is relevant if a

+      // class with a destructor is declared within a destructor.

+      mangleCXXDtorType(Dtor_Complete);

+    break;

+

+  case DeclarationName::CXXConversionFunctionName:

+    // <operator-name> ::= cv <type>    # (cast)

+    Out << "cv";

+    mangleType(Name.getCXXNameType());

+    break;

+

+  case DeclarationName::CXXOperatorName: {

+    unsigned Arity;

+    if (ND) {

+      Arity = cast<FunctionDecl>(ND)->getNumParams();

+

+      // If we have a C++ member function, we need to include the 'this' pointer.

+      // FIXME: This does not make sense for operators that are static, but their

+      // names stay the same regardless of the arity (operator new for instance).

+      if (isa<CXXMethodDecl>(ND))

+        Arity++;

+    } else

+      Arity = KnownArity;

+

+    mangleOperatorName(Name.getCXXOverloadedOperator(), Arity);

+    break;

+  }

+

+  case DeclarationName::CXXLiteralOperatorName:

+    // FIXME: This mangling is not yet official.

+    Out << "li";

+    mangleSourceName(Name.getCXXLiteralIdentifier());

+    break;

+

+  case DeclarationName::CXXUsingDirective:

+    llvm_unreachable("Can't mangle a using directive name!");

+  }

+}

+

+void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {

+  // <source-name> ::= <positive length number> <identifier>

+  // <number> ::= [n] <non-negative decimal integer>

+  // <identifier> ::= <unqualified source code identifier>

+  Out << II->getLength() << II->getName();

+}

+

+void CXXNameMangler::mangleNestedName(const NamedDecl *ND,

+                                      const DeclContext *DC,

+                                      bool NoFunction) {

+  // <nested-name> 

+  //   ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E

+  //   ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> 

+  //       <template-args> E

+

+  Out << 'N';

+  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND)) {

+    mangleQualifiers(Qualifiers::fromCVRMask(Method->getTypeQualifiers()));

+    mangleRefQualifier(Method->getRefQualifier());

+  }

+  

+  // Check if we have a template.

+  const TemplateArgumentList *TemplateArgs = 0;

+  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {

+    mangleTemplatePrefix(TD);

+    mangleTemplateArgs(*TemplateArgs);

+  }

+  else {

+    manglePrefix(DC, NoFunction);

+    mangleUnqualifiedName(ND);

+  }

+

+  Out << 'E';

+}

+void CXXNameMangler::mangleNestedName(const TemplateDecl *TD,

+                                      const TemplateArgument *TemplateArgs,

+                                      unsigned NumTemplateArgs) {

+  // <nested-name> ::= N [<CV-qualifiers>] <template-prefix> <template-args> E

+

+  Out << 'N';

+

+  mangleTemplatePrefix(TD);

+  mangleTemplateArgs(TemplateArgs, NumTemplateArgs);

+

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {

+  // <local-name> := Z <function encoding> E <entity name> [<discriminator>]

+  //              := Z <function encoding> E s [<discriminator>]

+  // <local-name> := Z <function encoding> E d [ <parameter number> ] 

+  //                 _ <entity name>

+  // <discriminator> := _ <non-negative number>

+  const DeclContext *DC = getEffectiveDeclContext(ND);

+  if (isa<ObjCMethodDecl>(DC) && isa<FunctionDecl>(ND)) {

+    // Don't add objc method name mangling to locally declared function

+    mangleUnqualifiedName(ND);

+    return;

+  }

+

+  Out << 'Z';

+

+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {

+   mangleObjCMethodName(MD);

+  } else if (const CXXRecordDecl *RD = GetLocalClassDecl(ND)) {

+    mangleFunctionEncoding(cast<FunctionDecl>(getEffectiveDeclContext(RD)));

+    Out << 'E';

+

+    // The parameter number is omitted for the last parameter, 0 for the 

+    // second-to-last parameter, 1 for the third-to-last parameter, etc. The 

+    // <entity name> will of course contain a <closure-type-name>: Its 

+    // numbering will be local to the particular argument in which it appears

+    // -- other default arguments do not affect its encoding.

+    bool SkipDiscriminator = false;

+    if (RD->isLambda()) {

+      if (const ParmVarDecl *Parm

+                 = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl())) {

+        if (const FunctionDecl *Func

+              = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {

+          Out << 'd';

+          unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex();

+          if (Num > 1)

+            mangleNumber(Num - 2);

+          Out << '_';

+          SkipDiscriminator = true;

+        }

+      }

+    }

+    

+    // Mangle the name relative to the closest enclosing function.

+    if (ND == RD) // equality ok because RD derived from ND above

+      mangleUnqualifiedName(ND);

+    else

+      mangleNestedName(ND, DC, true /*NoFunction*/);

+

+    if (!SkipDiscriminator) {

+      unsigned disc;

+      if (Context.getNextDiscriminator(RD, disc)) {

+        if (disc < 10)

+          Out << '_' << disc;

+        else

+          Out << "__" << disc << '_';

+      }

+    }

+    

+    return;

+  }

+  else

+    mangleFunctionEncoding(cast<FunctionDecl>(DC));

+

+  Out << 'E';

+  mangleUnqualifiedName(ND);

+}

+

+void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {

+  // If the context of a closure type is an initializer for a class member 

+  // (static or nonstatic), it is encoded in a qualified name with a final 

+  // <prefix> of the form:

+  //

+  //   <data-member-prefix> := <member source-name> M

+  //

+  // Technically, the data-member-prefix is part of the <prefix>. However,

+  // since a closure type will always be mangled with a prefix, it's easier

+  // to emit that last part of the prefix here.

+  if (Decl *Context = Lambda->getLambdaContextDecl()) {

+    if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&

+        Context->getDeclContext()->isRecord()) {

+      if (const IdentifierInfo *Name

+            = cast<NamedDecl>(Context)->getIdentifier()) {

+        mangleSourceName(Name);

+        Out << 'M';            

+      }

+    }

+  }

+

+  Out << "Ul";

+  const FunctionProtoType *Proto = Lambda->getLambdaTypeInfo()->getType()->

+                                   getAs<FunctionProtoType>();

+  mangleBareFunctionType(Proto, /*MangleReturnType=*/false);        

+  Out << "E";

+  

+  // The number is omitted for the first closure type with a given 

+  // <lambda-sig> in a given context; it is n-2 for the nth closure type 

+  // (in lexical order) with that same <lambda-sig> and context.

+  //

+  // The AST keeps track of the number for us.

+  unsigned Number = Lambda->getLambdaManglingNumber();

+  assert(Number > 0 && "Lambda should be mangled as an unnamed class");

+  if (Number > 1)

+    mangleNumber(Number - 2);

+  Out << '_';  

+}

+

+void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {

+  switch (qualifier->getKind()) {

+  case NestedNameSpecifier::Global:

+    // nothing

+    return;

+

+  case NestedNameSpecifier::Namespace:

+    mangleName(qualifier->getAsNamespace());

+    return;

+

+  case NestedNameSpecifier::NamespaceAlias:

+    mangleName(qualifier->getAsNamespaceAlias()->getNamespace());

+    return;

+

+  case NestedNameSpecifier::TypeSpec:

+  case NestedNameSpecifier::TypeSpecWithTemplate:

+    manglePrefix(QualType(qualifier->getAsType(), 0));

+    return;

+

+  case NestedNameSpecifier::Identifier:

+    // Member expressions can have these without prefixes, but that

+    // should end up in mangleUnresolvedPrefix instead.

+    assert(qualifier->getPrefix());

+    manglePrefix(qualifier->getPrefix());

+

+    mangleSourceName(qualifier->getAsIdentifier());

+    return;

+  }

+

+  llvm_unreachable("unexpected nested name specifier");

+}

+

+void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {

+  //  <prefix> ::= <prefix> <unqualified-name>

+  //           ::= <template-prefix> <template-args>

+  //           ::= <template-param>

+  //           ::= # empty

+  //           ::= <substitution>

+

+  DC = IgnoreLinkageSpecDecls(DC);

+

+  if (DC->isTranslationUnit())

+    return;

+

+  if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {

+    manglePrefix(getEffectiveParentContext(DC), NoFunction);    

+    SmallString<64> Name;

+    llvm::raw_svector_ostream NameStream(Name);

+    Context.mangleBlock(Block, NameStream);

+    NameStream.flush();

+    Out << Name.size() << Name;

+    return;

+  }

+  

+  const NamedDecl *ND = cast<NamedDecl>(DC);  

+  if (mangleSubstitution(ND))

+    return;

+  

+  // Check if we have a template.

+  const TemplateArgumentList *TemplateArgs = 0;

+  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {

+    mangleTemplatePrefix(TD);

+    mangleTemplateArgs(*TemplateArgs);

+  }

+  else if(NoFunction && (isa<FunctionDecl>(ND) || isa<ObjCMethodDecl>(ND)))

+    return;

+  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))

+    mangleObjCMethodName(Method);

+  else {

+    manglePrefix(getEffectiveDeclContext(ND), NoFunction);

+    mangleUnqualifiedName(ND);

+  }

+

+  addSubstitution(ND);

+}

+

+void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {

+  // <template-prefix> ::= <prefix> <template unqualified-name>

+  //                   ::= <template-param>

+  //                   ::= <substitution>

+  if (TemplateDecl *TD = Template.getAsTemplateDecl())

+    return mangleTemplatePrefix(TD);

+

+  if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName())

+    manglePrefix(Qualified->getQualifier());

+  

+  if (OverloadedTemplateStorage *Overloaded

+                                      = Template.getAsOverloadedTemplate()) {

+    mangleUnqualifiedName(0, (*Overloaded->begin())->getDeclName(), 

+                          UnknownArity);

+    return;

+  }

+   

+  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();

+  assert(Dependent && "Unknown template name kind?");

+  manglePrefix(Dependent->getQualifier());

+  mangleUnscopedTemplateName(Template);

+}

+

+void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {

+  // <template-prefix> ::= <prefix> <template unqualified-name>

+  //                   ::= <template-param>

+  //                   ::= <substitution>

+  // <template-template-param> ::= <template-param>

+  //                               <substitution>

+

+  if (mangleSubstitution(ND))

+    return;

+

+  // <template-template-param> ::= <template-param>

+  if (const TemplateTemplateParmDecl *TTP

+                                     = dyn_cast<TemplateTemplateParmDecl>(ND)) {

+    mangleTemplateParameter(TTP->getIndex());

+    return;

+  }

+

+  manglePrefix(getEffectiveDeclContext(ND));

+  mangleUnqualifiedName(ND->getTemplatedDecl());

+  addSubstitution(ND);

+}

+

+/// Mangles a template name under the production <type>.  Required for

+/// template template arguments.

+///   <type> ::= <class-enum-type>

+///          ::= <template-param>

+///          ::= <substitution>

+void CXXNameMangler::mangleType(TemplateName TN) {

+  if (mangleSubstitution(TN))

+    return;

+      

+  TemplateDecl *TD = 0;

+

+  switch (TN.getKind()) {

+  case TemplateName::QualifiedTemplate:

+    TD = TN.getAsQualifiedTemplateName()->getTemplateDecl();

+    goto HaveDecl;

+

+  case TemplateName::Template:

+    TD = TN.getAsTemplateDecl();

+    goto HaveDecl;

+

+  HaveDecl:

+    if (isa<TemplateTemplateParmDecl>(TD))

+      mangleTemplateParameter(cast<TemplateTemplateParmDecl>(TD)->getIndex());

+    else

+      mangleName(TD);

+    break;

+

+  case TemplateName::OverloadedTemplate:

+    llvm_unreachable("can't mangle an overloaded template name as a <type>");

+

+  case TemplateName::DependentTemplate: {

+    const DependentTemplateName *Dependent = TN.getAsDependentTemplateName();

+    assert(Dependent->isIdentifier());

+

+    // <class-enum-type> ::= <name>

+    // <name> ::= <nested-name>

+    mangleUnresolvedPrefix(Dependent->getQualifier(), 0);

+    mangleSourceName(Dependent->getIdentifier());

+    break;

+  }

+

+  case TemplateName::SubstTemplateTemplateParm: {

+    // Substituted template parameters are mangled as the substituted

+    // template.  This will check for the substitution twice, which is

+    // fine, but we have to return early so that we don't try to *add*

+    // the substitution twice.

+    SubstTemplateTemplateParmStorage *subst

+      = TN.getAsSubstTemplateTemplateParm();

+    mangleType(subst->getReplacement());

+    return;

+  }

+

+  case TemplateName::SubstTemplateTemplateParmPack: {

+    // FIXME: not clear how to mangle this!

+    // template <template <class> class T...> class A {

+    //   template <template <class> class U...> void foo(B<T,U> x...);

+    // };

+    Out << "_SUBSTPACK_";

+    break;

+  }

+  }

+

+  addSubstitution(TN);

+}

+

+void

+CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {

+  switch (OO) {

+  // <operator-name> ::= nw     # new

+  case OO_New: Out << "nw"; break;

+  //              ::= na        # new[]

+  case OO_Array_New: Out << "na"; break;

+  //              ::= dl        # delete

+  case OO_Delete: Out << "dl"; break;

+  //              ::= da        # delete[]

+  case OO_Array_Delete: Out << "da"; break;

+  //              ::= ps        # + (unary)

+  //              ::= pl        # + (binary or unknown)

+  case OO_Plus:

+    Out << (Arity == 1? "ps" : "pl"); break;

+  //              ::= ng        # - (unary)

+  //              ::= mi        # - (binary or unknown)

+  case OO_Minus:

+    Out << (Arity == 1? "ng" : "mi"); break;

+  //              ::= ad        # & (unary)

+  //              ::= an        # & (binary or unknown)

+  case OO_Amp:

+    Out << (Arity == 1? "ad" : "an"); break;

+  //              ::= de        # * (unary)

+  //              ::= ml        # * (binary or unknown)

+  case OO_Star:

+    // Use binary when unknown.

+    Out << (Arity == 1? "de" : "ml"); break;

+  //              ::= co        # ~

+  case OO_Tilde: Out << "co"; break;

+  //              ::= dv        # /

+  case OO_Slash: Out << "dv"; break;

+  //              ::= rm        # %

+  case OO_Percent: Out << "rm"; break;

+  //              ::= or        # |

+  case OO_Pipe: Out << "or"; break;

+  //              ::= eo        # ^

+  case OO_Caret: Out << "eo"; break;

+  //              ::= aS        # =

+  case OO_Equal: Out << "aS"; break;

+  //              ::= pL        # +=

+  case OO_PlusEqual: Out << "pL"; break;

+  //              ::= mI        # -=

+  case OO_MinusEqual: Out << "mI"; break;

+  //              ::= mL        # *=

+  case OO_StarEqual: Out << "mL"; break;

+  //              ::= dV        # /=

+  case OO_SlashEqual: Out << "dV"; break;

+  //              ::= rM        # %=

+  case OO_PercentEqual: Out << "rM"; break;

+  //              ::= aN        # &=

+  case OO_AmpEqual: Out << "aN"; break;

+  //              ::= oR        # |=

+  case OO_PipeEqual: Out << "oR"; break;

+  //              ::= eO        # ^=

+  case OO_CaretEqual: Out << "eO"; break;

+  //              ::= ls        # <<

+  case OO_LessLess: Out << "ls"; break;

+  //              ::= rs        # >>

+  case OO_GreaterGreater: Out << "rs"; break;

+  //              ::= lS        # <<=

+  case OO_LessLessEqual: Out << "lS"; break;

+  //              ::= rS        # >>=

+  case OO_GreaterGreaterEqual: Out << "rS"; break;

+  //              ::= eq        # ==

+  case OO_EqualEqual: Out << "eq"; break;

+  //              ::= ne        # !=

+  case OO_ExclaimEqual: Out << "ne"; break;

+  //              ::= lt        # <

+  case OO_Less: Out << "lt"; break;

+  //              ::= gt        # >

+  case OO_Greater: Out << "gt"; break;

+  //              ::= le        # <=

+  case OO_LessEqual: Out << "le"; break;

+  //              ::= ge        # >=

+  case OO_GreaterEqual: Out << "ge"; break;

+  //              ::= nt        # !

+  case OO_Exclaim: Out << "nt"; break;

+  //              ::= aa        # &&

+  case OO_AmpAmp: Out << "aa"; break;

+  //              ::= oo        # ||

+  case OO_PipePipe: Out << "oo"; break;

+  //              ::= pp        # ++

+  case OO_PlusPlus: Out << "pp"; break;

+  //              ::= mm        # --

+  case OO_MinusMinus: Out << "mm"; break;

+  //              ::= cm        # ,

+  case OO_Comma: Out << "cm"; break;

+  //              ::= pm        # ->*

+  case OO_ArrowStar: Out << "pm"; break;

+  //              ::= pt        # ->

+  case OO_Arrow: Out << "pt"; break;

+  //              ::= cl        # ()

+  case OO_Call: Out << "cl"; break;

+  //              ::= ix        # []

+  case OO_Subscript: Out << "ix"; break;

+

+  //              ::= qu        # ?

+  // The conditional operator can't be overloaded, but we still handle it when

+  // mangling expressions.

+  case OO_Conditional: Out << "qu"; break;

+

+  case OO_None:

+  case NUM_OVERLOADED_OPERATORS:

+    llvm_unreachable("Not an overloaded operator");

+  }

+}

+

+void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {

+  // <CV-qualifiers> ::= [r] [V] [K]    # restrict (C99), volatile, const

+  if (Quals.hasRestrict())

+    Out << 'r';

+  if (Quals.hasVolatile())

+    Out << 'V';

+  if (Quals.hasConst())

+    Out << 'K';

+

+  if (Quals.hasAddressSpace()) {

+    // Extension:

+    //

+    //   <type> ::= U <address-space-number>

+    // 

+    // where <address-space-number> is a source name consisting of 'AS' 

+    // followed by the address space <number>.

+    SmallString<64> ASString;

+    ASString = "AS" + llvm::utostr_32(Quals.getAddressSpace());

+    Out << 'U' << ASString.size() << ASString;

+  }

+  

+  StringRef LifetimeName;

+  switch (Quals.getObjCLifetime()) {

+  // Objective-C ARC Extension:

+  //

+  //   <type> ::= U "__strong"

+  //   <type> ::= U "__weak"

+  //   <type> ::= U "__autoreleasing"

+  case Qualifiers::OCL_None:

+    break;

+    

+  case Qualifiers::OCL_Weak:

+    LifetimeName = "__weak";

+    break;

+    

+  case Qualifiers::OCL_Strong:

+    LifetimeName = "__strong";

+    break;

+    

+  case Qualifiers::OCL_Autoreleasing:

+    LifetimeName = "__autoreleasing";

+    break;

+    

+  case Qualifiers::OCL_ExplicitNone:

+    // The __unsafe_unretained qualifier is *not* mangled, so that

+    // __unsafe_unretained types in ARC produce the same manglings as the

+    // equivalent (but, naturally, unqualified) types in non-ARC, providing

+    // better ABI compatibility.

+    //

+    // It's safe to do this because unqualified 'id' won't show up

+    // in any type signatures that need to be mangled.

+    break;

+  }

+  if (!LifetimeName.empty())

+    Out << 'U' << LifetimeName.size() << LifetimeName;

+}

+

+void CXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {

+  // <ref-qualifier> ::= R                # lvalue reference

+  //                 ::= O                # rvalue-reference

+  // Proposal to Itanium C++ ABI list on 1/26/11

+  switch (RefQualifier) {

+  case RQ_None:

+    break;

+      

+  case RQ_LValue:

+    Out << 'R';

+    break;

+      

+  case RQ_RValue:

+    Out << 'O';

+    break;

+  }

+}

+

+void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {

+  Context.mangleObjCMethodName(MD, Out);

+}

+

+void CXXNameMangler::mangleType(QualType T) {

+  // If our type is instantiation-dependent but not dependent, we mangle

+  // it as it was written in the source, removing any top-level sugar. 

+  // Otherwise, use the canonical type.

+  //

+  // FIXME: This is an approximation of the instantiation-dependent name 

+  // mangling rules, since we should really be using the type as written and

+  // augmented via semantic analysis (i.e., with implicit conversions and

+  // default template arguments) for any instantiation-dependent type. 

+  // Unfortunately, that requires several changes to our AST:

+  //   - Instantiation-dependent TemplateSpecializationTypes will need to be 

+  //     uniqued, so that we can handle substitutions properly

+  //   - Default template arguments will need to be represented in the

+  //     TemplateSpecializationType, since they need to be mangled even though

+  //     they aren't written.

+  //   - Conversions on non-type template arguments need to be expressed, since

+  //     they can affect the mangling of sizeof/alignof.

+  if (!T->isInstantiationDependentType() || T->isDependentType())

+    T = T.getCanonicalType();

+  else {

+    // Desugar any types that are purely sugar.

+    do {

+      // Don't desugar through template specialization types that aren't

+      // type aliases. We need to mangle the template arguments as written.

+      if (const TemplateSpecializationType *TST 

+                                      = dyn_cast<TemplateSpecializationType>(T))

+        if (!TST->isTypeAlias())

+          break;

+

+      QualType Desugared 

+        = T.getSingleStepDesugaredType(Context.getASTContext());

+      if (Desugared == T)

+        break;

+      

+      T = Desugared;

+    } while (true);

+  }

+  SplitQualType split = T.split();

+  Qualifiers quals = split.Quals;

+  const Type *ty = split.Ty;

+

+  bool isSubstitutable = quals || !isa<BuiltinType>(T);

+  if (isSubstitutable && mangleSubstitution(T))

+    return;

+

+  // If we're mangling a qualified array type, push the qualifiers to

+  // the element type.

+  if (quals && isa<ArrayType>(T)) {

+    ty = Context.getASTContext().getAsArrayType(T);

+    quals = Qualifiers();

+

+    // Note that we don't update T: we want to add the

+    // substitution at the original type.

+  }

+

+  if (quals) {

+    mangleQualifiers(quals);

+    // Recurse:  even if the qualified type isn't yet substitutable,

+    // the unqualified type might be.

+    mangleType(QualType(ty, 0));

+  } else {

+    switch (ty->getTypeClass()) {

+#define ABSTRACT_TYPE(CLASS, PARENT)

+#define NON_CANONICAL_TYPE(CLASS, PARENT) \

+    case Type::CLASS: \

+      llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \

+      return;

+#define TYPE(CLASS, PARENT) \

+    case Type::CLASS: \

+      mangleType(static_cast<const CLASS##Type*>(ty)); \

+      break;

+#include "clang/AST/TypeNodes.def"

+    }

+  }

+

+  // Add the substitution.

+  if (isSubstitutable)

+    addSubstitution(T);

+}

+

+void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {

+  if (!mangleStandardSubstitution(ND))

+    mangleName(ND);

+}

+

+void CXXNameMangler::mangleType(const BuiltinType *T) {

+  //  <type>         ::= <builtin-type>

+  //  <builtin-type> ::= v  # void

+  //                 ::= w  # wchar_t

+  //                 ::= b  # bool

+  //                 ::= c  # char

+  //                 ::= a  # signed char

+  //                 ::= h  # unsigned char

+  //                 ::= s  # short

+  //                 ::= t  # unsigned short

+  //                 ::= i  # int

+  //                 ::= j  # unsigned int

+  //                 ::= l  # long

+  //                 ::= m  # unsigned long

+  //                 ::= x  # long long, __int64

+  //                 ::= y  # unsigned long long, __int64

+  //                 ::= n  # __int128

+  // UNSUPPORTED:    ::= o  # unsigned __int128

+  //                 ::= f  # float

+  //                 ::= d  # double

+  //                 ::= e  # long double, __float80

+  // UNSUPPORTED:    ::= g  # __float128

+  // UNSUPPORTED:    ::= Dd # IEEE 754r decimal floating point (64 bits)

+  // UNSUPPORTED:    ::= De # IEEE 754r decimal floating point (128 bits)

+  // UNSUPPORTED:    ::= Df # IEEE 754r decimal floating point (32 bits)

+  //                 ::= Dh # IEEE 754r half-precision floating point (16 bits)

+  //                 ::= Di # char32_t

+  //                 ::= Ds # char16_t

+  //                 ::= Dn # std::nullptr_t (i.e., decltype(nullptr))

+  //                 ::= u <source-name>    # vendor extended type

+  switch (T->getKind()) {

+  case BuiltinType::Void: Out << 'v'; break;

+  case BuiltinType::Bool: Out << 'b'; break;

+  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;

+  case BuiltinType::UChar: Out << 'h'; break;

+  case BuiltinType::UShort: Out << 't'; break;

+  case BuiltinType::UInt: Out << 'j'; break;

+  case BuiltinType::ULong: Out << 'm'; break;

+  case BuiltinType::ULongLong: Out << 'y'; break;

+  case BuiltinType::UInt128: Out << 'o'; break;

+  case BuiltinType::SChar: Out << 'a'; break;

+  case BuiltinType::WChar_S:

+  case BuiltinType::WChar_U: Out << 'w'; break;

+  case BuiltinType::Char16: Out << "Ds"; break;

+  case BuiltinType::Char32: Out << "Di"; break;

+  case BuiltinType::Short: Out << 's'; break;

+  case BuiltinType::Int: Out << 'i'; break;

+  case BuiltinType::Long: Out << 'l'; break;

+  case BuiltinType::LongLong: Out << 'x'; break;

+  case BuiltinType::Int128: Out << 'n'; break;

+  case BuiltinType::Half: Out << "Dh"; break;

+  case BuiltinType::Float: Out << 'f'; break;

+  case BuiltinType::Double: Out << 'd'; break;

+  case BuiltinType::LongDouble: Out << 'e'; break;

+  case BuiltinType::NullPtr: Out << "Dn"; break;

+

+#define BUILTIN_TYPE(Id, SingletonId)

+#define PLACEHOLDER_TYPE(Id, SingletonId) \

+  case BuiltinType::Id:

+#include "clang/AST/BuiltinTypes.def"

+  case BuiltinType::Dependent:

+    llvm_unreachable("mangling a placeholder type");

+  case BuiltinType::ObjCId: Out << "11objc_object"; break;

+  case BuiltinType::ObjCClass: Out << "10objc_class"; break;

+  case BuiltinType::ObjCSel: Out << "13objc_selector"; break;

+  case BuiltinType::OCLImage1d: Out << "11ocl_image1d"; break;

+  case BuiltinType::OCLImage1dArray: Out << "16ocl_image1darray"; break;

+  case BuiltinType::OCLImage1dBuffer: Out << "17ocl_image1dbuffer"; break;

+  case BuiltinType::OCLImage2d: Out << "11ocl_image2d"; break;

+  case BuiltinType::OCLImage2dArray: Out << "16ocl_image2darray"; break;

+  case BuiltinType::OCLImage3d: Out << "11ocl_image3d"; break;

+  }

+}

+

+// <type>          ::= <function-type>

+// <function-type> ::= [<CV-qualifiers>] F [Y]

+//                      <bare-function-type> [<ref-qualifier>] E

+// (Proposal to cxx-abi-dev, 2012-05-11)

+void CXXNameMangler::mangleType(const FunctionProtoType *T) {

+  // Mangle CV-qualifiers, if present.  These are 'this' qualifiers,

+  // e.g. "const" in "int (A::*)() const".

+  mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals()));

+

+  Out << 'F';

+

+  // FIXME: We don't have enough information in the AST to produce the 'Y'

+  // encoding for extern "C" function types.

+  mangleBareFunctionType(T, /*MangleReturnType=*/true);

+

+  // Mangle the ref-qualifier, if present.

+  mangleRefQualifier(T->getRefQualifier());

+

+  Out << 'E';

+}

+void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {

+  llvm_unreachable("Can't mangle K&R function prototypes");

+}

+void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,

+                                            bool MangleReturnType) {

+  // We should never be mangling something without a prototype.

+  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);

+

+  // Record that we're in a function type.  See mangleFunctionParam

+  // for details on what we're trying to achieve here.

+  FunctionTypeDepthState saved = FunctionTypeDepth.push();

+

+  // <bare-function-type> ::= <signature type>+

+  if (MangleReturnType) {

+    FunctionTypeDepth.enterResultType();

+    mangleType(Proto->getResultType());

+    FunctionTypeDepth.leaveResultType();

+  }

+

+  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {

+    //   <builtin-type> ::= v   # void

+    Out << 'v';

+

+    FunctionTypeDepth.pop(saved);

+    return;

+  }

+

+  for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),

+                                         ArgEnd = Proto->arg_type_end();

+       Arg != ArgEnd; ++Arg)

+    mangleType(Context.getASTContext().getSignatureParameterType(*Arg));

+

+  FunctionTypeDepth.pop(saved);

+

+  // <builtin-type>      ::= z  # ellipsis

+  if (Proto->isVariadic())

+    Out << 'z';

+}

+

+// <type>            ::= <class-enum-type>

+// <class-enum-type> ::= <name>

+void CXXNameMangler::mangleType(const UnresolvedUsingType *T) {

+  mangleName(T->getDecl());

+}

+

+// <type>            ::= <class-enum-type>

+// <class-enum-type> ::= <name>

+void CXXNameMangler::mangleType(const EnumType *T) {

+  mangleType(static_cast<const TagType*>(T));

+}

+void CXXNameMangler::mangleType(const RecordType *T) {

+  mangleType(static_cast<const TagType*>(T));

+}

+void CXXNameMangler::mangleType(const TagType *T) {

+  mangleName(T->getDecl());

+}

+

+// <type>       ::= <array-type>

+// <array-type> ::= A <positive dimension number> _ <element type>

+//              ::= A [<dimension expression>] _ <element type>

+void CXXNameMangler::mangleType(const ConstantArrayType *T) {

+  Out << 'A' << T->getSize() << '_';

+  mangleType(T->getElementType());

+}

+void CXXNameMangler::mangleType(const VariableArrayType *T) {

+  Out << 'A';

+  // decayed vla types (size 0) will just be skipped.

+  if (T->getSizeExpr())

+    mangleExpression(T->getSizeExpr());

+  Out << '_';

+  mangleType(T->getElementType());

+}

+void CXXNameMangler::mangleType(const DependentSizedArrayType *T) {

+  Out << 'A';

+  mangleExpression(T->getSizeExpr());

+  Out << '_';

+  mangleType(T->getElementType());

+}

+void CXXNameMangler::mangleType(const IncompleteArrayType *T) {

+  Out << "A_";

+  mangleType(T->getElementType());

+}

+

+// <type>                   ::= <pointer-to-member-type>

+// <pointer-to-member-type> ::= M <class type> <member type>

+void CXXNameMangler::mangleType(const MemberPointerType *T) {

+  Out << 'M';

+  mangleType(QualType(T->getClass(), 0));

+  QualType PointeeType = T->getPointeeType();

+  if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {

+    mangleType(FPT);

+    

+    // Itanium C++ ABI 5.1.8:

+    //

+    //   The type of a non-static member function is considered to be different,

+    //   for the purposes of substitution, from the type of a namespace-scope or

+    //   static member function whose type appears similar. The types of two

+    //   non-static member functions are considered to be different, for the

+    //   purposes of substitution, if the functions are members of different

+    //   classes. In other words, for the purposes of substitution, the class of 

+    //   which the function is a member is considered part of the type of 

+    //   function.

+

+    // Given that we already substitute member function pointers as a

+    // whole, the net effect of this rule is just to unconditionally

+    // suppress substitution on the function type in a member pointer.

+    // We increment the SeqID here to emulate adding an entry to the

+    // substitution table.

+    ++SeqID;

+  } else

+    mangleType(PointeeType);

+}

+

+// <type>           ::= <template-param>

+void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {

+  mangleTemplateParameter(T->getIndex());

+}

+

+// <type>           ::= <template-param>

+void CXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T) {

+  // FIXME: not clear how to mangle this!

+  // template <class T...> class A {

+  //   template <class U...> void foo(T(*)(U) x...);

+  // };

+  Out << "_SUBSTPACK_";

+}

+

+// <type> ::= P <type>   # pointer-to

+void CXXNameMangler::mangleType(const PointerType *T) {

+  Out << 'P';

+  mangleType(T->getPointeeType());

+}

+void CXXNameMangler::mangleType(const ObjCObjectPointerType *T) {

+  Out << 'P';

+  mangleType(T->getPointeeType());

+}

+

+// <type> ::= R <type>   # reference-to

+void CXXNameMangler::mangleType(const LValueReferenceType *T) {

+  Out << 'R';

+  mangleType(T->getPointeeType());

+}

+

+// <type> ::= O <type>   # rvalue reference-to (C++0x)

+void CXXNameMangler::mangleType(const RValueReferenceType *T) {

+  Out << 'O';

+  mangleType(T->getPointeeType());

+}

+

+// <type> ::= C <type>   # complex pair (C 2000)

+void CXXNameMangler::mangleType(const ComplexType *T) {

+  Out << 'C';

+  mangleType(T->getElementType());

+}

+

+// ARM's ABI for Neon vector types specifies that they should be mangled as

+// if they are structs (to match ARM's initial implementation).  The

+// vector type must be one of the special types predefined by ARM.

+void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {

+  QualType EltType = T->getElementType();

+  assert(EltType->isBuiltinType() && "Neon vector element not a BuiltinType");

+  const char *EltName = 0;

+  if (T->getVectorKind() == VectorType::NeonPolyVector) {

+    switch (cast<BuiltinType>(EltType)->getKind()) {

+    case BuiltinType::SChar:     EltName = "poly8_t"; break;

+    case BuiltinType::Short:     EltName = "poly16_t"; break;

+    default: llvm_unreachable("unexpected Neon polynomial vector element type");

+    }

+  } else {

+    switch (cast<BuiltinType>(EltType)->getKind()) {

+    case BuiltinType::SChar:     EltName = "int8_t"; break;

+    case BuiltinType::UChar:     EltName = "uint8_t"; break;

+    case BuiltinType::Short:     EltName = "int16_t"; break;

+    case BuiltinType::UShort:    EltName = "uint16_t"; break;

+    case BuiltinType::Int:       EltName = "int32_t"; break;

+    case BuiltinType::UInt:      EltName = "uint32_t"; break;

+    case BuiltinType::LongLong:  EltName = "int64_t"; break;

+    case BuiltinType::ULongLong: EltName = "uint64_t"; break;

+    case BuiltinType::Float:     EltName = "float32_t"; break;

+    default: llvm_unreachable("unexpected Neon vector element type");

+    }

+  }

+  const char *BaseName = 0;

+  unsigned BitSize = (T->getNumElements() *

+                      getASTContext().getTypeSize(EltType));

+  if (BitSize == 64)

+    BaseName = "__simd64_";

+  else {

+    assert(BitSize == 128 && "Neon vector type not 64 or 128 bits");

+    BaseName = "__simd128_";

+  }

+  Out << strlen(BaseName) + strlen(EltName);

+  Out << BaseName << EltName;

+}

+

+// GNU extension: vector types

+// <type>                  ::= <vector-type>

+// <vector-type>           ::= Dv <positive dimension number> _

+//                                    <extended element type>

+//                         ::= Dv [<dimension expression>] _ <element type>

+// <extended element type> ::= <element type>

+//                         ::= p # AltiVec vector pixel

+//                         ::= b # Altivec vector bool

+void CXXNameMangler::mangleType(const VectorType *T) {

+  if ((T->getVectorKind() == VectorType::NeonVector ||

+       T->getVectorKind() == VectorType::NeonPolyVector)) {

+    mangleNeonVectorType(T);

+    return;

+  }

+  Out << "Dv" << T->getNumElements() << '_';

+  if (T->getVectorKind() == VectorType::AltiVecPixel)

+    Out << 'p';

+  else if (T->getVectorKind() == VectorType::AltiVecBool)

+    Out << 'b';

+  else

+    mangleType(T->getElementType());

+}

+void CXXNameMangler::mangleType(const ExtVectorType *T) {

+  mangleType(static_cast<const VectorType*>(T));

+}

+void CXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {

+  Out << "Dv";

+  mangleExpression(T->getSizeExpr());

+  Out << '_';

+  mangleType(T->getElementType());

+}

+

+void CXXNameMangler::mangleType(const PackExpansionType *T) {

+  // <type>  ::= Dp <type>          # pack expansion (C++0x)

+  Out << "Dp";

+  mangleType(T->getPattern());

+}

+

+void CXXNameMangler::mangleType(const ObjCInterfaceType *T) {

+  mangleSourceName(T->getDecl()->getIdentifier());

+}

+

+void CXXNameMangler::mangleType(const ObjCObjectType *T) {

+  // We don't allow overloading by different protocol qualification,

+  // so mangling them isn't necessary.

+  mangleType(T->getBaseType());

+}

+

+void CXXNameMangler::mangleType(const BlockPointerType *T) {

+  Out << "U13block_pointer";

+  mangleType(T->getPointeeType());

+}

+

+void CXXNameMangler::mangleType(const InjectedClassNameType *T) {

+  // Mangle injected class name types as if the user had written the

+  // specialization out fully.  It may not actually be possible to see

+  // this mangling, though.

+  mangleType(T->getInjectedSpecializationType());

+}

+

+void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {

+  if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) {

+    mangleName(TD, T->getArgs(), T->getNumArgs());

+  } else {

+    if (mangleSubstitution(QualType(T, 0)))

+      return;

+    

+    mangleTemplatePrefix(T->getTemplateName());

+    

+    // FIXME: GCC does not appear to mangle the template arguments when

+    // the template in question is a dependent template name. Should we

+    // emulate that badness?

+    mangleTemplateArgs(T->getArgs(), T->getNumArgs());

+    addSubstitution(QualType(T, 0));

+  }

+}

+

+void CXXNameMangler::mangleType(const DependentNameType *T) {

+  // Typename types are always nested

+  Out << 'N';

+  manglePrefix(T->getQualifier());

+  mangleSourceName(T->getIdentifier());    

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {

+  // Dependently-scoped template types are nested if they have a prefix.

+  Out << 'N';

+

+  // TODO: avoid making this TemplateName.

+  TemplateName Prefix =

+    getASTContext().getDependentTemplateName(T->getQualifier(),

+                                             T->getIdentifier());

+  mangleTemplatePrefix(Prefix);

+

+  // FIXME: GCC does not appear to mangle the template arguments when

+  // the template in question is a dependent template name. Should we

+  // emulate that badness?

+  mangleTemplateArgs(T->getArgs(), T->getNumArgs());    

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleType(const TypeOfType *T) {

+  // FIXME: this is pretty unsatisfactory, but there isn't an obvious

+  // "extension with parameters" mangling.

+  Out << "u6typeof";

+}

+

+void CXXNameMangler::mangleType(const TypeOfExprType *T) {

+  // FIXME: this is pretty unsatisfactory, but there isn't an obvious

+  // "extension with parameters" mangling.

+  Out << "u6typeof";

+}

+

+void CXXNameMangler::mangleType(const DecltypeType *T) {

+  Expr *E = T->getUnderlyingExpr();

+

+  // type ::= Dt <expression> E  # decltype of an id-expression

+  //                             #   or class member access

+  //      ::= DT <expression> E  # decltype of an expression

+

+  // This purports to be an exhaustive list of id-expressions and

+  // class member accesses.  Note that we do not ignore parentheses;

+  // parentheses change the semantics of decltype for these

+  // expressions (and cause the mangler to use the other form).

+  if (isa<DeclRefExpr>(E) ||

+      isa<MemberExpr>(E) ||

+      isa<UnresolvedLookupExpr>(E) ||

+      isa<DependentScopeDeclRefExpr>(E) ||

+      isa<CXXDependentScopeMemberExpr>(E) ||

+      isa<UnresolvedMemberExpr>(E))

+    Out << "Dt";

+  else

+    Out << "DT";

+  mangleExpression(E);

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleType(const UnaryTransformType *T) {

+  // If this is dependent, we need to record that. If not, we simply

+  // mangle it as the underlying type since they are equivalent.

+  if (T->isDependentType()) {

+    Out << 'U';

+    

+    switch (T->getUTTKind()) {

+      case UnaryTransformType::EnumUnderlyingType:

+        Out << "3eut";

+        break;

+    }

+  }

+

+  mangleType(T->getUnderlyingType());

+}

+

+void CXXNameMangler::mangleType(const AutoType *T) {

+  QualType D = T->getDeducedType();

+  // <builtin-type> ::= Da  # dependent auto

+  if (D.isNull())

+    Out << "Da";

+  else

+    mangleType(D);

+}

+

+void CXXNameMangler::mangleType(const AtomicType *T) {

+  // <type> ::= U <source-name> <type>	# vendor extended type qualifier

+  // (Until there's a standardized mangling...)

+  Out << "U7_Atomic";

+  mangleType(T->getValueType());

+}

+

+void CXXNameMangler::mangleIntegerLiteral(QualType T,

+                                          const llvm::APSInt &Value) {

+  //  <expr-primary> ::= L <type> <value number> E # integer literal

+  Out << 'L';

+

+  mangleType(T);

+  if (T->isBooleanType()) {

+    // Boolean values are encoded as 0/1.

+    Out << (Value.getBoolValue() ? '1' : '0');

+  } else {

+    mangleNumber(Value);

+  }

+  Out << 'E';

+

+}

+

+/// Mangles a member expression.

+void CXXNameMangler::mangleMemberExpr(const Expr *base,

+                                      bool isArrow,

+                                      NestedNameSpecifier *qualifier,

+                                      NamedDecl *firstQualifierLookup,

+                                      DeclarationName member,

+                                      unsigned arity) {

+  // <expression> ::= dt <expression> <unresolved-name>

+  //              ::= pt <expression> <unresolved-name>

+  if (base) {

+    if (base->isImplicitCXXThis()) {

+      // Note: GCC mangles member expressions to the implicit 'this' as

+      // *this., whereas we represent them as this->. The Itanium C++ ABI

+      // does not specify anything here, so we follow GCC.

+      Out << "dtdefpT";

+    } else {

+      Out << (isArrow ? "pt" : "dt");

+      mangleExpression(base);

+    }

+  }

+  mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity);

+}

+

+/// Look at the callee of the given call expression and determine if

+/// it's a parenthesized id-expression which would have triggered ADL

+/// otherwise.

+static bool isParenthesizedADLCallee(const CallExpr *call) {

+  const Expr *callee = call->getCallee();

+  const Expr *fn = callee->IgnoreParens();

+

+  // Must be parenthesized.  IgnoreParens() skips __extension__ nodes,

+  // too, but for those to appear in the callee, it would have to be

+  // parenthesized.

+  if (callee == fn) return false;

+

+  // Must be an unresolved lookup.

+  const UnresolvedLookupExpr *lookup = dyn_cast<UnresolvedLookupExpr>(fn);

+  if (!lookup) return false;

+

+  assert(!lookup->requiresADL());

+

+  // Must be an unqualified lookup.

+  if (lookup->getQualifier()) return false;

+

+  // Must not have found a class member.  Note that if one is a class

+  // member, they're all class members.

+  if (lookup->getNumDecls() > 0 &&

+      (*lookup->decls_begin())->isCXXClassMember())

+    return false;

+

+  // Otherwise, ADL would have been triggered.

+  return true;

+}

+

+void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {

+  // <expression> ::= <unary operator-name> <expression>

+  //              ::= <binary operator-name> <expression> <expression>

+  //              ::= <trinary operator-name> <expression> <expression> <expression>

+  //              ::= cv <type> expression           # conversion with one argument

+  //              ::= cv <type> _ <expression>* E # conversion with a different number of arguments

+  //              ::= st <type>                      # sizeof (a type)

+  //              ::= at <type>                      # alignof (a type)

+  //              ::= <template-param>

+  //              ::= <function-param>

+  //              ::= sr <type> <unqualified-name>                   # dependent name

+  //              ::= sr <type> <unqualified-name> <template-args>   # dependent template-id

+  //              ::= ds <expression> <expression>                   # expr.*expr

+  //              ::= sZ <template-param>                            # size of a parameter pack

+  //              ::= sZ <function-param>    # size of a function parameter pack

+  //              ::= <expr-primary>

+  // <expr-primary> ::= L <type> <value number> E    # integer literal

+  //                ::= L <type <value float> E      # floating literal

+  //                ::= L <mangled-name> E           # external name

+  //                ::= fpT                          # 'this' expression

+  QualType ImplicitlyConvertedToType;

+  

+recurse:

+  switch (E->getStmtClass()) {

+  case Expr::NoStmtClass:

+#define ABSTRACT_STMT(Type)

+#define EXPR(Type, Base)

+#define STMT(Type, Base) \

+  case Expr::Type##Class:

+#include "clang/AST/StmtNodes.inc"

+    // fallthrough

+

+  // These all can only appear in local or variable-initialization

+  // contexts and so should never appear in a mangling.

+  case Expr::AddrLabelExprClass:

+  case Expr::DesignatedInitExprClass:

+  case Expr::ImplicitValueInitExprClass:

+  case Expr::ParenListExprClass:

+  case Expr::LambdaExprClass:

+    llvm_unreachable("unexpected statement kind");

+

+  // FIXME: invent manglings for all these.

+  case Expr::BlockExprClass:

+  case Expr::CXXPseudoDestructorExprClass:

+  case Expr::ChooseExprClass:

+  case Expr::CompoundLiteralExprClass:

+  case Expr::ExtVectorElementExprClass:

+  case Expr::GenericSelectionExprClass:

+  case Expr::ObjCEncodeExprClass:

+  case Expr::ObjCIsaExprClass:

+  case Expr::ObjCIvarRefExprClass:

+  case Expr::ObjCMessageExprClass:

+  case Expr::ObjCPropertyRefExprClass:

+  case Expr::ObjCProtocolExprClass:

+  case Expr::ObjCSelectorExprClass:

+  case Expr::ObjCStringLiteralClass:

+  case Expr::ObjCBoxedExprClass:

+  case Expr::ObjCArrayLiteralClass:

+  case Expr::ObjCDictionaryLiteralClass:

+  case Expr::ObjCSubscriptRefExprClass:

+  case Expr::ObjCIndirectCopyRestoreExprClass:

+  case Expr::OffsetOfExprClass:

+  case Expr::PredefinedExprClass:

+  case Expr::ShuffleVectorExprClass:

+  case Expr::StmtExprClass:

+  case Expr::UnaryTypeTraitExprClass:

+  case Expr::BinaryTypeTraitExprClass:

+  case Expr::TypeTraitExprClass:

+  case Expr::ArrayTypeTraitExprClass:

+  case Expr::ExpressionTraitExprClass:

+  case Expr::VAArgExprClass:

+  case Expr::CXXUuidofExprClass:

+  case Expr::CUDAKernelCallExprClass:

+  case Expr::AsTypeExprClass:

+  case Expr::PseudoObjectExprClass:

+  case Expr::AtomicExprClass:

+  {

+    // As bad as this diagnostic is, it's better than crashing.

+    DiagnosticsEngine &Diags = Context.getDiags();

+    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+                                     "cannot yet mangle expression type %0");

+    Diags.Report(E->getExprLoc(), DiagID)

+      << E->getStmtClassName() << E->getSourceRange();

+    break;

+  }

+

+  // Even gcc-4.5 doesn't mangle this.

+  case Expr::BinaryConditionalOperatorClass: {

+    DiagnosticsEngine &Diags = Context.getDiags();

+    unsigned DiagID =

+      Diags.getCustomDiagID(DiagnosticsEngine::Error,

+                "?: operator with omitted middle operand cannot be mangled");

+    Diags.Report(E->getExprLoc(), DiagID)

+      << E->getStmtClassName() << E->getSourceRange();

+    break;

+  }

+

+  // These are used for internal purposes and cannot be meaningfully mangled.

+  case Expr::OpaqueValueExprClass:

+    llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");

+

+  case Expr::InitListExprClass: {

+    // Proposal by Jason Merrill, 2012-01-03

+    Out << "il";

+    const InitListExpr *InitList = cast<InitListExpr>(E);

+    for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)

+      mangleExpression(InitList->getInit(i));

+    Out << "E";

+    break;

+  }

+

+  case Expr::CXXDefaultArgExprClass:

+    mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr(), Arity);

+    break;

+

+  case Expr::SubstNonTypeTemplateParmExprClass:

+    mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),

+                     Arity);

+    break;

+

+  case Expr::UserDefinedLiteralClass:

+    // We follow g++'s approach of mangling a UDL as a call to the literal

+    // operator.

+  case Expr::CXXMemberCallExprClass: // fallthrough

+  case Expr::CallExprClass: {

+    const CallExpr *CE = cast<CallExpr>(E);

+

+    // <expression> ::= cp <simple-id> <expression>* E

+    // We use this mangling only when the call would use ADL except

+    // for being parenthesized.  Per discussion with David

+    // Vandervoorde, 2011.04.25.

+    if (isParenthesizedADLCallee(CE)) {

+      Out << "cp";

+      // The callee here is a parenthesized UnresolvedLookupExpr with

+      // no qualifier and should always get mangled as a <simple-id>

+      // anyway.

+

+    // <expression> ::= cl <expression>* E

+    } else {

+      Out << "cl";

+    }

+

+    mangleExpression(CE->getCallee(), CE->getNumArgs());

+    for (unsigned I = 0, N = CE->getNumArgs(); I != N; ++I)

+      mangleExpression(CE->getArg(I));

+    Out << 'E';

+    break;

+  }

+

+  case Expr::CXXNewExprClass: {

+    const CXXNewExpr *New = cast<CXXNewExpr>(E);

+    if (New->isGlobalNew()) Out << "gs";

+    Out << (New->isArray() ? "na" : "nw");

+    for (CXXNewExpr::const_arg_iterator I = New->placement_arg_begin(),

+           E = New->placement_arg_end(); I != E; ++I)

+      mangleExpression(*I);

+    Out << '_';

+    mangleType(New->getAllocatedType());

+    if (New->hasInitializer()) {

+      // Proposal by Jason Merrill, 2012-01-03

+      if (New->getInitializationStyle() == CXXNewExpr::ListInit)

+        Out << "il";

+      else

+        Out << "pi";

+      const Expr *Init = New->getInitializer();

+      if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {

+        // Directly inline the initializers.

+        for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),

+                                                  E = CCE->arg_end();

+             I != E; ++I)

+          mangleExpression(*I);

+      } else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {

+        for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)

+          mangleExpression(PLE->getExpr(i));

+      } else if (New->getInitializationStyle() == CXXNewExpr::ListInit &&

+                 isa<InitListExpr>(Init)) {

+        // Only take InitListExprs apart for list-initialization.

+        const InitListExpr *InitList = cast<InitListExpr>(Init);

+        for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)

+          mangleExpression(InitList->getInit(i));

+      } else

+        mangleExpression(Init);

+    }

+    Out << 'E';

+    break;

+  }

+

+  case Expr::MemberExprClass: {

+    const MemberExpr *ME = cast<MemberExpr>(E);

+    mangleMemberExpr(ME->getBase(), ME->isArrow(),

+                     ME->getQualifier(), 0, ME->getMemberDecl()->getDeclName(),

+                     Arity);

+    break;

+  }

+

+  case Expr::UnresolvedMemberExprClass: {

+    const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);

+    mangleMemberExpr(ME->getBase(), ME->isArrow(),

+                     ME->getQualifier(), 0, ME->getMemberName(),

+                     Arity);

+    if (ME->hasExplicitTemplateArgs())

+      mangleTemplateArgs(ME->getExplicitTemplateArgs());

+    break;

+  }

+

+  case Expr::CXXDependentScopeMemberExprClass: {

+    const CXXDependentScopeMemberExpr *ME

+      = cast<CXXDependentScopeMemberExpr>(E);

+    mangleMemberExpr(ME->getBase(), ME->isArrow(),

+                     ME->getQualifier(), ME->getFirstQualifierFoundInScope(),

+                     ME->getMember(), Arity);

+    if (ME->hasExplicitTemplateArgs())

+      mangleTemplateArgs(ME->getExplicitTemplateArgs());

+    break;

+  }

+

+  case Expr::UnresolvedLookupExprClass: {

+    const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);

+    mangleUnresolvedName(ULE->getQualifier(), 0, ULE->getName(), Arity);

+

+    // All the <unresolved-name> productions end in a

+    // base-unresolved-name, where <template-args> are just tacked

+    // onto the end.

+    if (ULE->hasExplicitTemplateArgs())

+      mangleTemplateArgs(ULE->getExplicitTemplateArgs());

+    break;

+  }

+

+  case Expr::CXXUnresolvedConstructExprClass: {

+    const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);

+    unsigned N = CE->arg_size();

+

+    Out << "cv";

+    mangleType(CE->getType());

+    if (N != 1) Out << '_';

+    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));

+    if (N != 1) Out << 'E';

+    break;

+  }

+

+  case Expr::CXXTemporaryObjectExprClass:

+  case Expr::CXXConstructExprClass: {

+    const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);

+    unsigned N = CE->getNumArgs();

+

+    // Proposal by Jason Merrill, 2012-01-03

+    if (CE->isListInitialization())

+      Out << "tl";

+    else

+      Out << "cv";

+    mangleType(CE->getType());

+    if (N != 1) Out << '_';

+    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));

+    if (N != 1) Out << 'E';

+    break;

+  }

+

+  case Expr::CXXScalarValueInitExprClass:

+    Out <<"cv";

+    mangleType(E->getType());

+    Out <<"_E";

+    break;

+

+  case Expr::CXXNoexceptExprClass:

+    Out << "nx";

+    mangleExpression(cast<CXXNoexceptExpr>(E)->getOperand());

+    break;

+

+  case Expr::UnaryExprOrTypeTraitExprClass: {

+    const UnaryExprOrTypeTraitExpr *SAE = cast<UnaryExprOrTypeTraitExpr>(E);

+    

+    if (!SAE->isInstantiationDependent()) {

+      // Itanium C++ ABI:

+      //   If the operand of a sizeof or alignof operator is not 

+      //   instantiation-dependent it is encoded as an integer literal 

+      //   reflecting the result of the operator.

+      //

+      //   If the result of the operator is implicitly converted to a known 

+      //   integer type, that type is used for the literal; otherwise, the type 

+      //   of std::size_t or std::ptrdiff_t is used.

+      QualType T = (ImplicitlyConvertedToType.isNull() || 

+                    !ImplicitlyConvertedToType->isIntegerType())? SAE->getType()

+                                                    : ImplicitlyConvertedToType;

+      llvm::APSInt V = SAE->EvaluateKnownConstInt(Context.getASTContext());

+      mangleIntegerLiteral(T, V);

+      break;

+    }

+    

+    switch(SAE->getKind()) {

+    case UETT_SizeOf:

+      Out << 's';

+      break;

+    case UETT_AlignOf:

+      Out << 'a';

+      break;

+    case UETT_VecStep:

+      DiagnosticsEngine &Diags = Context.getDiags();

+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+                                     "cannot yet mangle vec_step expression");

+      Diags.Report(DiagID);

+      return;

+    }

+    if (SAE->isArgumentType()) {

+      Out << 't';

+      mangleType(SAE->getArgumentType());

+    } else {

+      Out << 'z';

+      mangleExpression(SAE->getArgumentExpr());

+    }

+    break;

+  }

+

+  case Expr::CXXThrowExprClass: {

+    const CXXThrowExpr *TE = cast<CXXThrowExpr>(E);

+

+    // Proposal from David Vandervoorde, 2010.06.30

+    if (TE->getSubExpr()) {

+      Out << "tw";

+      mangleExpression(TE->getSubExpr());

+    } else {

+      Out << "tr";

+    }

+    break;

+  }

+

+  case Expr::CXXTypeidExprClass: {

+    const CXXTypeidExpr *TIE = cast<CXXTypeidExpr>(E);

+

+    // Proposal from David Vandervoorde, 2010.06.30

+    if (TIE->isTypeOperand()) {

+      Out << "ti";

+      mangleType(TIE->getTypeOperand());

+    } else {

+      Out << "te";

+      mangleExpression(TIE->getExprOperand());

+    }

+    break;

+  }

+

+  case Expr::CXXDeleteExprClass: {

+    const CXXDeleteExpr *DE = cast<CXXDeleteExpr>(E);

+

+    // Proposal from David Vandervoorde, 2010.06.30

+    if (DE->isGlobalDelete()) Out << "gs";

+    Out << (DE->isArrayForm() ? "da" : "dl");

+    mangleExpression(DE->getArgument());

+    break;

+  }

+

+  case Expr::UnaryOperatorClass: {

+    const UnaryOperator *UO = cast<UnaryOperator>(E);

+    mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),

+                       /*Arity=*/1);

+    mangleExpression(UO->getSubExpr());

+    break;

+  }

+

+  case Expr::ArraySubscriptExprClass: {

+    const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(E);

+

+    // Array subscript is treated as a syntactically weird form of

+    // binary operator.

+    Out << "ix";

+    mangleExpression(AE->getLHS());

+    mangleExpression(AE->getRHS());

+    break;

+  }

+

+  case Expr::CompoundAssignOperatorClass: // fallthrough

+  case Expr::BinaryOperatorClass: {

+    const BinaryOperator *BO = cast<BinaryOperator>(E);

+    if (BO->getOpcode() == BO_PtrMemD)

+      Out << "ds";

+    else

+      mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),

+                         /*Arity=*/2);

+    mangleExpression(BO->getLHS());

+    mangleExpression(BO->getRHS());

+    break;

+  }

+

+  case Expr::ConditionalOperatorClass: {

+    const ConditionalOperator *CO = cast<ConditionalOperator>(E);

+    mangleOperatorName(OO_Conditional, /*Arity=*/3);

+    mangleExpression(CO->getCond());

+    mangleExpression(CO->getLHS(), Arity);

+    mangleExpression(CO->getRHS(), Arity);

+    break;

+  }

+

+  case Expr::ImplicitCastExprClass: {

+    ImplicitlyConvertedToType = E->getType();

+    E = cast<ImplicitCastExpr>(E)->getSubExpr();

+    goto recurse;

+  }

+      

+  case Expr::ObjCBridgedCastExprClass: {

+    // Mangle ownership casts as a vendor extended operator __bridge, 

+    // __bridge_transfer, or __bridge_retain.

+    StringRef Kind = cast<ObjCBridgedCastExpr>(E)->getBridgeKindName();

+    Out << "v1U" << Kind.size() << Kind;

+  }

+  // Fall through to mangle the cast itself.

+      

+  case Expr::CStyleCastExprClass:

+  case Expr::CXXStaticCastExprClass:

+  case Expr::CXXDynamicCastExprClass:

+  case Expr::CXXReinterpretCastExprClass:

+  case Expr::CXXConstCastExprClass:

+  case Expr::CXXFunctionalCastExprClass: {

+    const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E);

+    Out << "cv";

+    mangleType(ECE->getType());

+    mangleExpression(ECE->getSubExpr());

+    break;

+  }

+

+  case Expr::CXXOperatorCallExprClass: {

+    const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);

+    unsigned NumArgs = CE->getNumArgs();

+    mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs);

+    // Mangle the arguments.

+    for (unsigned i = 0; i != NumArgs; ++i)

+      mangleExpression(CE->getArg(i));

+    break;

+  }

+

+  case Expr::ParenExprClass:

+    mangleExpression(cast<ParenExpr>(E)->getSubExpr(), Arity);

+    break;

+

+  case Expr::DeclRefExprClass: {

+    const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();

+

+    switch (D->getKind()) {

+    default:

+      //  <expr-primary> ::= L <mangled-name> E # external name

+      Out << 'L';

+      mangle(D, "_Z");

+      Out << 'E';

+      break;

+

+    case Decl::ParmVar:

+      mangleFunctionParam(cast<ParmVarDecl>(D));

+      break;

+

+    case Decl::EnumConstant: {

+      const EnumConstantDecl *ED = cast<EnumConstantDecl>(D);

+      mangleIntegerLiteral(ED->getType(), ED->getInitVal());

+      break;

+    }

+

+    case Decl::NonTypeTemplateParm: {

+      const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);

+      mangleTemplateParameter(PD->getIndex());

+      break;

+    }

+

+    }

+

+    break;

+  }

+

+  case Expr::SubstNonTypeTemplateParmPackExprClass:

+    // FIXME: not clear how to mangle this!

+    // template <unsigned N...> class A {

+    //   template <class U...> void foo(U (&x)[N]...);

+    // };

+    Out << "_SUBSTPACK_";

+    break;

+

+  case Expr::FunctionParmPackExprClass: {

+    // FIXME: not clear how to mangle this!

+    const FunctionParmPackExpr *FPPE = cast<FunctionParmPackExpr>(E);

+    Out << "v110_SUBSTPACK";

+    mangleFunctionParam(FPPE->getParameterPack());

+    break;

+  }

+

+  case Expr::DependentScopeDeclRefExprClass: {

+    const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);

+    mangleUnresolvedName(DRE->getQualifier(), 0, DRE->getDeclName(), Arity);

+

+    // All the <unresolved-name> productions end in a

+    // base-unresolved-name, where <template-args> are just tacked

+    // onto the end.

+    if (DRE->hasExplicitTemplateArgs())

+      mangleTemplateArgs(DRE->getExplicitTemplateArgs());

+    break;

+  }

+

+  case Expr::CXXBindTemporaryExprClass:

+    mangleExpression(cast<CXXBindTemporaryExpr>(E)->getSubExpr());

+    break;

+

+  case Expr::ExprWithCleanupsClass:

+    mangleExpression(cast<ExprWithCleanups>(E)->getSubExpr(), Arity);

+    break;

+

+  case Expr::FloatingLiteralClass: {

+    const FloatingLiteral *FL = cast<FloatingLiteral>(E);

+    Out << 'L';

+    mangleType(FL->getType());

+    mangleFloat(FL->getValue());

+    Out << 'E';

+    break;

+  }

+

+  case Expr::CharacterLiteralClass:

+    Out << 'L';

+    mangleType(E->getType());

+    Out << cast<CharacterLiteral>(E)->getValue();

+    Out << 'E';

+    break;

+

+  // FIXME. __objc_yes/__objc_no are mangled same as true/false

+  case Expr::ObjCBoolLiteralExprClass:

+    Out << "Lb";

+    Out << (cast<ObjCBoolLiteralExpr>(E)->getValue() ? '1' : '0');

+    Out << 'E';

+    break;

+  

+  case Expr::CXXBoolLiteralExprClass:

+    Out << "Lb";

+    Out << (cast<CXXBoolLiteralExpr>(E)->getValue() ? '1' : '0');

+    Out << 'E';

+    break;

+

+  case Expr::IntegerLiteralClass: {

+    llvm::APSInt Value(cast<IntegerLiteral>(E)->getValue());

+    if (E->getType()->isSignedIntegerType())

+      Value.setIsSigned(true);

+    mangleIntegerLiteral(E->getType(), Value);

+    break;

+  }

+

+  case Expr::ImaginaryLiteralClass: {

+    const ImaginaryLiteral *IE = cast<ImaginaryLiteral>(E);

+    // Mangle as if a complex literal.

+    // Proposal from David Vandevoorde, 2010.06.30.

+    Out << 'L';

+    mangleType(E->getType());

+    if (const FloatingLiteral *Imag =

+          dyn_cast<FloatingLiteral>(IE->getSubExpr())) {

+      // Mangle a floating-point zero of the appropriate type.

+      mangleFloat(llvm::APFloat(Imag->getValue().getSemantics()));

+      Out << '_';

+      mangleFloat(Imag->getValue());

+    } else {

+      Out << "0_";

+      llvm::APSInt Value(cast<IntegerLiteral>(IE->getSubExpr())->getValue());

+      if (IE->getSubExpr()->getType()->isSignedIntegerType())

+        Value.setIsSigned(true);

+      mangleNumber(Value);

+    }

+    Out << 'E';

+    break;

+  }

+

+  case Expr::StringLiteralClass: {

+    // Revised proposal from David Vandervoorde, 2010.07.15.

+    Out << 'L';

+    assert(isa<ConstantArrayType>(E->getType()));

+    mangleType(E->getType());

+    Out << 'E';

+    break;

+  }

+

+  case Expr::GNUNullExprClass:

+    // FIXME: should this really be mangled the same as nullptr?

+    // fallthrough

+

+  case Expr::CXXNullPtrLiteralExprClass: {

+    // Proposal from David Vandervoorde, 2010.06.30, as

+    // modified by ABI list discussion.

+    Out << "LDnE";

+    break;

+  }

+      

+  case Expr::PackExpansionExprClass:

+    Out << "sp";

+    mangleExpression(cast<PackExpansionExpr>(E)->getPattern());

+    break;

+      

+  case Expr::SizeOfPackExprClass: {

+    Out << "sZ";

+    const NamedDecl *Pack = cast<SizeOfPackExpr>(E)->getPack();

+    if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack))

+      mangleTemplateParameter(TTP->getIndex());

+    else if (const NonTypeTemplateParmDecl *NTTP

+                = dyn_cast<NonTypeTemplateParmDecl>(Pack))

+      mangleTemplateParameter(NTTP->getIndex());

+    else if (const TemplateTemplateParmDecl *TempTP

+                                    = dyn_cast<TemplateTemplateParmDecl>(Pack))

+      mangleTemplateParameter(TempTP->getIndex());

+    else

+      mangleFunctionParam(cast<ParmVarDecl>(Pack));

+    break;

+  }

+      

+  case Expr::MaterializeTemporaryExprClass: {

+    mangleExpression(cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr());

+    break;

+  }

+      

+  case Expr::CXXThisExprClass:

+    Out << "fpT";

+    break;

+  }

+}

+

+/// Mangle an expression which refers to a parameter variable.

+///

+/// <expression>     ::= <function-param>

+/// <function-param> ::= fp <top-level CV-qualifiers> _      # L == 0, I == 0

+/// <function-param> ::= fp <top-level CV-qualifiers>

+///                      <parameter-2 non-negative number> _ # L == 0, I > 0

+/// <function-param> ::= fL <L-1 non-negative number>

+///                      p <top-level CV-qualifiers> _       # L > 0, I == 0

+/// <function-param> ::= fL <L-1 non-negative number>

+///                      p <top-level CV-qualifiers>

+///                      <I-1 non-negative number> _         # L > 0, I > 0

+///

+/// L is the nesting depth of the parameter, defined as 1 if the

+/// parameter comes from the innermost function prototype scope

+/// enclosing the current context, 2 if from the next enclosing

+/// function prototype scope, and so on, with one special case: if

+/// we've processed the full parameter clause for the innermost

+/// function type, then L is one less.  This definition conveniently

+/// makes it irrelevant whether a function's result type was written

+/// trailing or leading, but is otherwise overly complicated; the

+/// numbering was first designed without considering references to

+/// parameter in locations other than return types, and then the

+/// mangling had to be generalized without changing the existing

+/// manglings.

+///

+/// I is the zero-based index of the parameter within its parameter

+/// declaration clause.  Note that the original ABI document describes

+/// this using 1-based ordinals.

+void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) {

+  unsigned parmDepth = parm->getFunctionScopeDepth();

+  unsigned parmIndex = parm->getFunctionScopeIndex();

+

+  // Compute 'L'.

+  // parmDepth does not include the declaring function prototype.

+  // FunctionTypeDepth does account for that.

+  assert(parmDepth < FunctionTypeDepth.getDepth());

+  unsigned nestingDepth = FunctionTypeDepth.getDepth() - parmDepth;

+  if (FunctionTypeDepth.isInResultType())

+    nestingDepth--;

+

+  if (nestingDepth == 0) {

+    Out << "fp";

+  } else {

+    Out << "fL" << (nestingDepth - 1) << 'p';

+  }

+

+  // Top-level qualifiers.  We don't have to worry about arrays here,

+  // because parameters declared as arrays should already have been

+  // transformed to have pointer type. FIXME: apparently these don't

+  // get mangled if used as an rvalue of a known non-class type?

+  assert(!parm->getType()->isArrayType()

+         && "parameter's type is still an array type?");

+  mangleQualifiers(parm->getType().getQualifiers());

+

+  // Parameter index.

+  if (parmIndex != 0) {

+    Out << (parmIndex - 1);

+  }

+  Out << '_';

+}

+

+void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {

+  // <ctor-dtor-name> ::= C1  # complete object constructor

+  //                  ::= C2  # base object constructor

+  //                  ::= C3  # complete object allocating constructor

+  //

+  switch (T) {

+  case Ctor_Complete:

+    Out << "C1";

+    break;

+  case Ctor_Base:

+    Out << "C2";

+    break;

+  case Ctor_CompleteAllocating:

+    Out << "C3";

+    break;

+  }

+}

+

+void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {

+  // <ctor-dtor-name> ::= D0  # deleting destructor

+  //                  ::= D1  # complete object destructor

+  //                  ::= D2  # base object destructor

+  //

+  switch (T) {

+  case Dtor_Deleting:

+    Out << "D0";

+    break;

+  case Dtor_Complete:

+    Out << "D1";

+    break;

+  case Dtor_Base:

+    Out << "D2";

+    break;

+  }

+}

+

+void CXXNameMangler::mangleTemplateArgs(

+                          const ASTTemplateArgumentListInfo &TemplateArgs) {

+  // <template-args> ::= I <template-arg>+ E

+  Out << 'I';

+  for (unsigned i = 0, e = TemplateArgs.NumTemplateArgs; i != e; ++i)

+    mangleTemplateArg(TemplateArgs.getTemplateArgs()[i].getArgument());

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &AL) {

+  // <template-args> ::= I <template-arg>+ E

+  Out << 'I';

+  for (unsigned i = 0, e = AL.size(); i != e; ++i)

+    mangleTemplateArg(AL[i]);

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,

+                                        unsigned NumTemplateArgs) {

+  // <template-args> ::= I <template-arg>+ E

+  Out << 'I';

+  for (unsigned i = 0; i != NumTemplateArgs; ++i)

+    mangleTemplateArg(TemplateArgs[i]);

+  Out << 'E';

+}

+

+void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {

+  // <template-arg> ::= <type>              # type or template

+  //                ::= X <expression> E    # expression

+  //                ::= <expr-primary>      # simple expressions

+  //                ::= J <template-arg>* E # argument pack

+  //                ::= sp <expression>     # pack expansion of (C++0x)  

+  if (!A.isInstantiationDependent() || A.isDependent())

+    A = Context.getASTContext().getCanonicalTemplateArgument(A);

+  

+  switch (A.getKind()) {

+  case TemplateArgument::Null:

+    llvm_unreachable("Cannot mangle NULL template argument");

+      

+  case TemplateArgument::Type:

+    mangleType(A.getAsType());

+    break;

+  case TemplateArgument::Template:

+    // This is mangled as <type>.

+    mangleType(A.getAsTemplate());

+    break;

+  case TemplateArgument::TemplateExpansion:

+    // <type>  ::= Dp <type>          # pack expansion (C++0x)

+    Out << "Dp";

+    mangleType(A.getAsTemplateOrTemplatePattern());

+    break;

+  case TemplateArgument::Expression: {

+    // It's possible to end up with a DeclRefExpr here in certain

+    // dependent cases, in which case we should mangle as a

+    // declaration.

+    const Expr *E = A.getAsExpr()->IgnoreParens();

+    if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {

+      const ValueDecl *D = DRE->getDecl();

+      if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) {

+        Out << "L";

+        mangle(D, "_Z");

+        Out << 'E';

+        break;

+      }

+    }

+    

+    Out << 'X';

+    mangleExpression(E);

+    Out << 'E';

+    break;

+  }

+  case TemplateArgument::Integral:

+    mangleIntegerLiteral(A.getIntegralType(), A.getAsIntegral());

+    break;

+  case TemplateArgument::Declaration: {

+    //  <expr-primary> ::= L <mangled-name> E # external name

+    // Clang produces AST's where pointer-to-member-function expressions

+    // and pointer-to-function expressions are represented as a declaration not

+    // an expression. We compensate for it here to produce the correct mangling.

+    ValueDecl *D = A.getAsDecl();

+    bool compensateMangling = !A.isDeclForReferenceParam();

+    if (compensateMangling) {

+      Out << 'X';

+      mangleOperatorName(OO_Amp, 1);

+    }

+

+    Out << 'L';

+    // References to external entities use the mangled name; if the name would

+    // not normally be manged then mangle it as unqualified.

+    //

+    // FIXME: The ABI specifies that external names here should have _Z, but

+    // gcc leaves this off.

+    if (compensateMangling)

+      mangle(D, "_Z");

+    else

+      mangle(D, "Z");

+    Out << 'E';

+

+    if (compensateMangling)

+      Out << 'E';

+

+    break;

+  }

+  case TemplateArgument::NullPtr: {

+    //  <expr-primary> ::= L <type> 0 E

+    Out << 'L';

+    mangleType(A.getNullPtrType());

+    Out << "0E";

+    break;

+  }

+  case TemplateArgument::Pack: {

+    // Note: proposal by Mike Herrick on 12/20/10

+    Out << 'J';

+    for (TemplateArgument::pack_iterator PA = A.pack_begin(), 

+                                      PAEnd = A.pack_end();

+         PA != PAEnd; ++PA)

+      mangleTemplateArg(*PA);

+    Out << 'E';

+  }

+  }

+}

+

+void CXXNameMangler::mangleTemplateParameter(unsigned Index) {

+  // <template-param> ::= T_    # first template parameter

+  //                  ::= T <parameter-2 non-negative number> _

+  if (Index == 0)

+    Out << "T_";

+  else

+    Out << 'T' << (Index - 1) << '_';

+}

+

+void CXXNameMangler::mangleExistingSubstitution(QualType type) {

+  bool result = mangleSubstitution(type);

+  assert(result && "no existing substitution for type");

+  (void) result;

+}

+

+void CXXNameMangler::mangleExistingSubstitution(TemplateName tname) {

+  bool result = mangleSubstitution(tname);

+  assert(result && "no existing substitution for template name");

+  (void) result;

+}

+

+// <substitution> ::= S <seq-id> _

+//                ::= S_

+bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {

+  // Try one of the standard substitutions first.

+  if (mangleStandardSubstitution(ND))

+    return true;

+

+  ND = cast<NamedDecl>(ND->getCanonicalDecl());

+  return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));

+}

+

+/// \brief Determine whether the given type has any qualifiers that are

+/// relevant for substitutions.

+static bool hasMangledSubstitutionQualifiers(QualType T) {

+  Qualifiers Qs = T.getQualifiers();

+  return Qs.getCVRQualifiers() || Qs.hasAddressSpace();

+}

+

+bool CXXNameMangler::mangleSubstitution(QualType T) {

+  if (!hasMangledSubstitutionQualifiers(T)) {

+    if (const RecordType *RT = T->getAs<RecordType>())

+      return mangleSubstitution(RT->getDecl());

+  }

+

+  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());

+

+  return mangleSubstitution(TypePtr);

+}

+

+bool CXXNameMangler::mangleSubstitution(TemplateName Template) {

+  if (TemplateDecl *TD = Template.getAsTemplateDecl())

+    return mangleSubstitution(TD);

+  

+  Template = Context.getASTContext().getCanonicalTemplateName(Template);

+  return mangleSubstitution(

+                      reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));

+}

+

+bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {

+  llvm::DenseMap<uintptr_t, unsigned>::iterator I = Substitutions.find(Ptr);

+  if (I == Substitutions.end())

+    return false;

+

+  unsigned SeqID = I->second;

+  if (SeqID == 0)

+    Out << "S_";

+  else {

+    SeqID--;

+

+    // <seq-id> is encoded in base-36, using digits and upper case letters.

+    char Buffer[10];

+    char *BufferPtr = llvm::array_endof(Buffer);

+

+    if (SeqID == 0) *--BufferPtr = '0';

+

+    while (SeqID) {

+      assert(BufferPtr > Buffer && "Buffer overflow!");

+

+      char c = static_cast<char>(SeqID % 36);

+

+      *--BufferPtr =  (c < 10 ? '0' + c : 'A' + c - 10);

+      SeqID /= 36;

+    }

+

+    Out << 'S'

+        << StringRef(BufferPtr, llvm::array_endof(Buffer)-BufferPtr)

+        << '_';

+  }

+

+  return true;

+}

+

+static bool isCharType(QualType T) {

+  if (T.isNull())

+    return false;

+

+  return T->isSpecificBuiltinType(BuiltinType::Char_S) ||

+    T->isSpecificBuiltinType(BuiltinType::Char_U);

+}

+

+/// isCharSpecialization - Returns whether a given type is a template

+/// specialization of a given name with a single argument of type char.

+static bool isCharSpecialization(QualType T, const char *Name) {

+  if (T.isNull())

+    return false;

+

+  const RecordType *RT = T->getAs<RecordType>();

+  if (!RT)

+    return false;

+

+  const ClassTemplateSpecializationDecl *SD =

+    dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());

+  if (!SD)

+    return false;

+

+  if (!isStdNamespace(getEffectiveDeclContext(SD)))

+    return false;

+

+  const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();

+  if (TemplateArgs.size() != 1)

+    return false;

+

+  if (!isCharType(TemplateArgs[0].getAsType()))

+    return false;

+

+  return SD->getIdentifier()->getName() == Name;

+}

+

+template <std::size_t StrLen>

+static bool isStreamCharSpecialization(const ClassTemplateSpecializationDecl*SD,

+                                       const char (&Str)[StrLen]) {

+  if (!SD->getIdentifier()->isStr(Str))

+    return false;

+

+  const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();

+  if (TemplateArgs.size() != 2)

+    return false;

+

+  if (!isCharType(TemplateArgs[0].getAsType()))

+    return false;

+

+  if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))

+    return false;

+

+  return true;

+}

+

+bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {

+  // <substitution> ::= St # ::std::

+  if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {

+    if (isStd(NS)) {

+      Out << "St";

+      return true;

+    }

+  }

+

+  if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {

+    if (!isStdNamespace(getEffectiveDeclContext(TD)))

+      return false;

+

+    // <substitution> ::= Sa # ::std::allocator

+    if (TD->getIdentifier()->isStr("allocator")) {

+      Out << "Sa";

+      return true;

+    }

+

+    // <<substitution> ::= Sb # ::std::basic_string

+    if (TD->getIdentifier()->isStr("basic_string")) {

+      Out << "Sb";

+      return true;

+    }

+  }

+

+  if (const ClassTemplateSpecializationDecl *SD =

+        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {

+    if (!isStdNamespace(getEffectiveDeclContext(SD)))

+      return false;

+

+    //    <substitution> ::= Ss # ::std::basic_string<char,

+    //                            ::std::char_traits<char>,

+    //                            ::std::allocator<char> >

+    if (SD->getIdentifier()->isStr("basic_string")) {

+      const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();

+

+      if (TemplateArgs.size() != 3)

+        return false;

+

+      if (!isCharType(TemplateArgs[0].getAsType()))

+        return false;

+

+      if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))

+        return false;

+

+      if (!isCharSpecialization(TemplateArgs[2].getAsType(), "allocator"))

+        return false;

+

+      Out << "Ss";

+      return true;

+    }

+

+    //    <substitution> ::= Si # ::std::basic_istream<char,

+    //                            ::std::char_traits<char> >

+    if (isStreamCharSpecialization(SD, "basic_istream")) {

+      Out << "Si";

+      return true;

+    }

+

+    //    <substitution> ::= So # ::std::basic_ostream<char,

+    //                            ::std::char_traits<char> >

+    if (isStreamCharSpecialization(SD, "basic_ostream")) {

+      Out << "So";

+      return true;

+    }

+

+    //    <substitution> ::= Sd # ::std::basic_iostream<char,

+    //                            ::std::char_traits<char> >

+    if (isStreamCharSpecialization(SD, "basic_iostream")) {

+      Out << "Sd";

+      return true;

+    }

+  }

+  return false;

+}

+

+void CXXNameMangler::addSubstitution(QualType T) {

+  if (!hasMangledSubstitutionQualifiers(T)) {

+    if (const RecordType *RT = T->getAs<RecordType>()) {

+      addSubstitution(RT->getDecl());

+      return;

+    }

+  }

+

+  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());

+  addSubstitution(TypePtr);

+}

+

+void CXXNameMangler::addSubstitution(TemplateName Template) {

+  if (TemplateDecl *TD = Template.getAsTemplateDecl())

+    return addSubstitution(TD);

+  

+  Template = Context.getASTContext().getCanonicalTemplateName(Template);

+  addSubstitution(reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));

+}

+

+void CXXNameMangler::addSubstitution(uintptr_t Ptr) {

+  assert(!Substitutions.count(Ptr) && "Substitution already exists!");

+  Substitutions[Ptr] = SeqID++;

+}

+

+//

+

+/// \brief Mangles the name of the declaration D and emits that name to the

+/// given output stream.

+///

+/// If the declaration D requires a mangled name, this routine will emit that

+/// mangled name to \p os and return true. Otherwise, \p os will be unchanged

+/// and this routine will return false. In this case, the caller should just

+/// emit the identifier of the declaration (\c D->getIdentifier()) as its

+/// name.

+void ItaniumMangleContext::mangleName(const NamedDecl *D,

+                                      raw_ostream &Out) {

+  assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&

+          "Invalid mangleName() call, argument is not a variable or function!");

+  assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&

+         "Invalid mangleName() call on 'structor decl!");

+

+  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),

+                                 getASTContext().getSourceManager(),

+                                 "Mangling declaration");

+

+  CXXNameMangler Mangler(*this, Out, D);

+  return Mangler.mangle(D);

+}

+

+void ItaniumMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,

+                                         CXXCtorType Type,

+                                         raw_ostream &Out) {

+  CXXNameMangler Mangler(*this, Out, D, Type);

+  Mangler.mangle(D);

+}

+

+void ItaniumMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,

+                                         CXXDtorType Type,

+                                         raw_ostream &Out) {

+  CXXNameMangler Mangler(*this, Out, D, Type);

+  Mangler.mangle(D);

+}

+

+void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD,

+                                       const ThunkInfo &Thunk,

+                                       raw_ostream &Out) {

+  //  <special-name> ::= T <call-offset> <base encoding>

+  //                      # base is the nominal target function of thunk

+  //  <special-name> ::= Tc <call-offset> <call-offset> <base encoding>

+  //                      # base is the nominal target function of thunk

+  //                      # first call-offset is 'this' adjustment

+  //                      # second call-offset is result adjustment

+  

+  assert(!isa<CXXDestructorDecl>(MD) &&

+         "Use mangleCXXDtor for destructor decls!");

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZT";

+  if (!Thunk.Return.isEmpty())

+    Mangler.getStream() << 'c';

+  

+  // Mangle the 'this' pointer adjustment.

+  Mangler.mangleCallOffset(Thunk.This.NonVirtual, Thunk.This.VCallOffsetOffset);

+  

+  // Mangle the return pointer adjustment if there is one.

+  if (!Thunk.Return.isEmpty())

+    Mangler.mangleCallOffset(Thunk.Return.NonVirtual,

+                             Thunk.Return.VBaseOffsetOffset);

+  

+  Mangler.mangleFunctionEncoding(MD);

+}

+

+void 

+ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,

+                                         CXXDtorType Type,

+                                         const ThisAdjustment &ThisAdjustment,

+                                         raw_ostream &Out) {

+  //  <special-name> ::= T <call-offset> <base encoding>

+  //                      # base is the nominal target function of thunk

+  CXXNameMangler Mangler(*this, Out, DD, Type);

+  Mangler.getStream() << "_ZT";

+

+  // Mangle the 'this' pointer adjustment.

+  Mangler.mangleCallOffset(ThisAdjustment.NonVirtual, 

+                           ThisAdjustment.VCallOffsetOffset);

+

+  Mangler.mangleFunctionEncoding(DD);

+}

+

+/// mangleGuardVariable - Returns the mangled name for a guard variable

+/// for the passed in VarDecl.

+void ItaniumMangleContext::mangleItaniumGuardVariable(const VarDecl *D,

+                                                      raw_ostream &Out) {

+  //  <special-name> ::= GV <object name>       # Guard variable for one-time

+  //                                            # initialization

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZGV";

+  Mangler.mangleName(D);

+}

+

+void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D,

+                                                    raw_ostream &Out) {

+  // We match the GCC mangling here.

+  //  <special-name> ::= GR <object name>

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZGR";

+  Mangler.mangleName(D);

+}

+

+void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,

+                                           raw_ostream &Out) {

+  // <special-name> ::= TV <type>  # virtual table

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZTV";

+  Mangler.mangleNameOrStandardSubstitution(RD);

+}

+

+void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,

+                                        raw_ostream &Out) {

+  // <special-name> ::= TT <type>  # VTT structure

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZTT";

+  Mangler.mangleNameOrStandardSubstitution(RD);

+}

+

+void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,

+                                               int64_t Offset,

+                                               const CXXRecordDecl *Type,

+                                               raw_ostream &Out) {

+  // <special-name> ::= TC <type> <offset number> _ <base type>

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZTC";

+  Mangler.mangleNameOrStandardSubstitution(RD);

+  Mangler.getStream() << Offset;

+  Mangler.getStream() << '_';

+  Mangler.mangleNameOrStandardSubstitution(Type);

+}

+

+void ItaniumMangleContext::mangleCXXRTTI(QualType Ty,

+                                         raw_ostream &Out) {

+  // <special-name> ::= TI <type>  # typeinfo structure

+  assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZTI";

+  Mangler.mangleType(Ty);

+}

+

+void ItaniumMangleContext::mangleCXXRTTIName(QualType Ty,

+                                             raw_ostream &Out) {

+  // <special-name> ::= TS <type>  # typeinfo name (null terminated byte string)

+  CXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "_ZTS";

+  Mangler.mangleType(Ty);

+}

+

+MangleContext *clang::createItaniumMangleContext(ASTContext &Context,

+                                                 DiagnosticsEngine &Diags) {

+  return new ItaniumMangleContext(Context, Diags);

+}

diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 0da7f51..a8737e7 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -1,1718 +1,1725 @@
-//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides C++ name mangling targeting the Microsoft Visual C++ ABI.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Mangle.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Basic/ABI.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include <map>
-
-using namespace clang;
-
-namespace {
-
-/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
-/// Microsoft Visual C++ ABI.
-class MicrosoftCXXNameMangler {
-  MangleContext &Context;
-  raw_ostream &Out;
-
-  // FIXME: audit the performance of BackRefMap as it might do way too many
-  // copying of strings.
-  typedef std::map<std::string, unsigned> BackRefMap;
-  BackRefMap NameBackReferences;
-  bool UseNameBackReferences;
-
-  typedef llvm::DenseMap<void*, unsigned> ArgBackRefMap;
-  ArgBackRefMap TypeBackReferences;
-
-  ASTContext &getASTContext() const { return Context.getASTContext(); }
-
-public:
-  MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)
-  : Context(C), Out(Out_), UseNameBackReferences(true) { }
-
-  raw_ostream &getStream() const { return Out; }
-
-  void mangle(const NamedDecl *D, StringRef Prefix = "\01?");
-  void mangleName(const NamedDecl *ND);
-  void mangleFunctionEncoding(const FunctionDecl *FD);
-  void mangleVariableEncoding(const VarDecl *VD);
-  void mangleNumber(int64_t Number);
-  void mangleNumber(const llvm::APSInt &Value);
-  void mangleType(QualType T, SourceRange Range, bool MangleQualifiers = true);
-
-private:
-  void disableBackReferences() { UseNameBackReferences = false; }
-  void mangleUnqualifiedName(const NamedDecl *ND) {
-    mangleUnqualifiedName(ND, ND->getDeclName());
-  }
-  void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
-  void mangleSourceName(const IdentifierInfo *II);
-  void manglePostfix(const DeclContext *DC, bool NoFunction=false);
-  void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
-  void mangleQualifiers(Qualifiers Quals, bool IsMember);
-  void manglePointerQualifiers(Qualifiers Quals);
-
-  void mangleUnscopedTemplateName(const TemplateDecl *ND);
-  void mangleTemplateInstantiationName(const TemplateDecl *TD,
-                      const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs);
-  void mangleObjCMethodName(const ObjCMethodDecl *MD);
-  void mangleLocalName(const FunctionDecl *FD);
-
-  void mangleArgumentType(QualType T, SourceRange Range);
-
-  // Declare manglers for every type class.
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define NON_CANONICAL_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
-                                            SourceRange Range);
-#include "clang/AST/TypeNodes.def"
-#undef ABSTRACT_TYPE
-#undef NON_CANONICAL_TYPE
-#undef TYPE
-  
-  void mangleType(const TagType*);
-  void mangleType(const FunctionType *T, const FunctionDecl *D,
-                  bool IsStructor, bool IsInstMethod);
-  void mangleType(const ArrayType *T, bool IsGlobal);
-  void mangleExtraDimensions(QualType T);
-  void mangleFunctionClass(const FunctionDecl *FD);
-  void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false);
-  void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean);
-  void mangleExpression(const Expr *E);
-  void mangleThrowSpecification(const FunctionProtoType *T);
-
-  void mangleTemplateArgs(
-                      const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs);
-
-};
-
-/// MicrosoftMangleContext - Overrides the default MangleContext for the
-/// Microsoft Visual C++ ABI.
-class MicrosoftMangleContext : public MangleContext {
-public:
-  MicrosoftMangleContext(ASTContext &Context,
-                   DiagnosticsEngine &Diags) : MangleContext(Context, Diags) { }
-  virtual bool shouldMangleDeclName(const NamedDecl *D);
-  virtual void mangleName(const NamedDecl *D, raw_ostream &Out);
-  virtual void mangleThunk(const CXXMethodDecl *MD,
-                           const ThunkInfo &Thunk,
-                           raw_ostream &);
-  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
-                                  const ThisAdjustment &ThisAdjustment,
-                                  raw_ostream &);
-  virtual void mangleCXXVTable(const CXXRecordDecl *RD,
-                               raw_ostream &);
-  virtual void mangleCXXVTT(const CXXRecordDecl *RD,
-                            raw_ostream &);
-  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
-                                   const CXXRecordDecl *Type,
-                                   raw_ostream &);
-  virtual void mangleCXXRTTI(QualType T, raw_ostream &);
-  virtual void mangleCXXRTTIName(QualType T, raw_ostream &);
-  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
-                             raw_ostream &);
-  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
-                             raw_ostream &);
-  virtual void mangleReferenceTemporary(const clang::VarDecl *,
-                                        raw_ostream &);
-};
-
-}
-
-static bool isInCLinkageSpecification(const Decl *D) {
-  D = D->getCanonicalDecl();
-  for (const DeclContext *DC = D->getDeclContext();
-       !DC->isTranslationUnit(); DC = DC->getParent()) {
-    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
-      return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
-  }
-
-  return false;
-}
-
-bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {
-  // In C, functions with no attributes never need to be mangled. Fastpath them.
-  if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
-    return false;
-
-  // Any decl can be declared with __asm("foo") on it, and this takes precedence
-  // over all other naming in the .o file.
-  if (D->hasAttr<AsmLabelAttr>())
-    return true;
-
-  // Clang's "overloadable" attribute extension to C/C++ implies name mangling
-  // (always) as does passing a C++ member function and a function
-  // whose name is not a simple identifier.
-  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||
-             !FD->getDeclName().isIdentifier()))
-    return true;
-
-  // Otherwise, no mangling is done outside C++ mode.
-  if (!getASTContext().getLangOpts().CPlusPlus)
-    return false;
-
-  // Variables at global scope with internal linkage are not mangled.
-  if (!FD) {
-    const DeclContext *DC = D->getDeclContext();
-    if (DC->isTranslationUnit() && D->getLinkage() == InternalLinkage)
-      return false;
-  }
-
-  // C functions and "main" are not mangled.
-  if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
-    return false;
-
-  return true;
-}
-
-void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
-                                     StringRef Prefix) {
-  // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
-  // Therefore it's really important that we don't decorate the
-  // name with leading underscores or leading/trailing at signs. So, by
-  // default, we emit an asm marker at the start so we get the name right.
-  // Callers can override this with a custom prefix.
-
-  // Any decl can be declared with __asm("foo") on it, and this takes precedence
-  // over all other naming in the .o file.
-  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
-    // If we have an asm name, then we use it as the mangling.
-    Out << '\01' << ALA->getLabel();
-    return;
-  }
-
-  // <mangled-name> ::= ? <name> <type-encoding>
-  Out << Prefix;
-  mangleName(D);
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    mangleFunctionEncoding(FD);
-  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
-    mangleVariableEncoding(VD);
-  else {
-    // TODO: Fields? Can MSVC even mangle them?
-    // Issue a diagnostic for now.
-    DiagnosticsEngine &Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-      "cannot mangle this declaration yet");
-    Diags.Report(D->getLocation(), DiagID)
-      << D->getSourceRange();
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
-  // <type-encoding> ::= <function-class> <function-type>
-
-  // Don't mangle in the type if this isn't a decl we should typically mangle.
-  if (!Context.shouldMangleDeclName(FD))
-    return;
-  
-  // We should never ever see a FunctionNoProtoType at this point.
-  // We don't even know how to mangle their types anyway :).
-  const FunctionProtoType *FT = FD->getType()->castAs<FunctionProtoType>();
-
-  bool InStructor = false, InInstMethod = false;
-  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
-  if (MD) {
-    if (MD->isInstance())
-      InInstMethod = true;
-    if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
-      InStructor = true;
-  }
-
-  // First, the function class.
-  mangleFunctionClass(FD);
-
-  mangleType(FT, FD, InStructor, InInstMethod);
-}
-
-void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
-  // <type-encoding> ::= <storage-class> <variable-type>
-  // <storage-class> ::= 0  # private static member
-  //                 ::= 1  # protected static member
-  //                 ::= 2  # public static member
-  //                 ::= 3  # global
-  //                 ::= 4  # static local
-  
-  // The first character in the encoding (after the name) is the storage class.
-  if (VD->isStaticDataMember()) {
-    // If it's a static member, it also encodes the access level.
-    switch (VD->getAccess()) {
-      default:
-      case AS_private: Out << '0'; break;
-      case AS_protected: Out << '1'; break;
-      case AS_public: Out << '2'; break;
-    }
-  }
-  else if (!VD->isStaticLocal())
-    Out << '3';
-  else
-    Out << '4';
-  // Now mangle the type.
-  // <variable-type> ::= <type> <cvr-qualifiers>
-  //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
-  // Pointers and references are odd. The type of 'int * const foo;' gets
-  // mangled as 'QAHA' instead of 'PAHB', for example.
-  TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
-  QualType Ty = TL.getType();
-  if (Ty->isPointerType() || Ty->isReferenceType()) {
-    mangleType(Ty, TL.getSourceRange());
-    mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
-  } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
-    // Global arrays are funny, too.
-    mangleType(AT, true);
-    mangleQualifiers(Ty.getQualifiers(), false);
-  } else {
-    mangleType(Ty.getLocalUnqualifiedType(), TL.getSourceRange());
-    mangleQualifiers(Ty.getLocalQualifiers(), false);
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
-  // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
-  const DeclContext *DC = ND->getDeclContext();
-
-  // Always start with the unqualified name.
-  mangleUnqualifiedName(ND);    
-
-  // If this is an extern variable declared locally, the relevant DeclContext
-  // is that of the containing namespace, or the translation unit.
-  if (isa<FunctionDecl>(DC) && ND->hasLinkage())
-    while (!DC->isNamespace() && !DC->isTranslationUnit())
-      DC = DC->getParent();
-
-  manglePostfix(DC);
-
-  // Terminate the whole name with an '@'.
-  Out << '@';
-}
-
-void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
-  llvm::APSInt APSNumber(/*BitWidth=*/64, /*isUnsigned=*/false);
-  APSNumber = Number;
-  mangleNumber(APSNumber);
-}
-
-void MicrosoftCXXNameMangler::mangleNumber(const llvm::APSInt &Value) {
-  // <number> ::= [?] <decimal digit> # 1 <= Number <= 10
-  //          ::= [?] <hex digit>+ @ # 0 or > 9; A = 0, B = 1, etc...
-  //          ::= [?] @ # 0 (alternate mangling, not emitted by VC)
-  if (Value.isSigned() && Value.isNegative()) {
-    Out << '?';
-    mangleNumber(llvm::APSInt(Value.abs()));
-    return;
-  }
-  llvm::APSInt Temp(Value);
-  // There's a special shorter mangling for 0, but Microsoft
-  // chose not to use it. Instead, 0 gets mangled as "A@". Oh well...
-  if (Value.uge(1) && Value.ule(10)) {
-    --Temp;
-    Temp.print(Out, false);
-  } else {
-    // We have to build up the encoding in reverse order, so it will come
-    // out right when we write it out.
-    char Encoding[64];
-    char *EndPtr = Encoding+sizeof(Encoding);
-    char *CurPtr = EndPtr;
-    llvm::APSInt NibbleMask(Value.getBitWidth(), Value.isUnsigned());
-    NibbleMask = 0xf;
-    do {
-      *--CurPtr = 'A' + Temp.And(NibbleMask).getLimitedValue(0xf);
-      Temp = Temp.lshr(4);
-    } while (Temp != 0);
-    Out.write(CurPtr, EndPtr-CurPtr);
-    Out << '@';
-  }
-}
-
-static const TemplateDecl *
-isTemplate(const NamedDecl *ND,
-           SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {
-  // Check if we have a function template.
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
-    if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
-      if (FD->getTemplateSpecializationArgsAsWritten()) {
-        const ASTTemplateArgumentListInfo *ArgList =
-          FD->getTemplateSpecializationArgsAsWritten();
-        TemplateArgs.append(ArgList->getTemplateArgs(),
-                            ArgList->getTemplateArgs() +
-                              ArgList->NumTemplateArgs);
-      } else {
-        const TemplateArgumentList *ArgList =
-          FD->getTemplateSpecializationArgs();
-        TemplateArgumentListInfo LI;
-        for (unsigned i = 0, e = ArgList->size(); i != e; ++i)
-          TemplateArgs.push_back(TemplateArgumentLoc(ArgList->get(i),
-                                                     FD->getTypeSourceInfo()));
-      }
-      return TD;
-    }
-  }
-
-  // Check if we have a class template.
-  if (const ClassTemplateSpecializationDecl *Spec =
-      dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
-    TypeSourceInfo *TSI = Spec->getTypeAsWritten();
-    if (TSI) {
-      TemplateSpecializationTypeLoc TSTL =
-        cast<TemplateSpecializationTypeLoc>(TSI->getTypeLoc());
-      TemplateArgumentListInfo LI(TSTL.getLAngleLoc(), TSTL.getRAngleLoc());
-      for (unsigned i = 0, e = TSTL.getNumArgs(); i != e; ++i)
-        TemplateArgs.push_back(TSTL.getArgLoc(i));
-    } else {
-      TemplateArgumentListInfo LI;
-      const TemplateArgumentList &ArgList =
-        Spec->getTemplateArgs();
-      for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
-        TemplateArgs.push_back(TemplateArgumentLoc(ArgList[i],
-                                                   TemplateArgumentLocInfo()));
-    }
-    return Spec->getSpecializedTemplate();
-  }
-
-  return 0;
-}
-
-void
-MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
-                                               DeclarationName Name) {
-  //  <unqualified-name> ::= <operator-name>
-  //                     ::= <ctor-dtor-name>
-  //                     ::= <source-name>
-  //                     ::= <template-name>
-  SmallVector<TemplateArgumentLoc, 2> TemplateArgs;
-  // Check if we have a template.
-  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
-    // We have a template.
-    // Here comes the tricky thing: if we need to mangle something like
-    //   void foo(A::X<Y>, B::X<Y>),
-    // the X<Y> part is aliased. However, if you need to mangle
-    //   void foo(A::X<A::Y>, A::X<B::Y>),
-    // the A::X<> part is not aliased.
-    // That said, from the mangler's perspective we have a structure like this:
-    //   namespace[s] -> type[ -> template-parameters]
-    // but from the Clang perspective we have
-    //   type [ -> template-parameters]
-    //      \-> namespace[s]
-    // What we do is we create a new mangler, mangle the same type (without
-    // a namespace suffix) using the extra mangler with back references
-    // disabled (to avoid infinite recursion) and then use the mangled type
-    // name as a key to check the mangling of different types for aliasing.
-
-    std::string BackReferenceKey;
-    BackRefMap::iterator Found;
-    if (UseNameBackReferences) {
-      llvm::raw_string_ostream Stream(BackReferenceKey);
-      MicrosoftCXXNameMangler Extra(Context, Stream);
-      Extra.disableBackReferences();
-      Extra.mangleUnqualifiedName(ND, Name);
-      Stream.flush();
-
-      Found = NameBackReferences.find(BackReferenceKey);
-    }
-    if (!UseNameBackReferences || Found == NameBackReferences.end()) {
-      mangleTemplateInstantiationName(TD, TemplateArgs);
-      if (UseNameBackReferences && NameBackReferences.size() < 10) {
-        size_t Size = NameBackReferences.size();
-        NameBackReferences[BackReferenceKey] = Size;
-      }
-    } else {
-      Out << Found->second;
-    }
-    return;
-  }
-
-  switch (Name.getNameKind()) {
-    case DeclarationName::Identifier: {
-      if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
-        mangleSourceName(II);
-        break;
-      }
-      
-      // Otherwise, an anonymous entity.  We must have a declaration.
-      assert(ND && "mangling empty name without declaration");
-      
-      if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
-        if (NS->isAnonymousNamespace()) {
-          Out << "?A@";
-          break;
-        }
-      }
-      
-      // We must have an anonymous struct.
-      const TagDecl *TD = cast<TagDecl>(ND);
-      if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
-        assert(TD->getDeclContext() == D->getDeclContext() &&
-               "Typedef should not be in another decl context!");
-        assert(D->getDeclName().getAsIdentifierInfo() &&
-               "Typedef was not named!");
-        mangleSourceName(D->getDeclName().getAsIdentifierInfo());
-        break;
-      }
-
-      // When VC encounters an anonymous type with no tag and no typedef,
-      // it literally emits '<unnamed-tag>'.
-      Out << "<unnamed-tag>";
-      break;
-    }
-      
-    case DeclarationName::ObjCZeroArgSelector:
-    case DeclarationName::ObjCOneArgSelector:
-    case DeclarationName::ObjCMultiArgSelector:
-      llvm_unreachable("Can't mangle Objective-C selector names here!");
-      
-    case DeclarationName::CXXConstructorName:
-      Out << "?0";
-      break;
-      
-    case DeclarationName::CXXDestructorName:
-      Out << "?1";
-      break;
-      
-    case DeclarationName::CXXConversionFunctionName:
-      // <operator-name> ::= ?B # (cast)
-      // The target type is encoded as the return type.
-      Out << "?B";
-      break;
-      
-    case DeclarationName::CXXOperatorName:
-      mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());
-      break;
-      
-    case DeclarationName::CXXLiteralOperatorName: {
-      // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
-      DiagnosticsEngine Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle this literal operator yet");
-      Diags.Report(ND->getLocation(), DiagID);
-      break;
-    }
-      
-    case DeclarationName::CXXUsingDirective:
-      llvm_unreachable("Can't mangle a using directive name!");
-  }
-}
-
-void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
-                                            bool NoFunction) {
-  // <postfix> ::= <unqualified-name> [<postfix>]
-  //           ::= <substitution> [<postfix>]
-
-  if (!DC) return;
-
-  while (isa<LinkageSpecDecl>(DC))
-    DC = DC->getParent();
-
-  if (DC->isTranslationUnit())
-    return;
-
-  if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
-    Context.mangleBlock(BD, Out);
-    Out << '@';
-    return manglePostfix(DC->getParent(), NoFunction);
-  }
-
-  if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
-    return;
-  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
-    mangleObjCMethodName(Method);
-  else if (const FunctionDecl *Func = dyn_cast<FunctionDecl>(DC))
-    mangleLocalName(Func);
-  else {
-    mangleUnqualifiedName(cast<NamedDecl>(DC));
-    manglePostfix(DC->getParent(), NoFunction);
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
-                                                 SourceLocation Loc) {
-  switch (OO) {
-  //                     ?0 # constructor
-  //                     ?1 # destructor
-  // <operator-name> ::= ?2 # new
-  case OO_New: Out << "?2"; break;
-  // <operator-name> ::= ?3 # delete
-  case OO_Delete: Out << "?3"; break;
-  // <operator-name> ::= ?4 # =
-  case OO_Equal: Out << "?4"; break;
-  // <operator-name> ::= ?5 # >>
-  case OO_GreaterGreater: Out << "?5"; break;
-  // <operator-name> ::= ?6 # <<
-  case OO_LessLess: Out << "?6"; break;
-  // <operator-name> ::= ?7 # !
-  case OO_Exclaim: Out << "?7"; break;
-  // <operator-name> ::= ?8 # ==
-  case OO_EqualEqual: Out << "?8"; break;
-  // <operator-name> ::= ?9 # !=
-  case OO_ExclaimEqual: Out << "?9"; break;
-  // <operator-name> ::= ?A # []
-  case OO_Subscript: Out << "?A"; break;
-  //                     ?B # conversion
-  // <operator-name> ::= ?C # ->
-  case OO_Arrow: Out << "?C"; break;
-  // <operator-name> ::= ?D # *
-  case OO_Star: Out << "?D"; break;
-  // <operator-name> ::= ?E # ++
-  case OO_PlusPlus: Out << "?E"; break;
-  // <operator-name> ::= ?F # --
-  case OO_MinusMinus: Out << "?F"; break;
-  // <operator-name> ::= ?G # -
-  case OO_Minus: Out << "?G"; break;
-  // <operator-name> ::= ?H # +
-  case OO_Plus: Out << "?H"; break;
-  // <operator-name> ::= ?I # &
-  case OO_Amp: Out << "?I"; break;
-  // <operator-name> ::= ?J # ->*
-  case OO_ArrowStar: Out << "?J"; break;
-  // <operator-name> ::= ?K # /
-  case OO_Slash: Out << "?K"; break;
-  // <operator-name> ::= ?L # %
-  case OO_Percent: Out << "?L"; break;
-  // <operator-name> ::= ?M # <
-  case OO_Less: Out << "?M"; break;
-  // <operator-name> ::= ?N # <=
-  case OO_LessEqual: Out << "?N"; break;
-  // <operator-name> ::= ?O # >
-  case OO_Greater: Out << "?O"; break;
-  // <operator-name> ::= ?P # >=
-  case OO_GreaterEqual: Out << "?P"; break;
-  // <operator-name> ::= ?Q # ,
-  case OO_Comma: Out << "?Q"; break;
-  // <operator-name> ::= ?R # ()
-  case OO_Call: Out << "?R"; break;
-  // <operator-name> ::= ?S # ~
-  case OO_Tilde: Out << "?S"; break;
-  // <operator-name> ::= ?T # ^
-  case OO_Caret: Out << "?T"; break;
-  // <operator-name> ::= ?U # |
-  case OO_Pipe: Out << "?U"; break;
-  // <operator-name> ::= ?V # &&
-  case OO_AmpAmp: Out << "?V"; break;
-  // <operator-name> ::= ?W # ||
-  case OO_PipePipe: Out << "?W"; break;
-  // <operator-name> ::= ?X # *=
-  case OO_StarEqual: Out << "?X"; break;
-  // <operator-name> ::= ?Y # +=
-  case OO_PlusEqual: Out << "?Y"; break;
-  // <operator-name> ::= ?Z # -=
-  case OO_MinusEqual: Out << "?Z"; break;
-  // <operator-name> ::= ?_0 # /=
-  case OO_SlashEqual: Out << "?_0"; break;
-  // <operator-name> ::= ?_1 # %=
-  case OO_PercentEqual: Out << "?_1"; break;
-  // <operator-name> ::= ?_2 # >>=
-  case OO_GreaterGreaterEqual: Out << "?_2"; break;
-  // <operator-name> ::= ?_3 # <<=
-  case OO_LessLessEqual: Out << "?_3"; break;
-  // <operator-name> ::= ?_4 # &=
-  case OO_AmpEqual: Out << "?_4"; break;
-  // <operator-name> ::= ?_5 # |=
-  case OO_PipeEqual: Out << "?_5"; break;
-  // <operator-name> ::= ?_6 # ^=
-  case OO_CaretEqual: Out << "?_6"; break;
-  //                     ?_7 # vftable
-  //                     ?_8 # vbtable
-  //                     ?_9 # vcall
-  //                     ?_A # typeof
-  //                     ?_B # local static guard
-  //                     ?_C # string
-  //                     ?_D # vbase destructor
-  //                     ?_E # vector deleting destructor
-  //                     ?_F # default constructor closure
-  //                     ?_G # scalar deleting destructor
-  //                     ?_H # vector constructor iterator
-  //                     ?_I # vector destructor iterator
-  //                     ?_J # vector vbase constructor iterator
-  //                     ?_K # virtual displacement map
-  //                     ?_L # eh vector constructor iterator
-  //                     ?_M # eh vector destructor iterator
-  //                     ?_N # eh vector vbase constructor iterator
-  //                     ?_O # copy constructor closure
-  //                     ?_P<name> # udt returning <name>
-  //                     ?_Q # <unknown>
-  //                     ?_R0 # RTTI Type Descriptor
-  //                     ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
-  //                     ?_R2 # RTTI Base Class Array
-  //                     ?_R3 # RTTI Class Hierarchy Descriptor
-  //                     ?_R4 # RTTI Complete Object Locator
-  //                     ?_S # local vftable
-  //                     ?_T # local vftable constructor closure
-  // <operator-name> ::= ?_U # new[]
-  case OO_Array_New: Out << "?_U"; break;
-  // <operator-name> ::= ?_V # delete[]
-  case OO_Array_Delete: Out << "?_V"; break;
-    
-  case OO_Conditional: {
-    DiagnosticsEngine &Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-      "cannot mangle this conditional operator yet");
-    Diags.Report(Loc, DiagID);
-    break;
-  }
-    
-  case OO_None:
-  case NUM_OVERLOADED_OPERATORS:
-    llvm_unreachable("Not an overloaded operator");
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
-  // <source name> ::= <identifier> @
-  std::string key = II->getNameStart();
-  BackRefMap::iterator Found;
-  if (UseNameBackReferences)
-    Found = NameBackReferences.find(key);
-  if (!UseNameBackReferences || Found == NameBackReferences.end()) {
-    Out << II->getName() << '@';
-    if (UseNameBackReferences && NameBackReferences.size() < 10) {
-      size_t Size = NameBackReferences.size();
-      NameBackReferences[key] = Size;
-    }
-  } else {
-    Out << Found->second;
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
-  Context.mangleObjCMethodName(MD, Out);
-}
-
-// Find out how many function decls live above this one and return an integer
-// suitable for use as the number in a numbered anonymous scope.
-// TODO: Memoize.
-static unsigned getLocalNestingLevel(const FunctionDecl *FD) {
-  const DeclContext *DC = FD->getParent();
-  int level = 1;
-
-  while (DC && !DC->isTranslationUnit()) {
-    if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) level++;
-    DC = DC->getParent();
-  }
-
-  return 2*level;
-}
-
-void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) {
-  // <nested-name> ::= <numbered-anonymous-scope> ? <mangled-name>
-  // <numbered-anonymous-scope> ::= ? <number>
-  // Even though the name is rendered in reverse order (e.g.
-  // A::B::C is rendered as C@B@A), VC numbers the scopes from outermost to
-  // innermost. So a method bar in class C local to function foo gets mangled
-  // as something like:
-  // ?bar@C@?1??foo@@YAXXZ@QAEXXZ
-  // This is more apparent when you have a type nested inside a method of a
-  // type nested inside a function. A method baz in class D local to method
-  // bar of class C local to function foo gets mangled as:
-  // ?baz@D@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ
-  // This scheme is general enough to support GCC-style nested
-  // functions. You could have a method baz of class C inside a function bar
-  // inside a function foo, like so:
-  // ?baz@C@?3??bar@?1??foo@@YAXXZ@YAXXZ@QAEXXZ
-  int NestLevel = getLocalNestingLevel(FD);
-  Out << '?';
-  mangleNumber(NestLevel);
-  Out << '?';
-  mangle(FD, "?");
-}
-
-void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
-                                                         const TemplateDecl *TD,
-                     const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {
-  // <template-name> ::= <unscoped-template-name> <template-args>
-  //                 ::= <substitution>
-  // Always start with the unqualified name.
-
-  // Templates have their own context for back references.
-  ArgBackRefMap OuterArgsContext;
-  BackRefMap OuterTemplateContext;
-  NameBackReferences.swap(OuterTemplateContext);
-  TypeBackReferences.swap(OuterArgsContext);
-
-  mangleUnscopedTemplateName(TD);
-  mangleTemplateArgs(TemplateArgs);
-
-  // Restore the previous back reference contexts.
-  NameBackReferences.swap(OuterTemplateContext);
-  TypeBackReferences.swap(OuterArgsContext);
-}
-
-void
-MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) {
-  // <unscoped-template-name> ::= ?$ <unqualified-name>
-  Out << "?$";
-  mangleUnqualifiedName(TD);
-}
-
-void
-MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
-                                              bool IsBoolean) {
-  // <integer-literal> ::= $0 <number>
-  Out << "$0";
-  // Make sure booleans are encoded as 0/1.
-  if (IsBoolean && Value.getBoolValue())
-    mangleNumber(1);
-  else
-    mangleNumber(Value);
-}
-
-void
-MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
-  // See if this is a constant expression.
-  llvm::APSInt Value;
-  if (E->isIntegerConstantExpr(Value, Context.getASTContext())) {
-    mangleIntegerLiteral(Value, E->getType()->isBooleanType());
-    return;
-  }
-
-  // As bad as this diagnostic is, it's better than crashing.
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                   "cannot yet mangle expression type %0");
-  Diags.Report(E->getExprLoc(), DiagID)
-    << E->getStmtClassName() << E->getSourceRange();
-}
-
-void
-MicrosoftCXXNameMangler::mangleTemplateArgs(
-                     const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {
-  // <template-args> ::= {<type> | <integer-literal>}+ @
-  unsigned NumTemplateArgs = TemplateArgs.size();
-  for (unsigned i = 0; i < NumTemplateArgs; ++i) {
-    const TemplateArgumentLoc &TAL = TemplateArgs[i];
-    const TemplateArgument &TA = TAL.getArgument();
-    switch (TA.getKind()) {
-    case TemplateArgument::Null:
-      llvm_unreachable("Can't mangle null template arguments!");
-    case TemplateArgument::Type:
-      mangleType(TA.getAsType(), TAL.getSourceRange());
-      break;
-    case TemplateArgument::Integral:
-      mangleIntegerLiteral(TA.getAsIntegral(),
-                           TA.getIntegralType()->isBooleanType());
-      break;
-    case TemplateArgument::Expression:
-      mangleExpression(TA.getAsExpr());
-      break;
-    case TemplateArgument::Template:
-    case TemplateArgument::TemplateExpansion:
-    case TemplateArgument::Declaration:
-    case TemplateArgument::NullPtr:
-    case TemplateArgument::Pack: {
-      // Issue a diagnostic.
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle this %select{ERROR|ERROR|pointer/reference|nullptr|"
-        "integral|template|template pack expansion|ERROR|parameter pack}0 "
-        "template argument yet");
-      Diags.Report(TAL.getLocation(), DiagID)
-        << TA.getKind()
-        << TAL.getSourceRange();
-    }
-    }
-  }
-  Out << '@';
-}
-
-void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
-                                               bool IsMember) {
-  // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
-  // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
-  // 'I' means __restrict (32/64-bit).
-  // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
-  // keyword!
-  // <base-cvr-qualifiers> ::= A  # near
-  //                       ::= B  # near const
-  //                       ::= C  # near volatile
-  //                       ::= D  # near const volatile
-  //                       ::= E  # far (16-bit)
-  //                       ::= F  # far const (16-bit)
-  //                       ::= G  # far volatile (16-bit)
-  //                       ::= H  # far const volatile (16-bit)
-  //                       ::= I  # huge (16-bit)
-  //                       ::= J  # huge const (16-bit)
-  //                       ::= K  # huge volatile (16-bit)
-  //                       ::= L  # huge const volatile (16-bit)
-  //                       ::= M <basis> # based
-  //                       ::= N <basis> # based const
-  //                       ::= O <basis> # based volatile
-  //                       ::= P <basis> # based const volatile
-  //                       ::= Q  # near member
-  //                       ::= R  # near const member
-  //                       ::= S  # near volatile member
-  //                       ::= T  # near const volatile member
-  //                       ::= U  # far member (16-bit)
-  //                       ::= V  # far const member (16-bit)
-  //                       ::= W  # far volatile member (16-bit)
-  //                       ::= X  # far const volatile member (16-bit)
-  //                       ::= Y  # huge member (16-bit)
-  //                       ::= Z  # huge const member (16-bit)
-  //                       ::= 0  # huge volatile member (16-bit)
-  //                       ::= 1  # huge const volatile member (16-bit)
-  //                       ::= 2 <basis> # based member
-  //                       ::= 3 <basis> # based const member
-  //                       ::= 4 <basis> # based volatile member
-  //                       ::= 5 <basis> # based const volatile member
-  //                       ::= 6  # near function (pointers only)
-  //                       ::= 7  # far function (pointers only)
-  //                       ::= 8  # near method (pointers only)
-  //                       ::= 9  # far method (pointers only)
-  //                       ::= _A <basis> # based function (pointers only)
-  //                       ::= _B <basis> # based function (far?) (pointers only)
-  //                       ::= _C <basis> # based method (pointers only)
-  //                       ::= _D <basis> # based method (far?) (pointers only)
-  //                       ::= _E # block (Clang)
-  // <basis> ::= 0 # __based(void)
-  //         ::= 1 # __based(segment)?
-  //         ::= 2 <name> # __based(name)
-  //         ::= 3 # ?
-  //         ::= 4 # ?
-  //         ::= 5 # not really based
-  bool HasConst = Quals.hasConst(),
-       HasVolatile = Quals.hasVolatile();
-  if (!IsMember) {
-    if (HasConst && HasVolatile) {
-      Out << 'D';
-    } else if (HasVolatile) {
-      Out << 'C';
-    } else if (HasConst) {
-      Out << 'B';
-    } else {
-      Out << 'A';
-    }
-  } else {
-    if (HasConst && HasVolatile) {
-      Out << 'T';
-    } else if (HasVolatile) {
-      Out << 'S';
-    } else if (HasConst) {
-      Out << 'R';
-    } else {
-      Out << 'Q';
-    }
-  }
-
-  // FIXME: For now, just drop all extension qualifiers on the floor.
-}
-
-void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {
-  // <pointer-cvr-qualifiers> ::= P  # no qualifiers
-  //                          ::= Q  # const
-  //                          ::= R  # volatile
-  //                          ::= S  # const volatile
-  bool HasConst = Quals.hasConst(),
-       HasVolatile = Quals.hasVolatile();
-  if (HasConst && HasVolatile) {
-    Out << 'S';
-  } else if (HasVolatile) {
-    Out << 'R';
-  } else if (HasConst) {
-    Out << 'Q';
-  } else {
-    Out << 'P';
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
-                                                 SourceRange Range) {
-  void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();
-  ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
-
-  if (Found == TypeBackReferences.end()) {
-    size_t OutSizeBefore = Out.GetNumBytesInBuffer();
-
-    mangleType(T, Range, false);
-
-    // See if it's worth creating a back reference.
-    // Only types longer than 1 character are considered
-    // and only 10 back references slots are available:
-    bool LongerThanOneChar = (Out.GetNumBytesInBuffer() - OutSizeBefore > 1);
-    if (LongerThanOneChar && TypeBackReferences.size() < 10) {
-      size_t Size = TypeBackReferences.size();
-      TypeBackReferences[TypePtr] = Size;
-    }
-  } else {
-    Out << Found->second;
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
-                                         bool MangleQualifiers) {
-  // Only operate on the canonical type!
-  T = getASTContext().getCanonicalType(T);
-
-  Qualifiers Quals = T.getLocalQualifiers();
-  // We have to mangle these now, while we still have enough information.
-  if (T->isAnyPointerType() || T->isMemberPointerType() ||
-      T->isBlockPointerType()) {
-    manglePointerQualifiers(Quals);
-  } else if (Quals && MangleQualifiers) {
-    mangleQualifiers(Quals, false);
-  }
-
-  SplitQualType split = T.split();
-  const Type *ty = split.Ty;
-
-  // If we're mangling a qualified array type, push the qualifiers to
-  // the element type.
-  if (split.Quals && isa<ArrayType>(T)) {
-    ty = Context.getASTContext().getAsArrayType(T);
-  }
-
-  switch (ty->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define NON_CANONICAL_TYPE(CLASS, PARENT) \
-  case Type::CLASS: \
-    llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
-    return;
-#define TYPE(CLASS, PARENT) \
-  case Type::CLASS: \
-    mangleType(cast<CLASS##Type>(ty), Range); \
-    break;
-#include "clang/AST/TypeNodes.def"
-#undef ABSTRACT_TYPE
-#undef NON_CANONICAL_TYPE
-#undef TYPE
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T,
-                                         SourceRange Range) {
-  //  <type>         ::= <builtin-type>
-  //  <builtin-type> ::= X  # void
-  //                 ::= C  # signed char
-  //                 ::= D  # char
-  //                 ::= E  # unsigned char
-  //                 ::= F  # short
-  //                 ::= G  # unsigned short (or wchar_t if it's not a builtin)
-  //                 ::= H  # int
-  //                 ::= I  # unsigned int
-  //                 ::= J  # long
-  //                 ::= K  # unsigned long
-  //                     L  # <none>
-  //                 ::= M  # float
-  //                 ::= N  # double
-  //                 ::= O  # long double (__float80 is mangled differently)
-  //                 ::= _J # long long, __int64
-  //                 ::= _K # unsigned long long, __int64
-  //                 ::= _L # __int128
-  //                 ::= _M # unsigned __int128
-  //                 ::= _N # bool
-  //                     _O # <array in parameter>
-  //                 ::= _T # __float80 (Intel)
-  //                 ::= _W # wchar_t
-  //                 ::= _Z # __float80 (Digital Mars)
-  switch (T->getKind()) {
-  case BuiltinType::Void: Out << 'X'; break;
-  case BuiltinType::SChar: Out << 'C'; break;
-  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break;
-  case BuiltinType::UChar: Out << 'E'; break;
-  case BuiltinType::Short: Out << 'F'; break;
-  case BuiltinType::UShort: Out << 'G'; break;
-  case BuiltinType::Int: Out << 'H'; break;
-  case BuiltinType::UInt: Out << 'I'; break;
-  case BuiltinType::Long: Out << 'J'; break;
-  case BuiltinType::ULong: Out << 'K'; break;
-  case BuiltinType::Float: Out << 'M'; break;
-  case BuiltinType::Double: Out << 'N'; break;
-  // TODO: Determine size and mangle accordingly
-  case BuiltinType::LongDouble: Out << 'O'; break;
-  case BuiltinType::LongLong: Out << "_J"; break;
-  case BuiltinType::ULongLong: Out << "_K"; break;
-  case BuiltinType::Int128: Out << "_L"; break;
-  case BuiltinType::UInt128: Out << "_M"; break;
-  case BuiltinType::Bool: Out << "_N"; break;
-  case BuiltinType::WChar_S:
-  case BuiltinType::WChar_U: Out << "_W"; break;
-
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-  case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-  case BuiltinType::Dependent:
-    llvm_unreachable("placeholder types shouldn't get to name mangling");
-
-  case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break;
-  case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break;
-  case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break;
- 
-  case BuiltinType::NullPtr: Out << "$$T"; break;
-
-  case BuiltinType::Char16:
-  case BuiltinType::Char32:
-  case BuiltinType::Half: {
-    DiagnosticsEngine &Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-      "cannot mangle this built-in %0 type yet");
-    Diags.Report(Range.getBegin(), DiagID)
-      << T->getName(Context.getASTContext().getPrintingPolicy())
-      << Range;
-    break;
-  }
-  }
-}
-
-// <type>          ::= <function-type>
-void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T,
-                                         SourceRange) {
-  // Structors only appear in decls, so at this point we know it's not a
-  // structor type.
-  // FIXME: This may not be lambda-friendly.
-  Out << "$$A6";
-  mangleType(T, NULL, false, false);
-}
-void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
-                                         SourceRange) {
-  llvm_unreachable("Can't mangle K&R function prototypes");
-}
-
-void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
-                                         const FunctionDecl *D,
-                                         bool IsStructor,
-                                         bool IsInstMethod) {
-  // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
-  //                     <return-type> <argument-list> <throw-spec>
-  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
-
-  // If this is a C++ instance method, mangle the CVR qualifiers for the
-  // this pointer.
-  if (IsInstMethod)
-    mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);
-
-  mangleCallingConvention(T, IsInstMethod);
-
-  // <return-type> ::= <type>
-  //               ::= @ # structors (they have no declared return type)
-  if (IsStructor)
-    Out << '@';
-  else {
-    QualType Result = Proto->getResultType();
-    const Type* RT = Result.getTypePtr();
-    if (!RT->isAnyPointerType() && !RT->isReferenceType()) {
-      if (Result.hasQualifiers() || !RT->isBuiltinType())
-        Out << '?';
-      if (!RT->isBuiltinType() && !Result.hasQualifiers()) {
-        // Lack of qualifiers for user types is mangled as 'A'.
-        Out << 'A';
-      }
-    }
-
-    // FIXME: Get the source range for the result type. Or, better yet,
-    // implement the unimplemented stuff so we don't need accurate source
-    // location info anymore :).
-    mangleType(Result, SourceRange());
-  }
-
-  // <argument-list> ::= X # void
-  //                 ::= <type>+ @
-  //                 ::= <type>* Z # varargs
-  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
-    Out << 'X';
-  } else {
-    if (D) {
-      // If we got a decl, use the type-as-written to make sure arrays
-      // get mangled right.  Note that we can't rely on the TSI
-      // existing if (for example) the parameter was synthesized.
-      for (FunctionDecl::param_const_iterator Parm = D->param_begin(),
-             ParmEnd = D->param_end(); Parm != ParmEnd; ++Parm) {
-        TypeSourceInfo *TSI = (*Parm)->getTypeSourceInfo();
-        QualType Type = TSI ? TSI->getType() : (*Parm)->getType();
-        mangleArgumentType(Type, (*Parm)->getSourceRange());
-      }
-    } else {
-      // Happens for function pointer type arguments for example.
-      for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
-           ArgEnd = Proto->arg_type_end();
-           Arg != ArgEnd; ++Arg)
-        mangleArgumentType(*Arg, SourceRange());
-    }
-    // <builtin-type>      ::= Z  # ellipsis
-    if (Proto->isVariadic())
-      Out << 'Z';
-    else
-      Out << '@';
-  }
-
-  mangleThrowSpecification(Proto);
-}
-
-void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
-  // <function-class> ::= A # private: near
-  //                  ::= B # private: far
-  //                  ::= C # private: static near
-  //                  ::= D # private: static far
-  //                  ::= E # private: virtual near
-  //                  ::= F # private: virtual far
-  //                  ::= G # private: thunk near
-  //                  ::= H # private: thunk far
-  //                  ::= I # protected: near
-  //                  ::= J # protected: far
-  //                  ::= K # protected: static near
-  //                  ::= L # protected: static far
-  //                  ::= M # protected: virtual near
-  //                  ::= N # protected: virtual far
-  //                  ::= O # protected: thunk near
-  //                  ::= P # protected: thunk far
-  //                  ::= Q # public: near
-  //                  ::= R # public: far
-  //                  ::= S # public: static near
-  //                  ::= T # public: static far
-  //                  ::= U # public: virtual near
-  //                  ::= V # public: virtual far
-  //                  ::= W # public: thunk near
-  //                  ::= X # public: thunk far
-  //                  ::= Y # global near
-  //                  ::= Z # global far
-  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
-    switch (MD->getAccess()) {
-      default:
-      case AS_private:
-        if (MD->isStatic())
-          Out << 'C';
-        else if (MD->isVirtual())
-          Out << 'E';
-        else
-          Out << 'A';
-        break;
-      case AS_protected:
-        if (MD->isStatic())
-          Out << 'K';
-        else if (MD->isVirtual())
-          Out << 'M';
-        else
-          Out << 'I';
-        break;
-      case AS_public:
-        if (MD->isStatic())
-          Out << 'S';
-        else if (MD->isVirtual())
-          Out << 'U';
-        else
-          Out << 'Q';
-    }
-  } else
-    Out << 'Y';
-}
-void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
-                                                      bool IsInstMethod) {
-  // <calling-convention> ::= A # __cdecl
-  //                      ::= B # __export __cdecl
-  //                      ::= C # __pascal
-  //                      ::= D # __export __pascal
-  //                      ::= E # __thiscall
-  //                      ::= F # __export __thiscall
-  //                      ::= G # __stdcall
-  //                      ::= H # __export __stdcall
-  //                      ::= I # __fastcall
-  //                      ::= J # __export __fastcall
-  // The 'export' calling conventions are from a bygone era
-  // (*cough*Win16*cough*) when functions were declared for export with
-  // that keyword. (It didn't actually export them, it just made them so
-  // that they could be in a DLL and somebody from another module could call
-  // them.)
-  CallingConv CC = T->getCallConv();
-  if (CC == CC_Default) {
-    if (IsInstMethod) {
-      const FunctionProtoType *FPT =
-        T->getCanonicalTypeUnqualified().castAs<FunctionProtoType>();
-      bool isVariadic = FPT->isVariadic();
-      CC = getASTContext().getDefaultCXXMethodCallConv(isVariadic);
-    } else {
-      CC = CC_C;
-    }
-  }
-  switch (CC) {
-    default:
-      llvm_unreachable("Unsupported CC for mangling");
-    case CC_Default:
-    case CC_C: Out << 'A'; break;
-    case CC_X86Pascal: Out << 'C'; break;
-    case CC_X86ThisCall: Out << 'E'; break;
-    case CC_X86StdCall: Out << 'G'; break;
-    case CC_X86FastCall: Out << 'I'; break;
-  }
-}
-void MicrosoftCXXNameMangler::mangleThrowSpecification(
-                                                const FunctionProtoType *FT) {
-  // <throw-spec> ::= Z # throw(...) (default)
-  //              ::= @ # throw() or __declspec/__attribute__((nothrow))
-  //              ::= <type>+
-  // NOTE: Since the Microsoft compiler ignores throw specifications, they are
-  // all actually mangled as 'Z'. (They're ignored because their associated
-  // functionality isn't implemented, and probably never will be.)
-  Out << 'Z';
-}
-
-void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
-                                         SourceRange Range) {
-  // Probably should be mangled as a template instantiation; need to see what
-  // VC does first.
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this unresolved dependent type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-// <type>        ::= <union-type> | <struct-type> | <class-type> | <enum-type>
-// <union-type>  ::= T <name>
-// <struct-type> ::= U <name>
-// <class-type>  ::= V <name>
-// <enum-type>   ::= W <size> <name>
-void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) {
-  mangleType(cast<TagType>(T));
-}
-void MicrosoftCXXNameMangler::mangleType(const RecordType *T, SourceRange) {
-  mangleType(cast<TagType>(T));
-}
-void MicrosoftCXXNameMangler::mangleType(const TagType *T) {
-  switch (T->getDecl()->getTagKind()) {
-    case TTK_Union:
-      Out << 'T';
-      break;
-    case TTK_Struct:
-    case TTK_Interface:
-      Out << 'U';
-      break;
-    case TTK_Class:
-      Out << 'V';
-      break;
-    case TTK_Enum:
-      Out << 'W';
-      Out << getASTContext().getTypeSizeInChars(
-                cast<EnumDecl>(T->getDecl())->getIntegerType()).getQuantity();
-      break;
-  }
-  mangleName(T->getDecl());
-}
-
-// <type>       ::= <array-type>
-// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
-//                  [Y <dimension-count> <dimension>+]
-//                  <element-type> # as global
-//              ::= Q <cvr-qualifiers> [Y <dimension-count> <dimension>+]
-//                  <element-type> # as param
-// It's supposed to be the other way around, but for some strange reason, it
-// isn't. Today this behavior is retained for the sole purpose of backwards
-// compatibility.
-void MicrosoftCXXNameMangler::mangleType(const ArrayType *T, bool IsGlobal) {
-  // This isn't a recursive mangling, so now we have to do it all in this
-  // one call.
-  if (IsGlobal) {
-    manglePointerQualifiers(T->getElementType().getQualifiers());
-  } else {
-    Out << 'Q';
-  }
-  mangleExtraDimensions(T->getElementType());
-}
-void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
-                                         SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
-}
-void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T,
-                                         SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
-}
-void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,
-                                         SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
-}
-void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,
-                                         SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
-}
-void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) {
-  SmallVector<llvm::APInt, 3> Dimensions;
-  for (;;) {
-    if (const ConstantArrayType *CAT =
-          getASTContext().getAsConstantArrayType(ElementTy)) {
-      Dimensions.push_back(CAT->getSize());
-      ElementTy = CAT->getElementType();
-    } else if (ElementTy->isVariableArrayType()) {
-      const VariableArrayType *VAT =
-        getASTContext().getAsVariableArrayType(ElementTy);
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle this variable-length array yet");
-      Diags.Report(VAT->getSizeExpr()->getExprLoc(), DiagID)
-        << VAT->getBracketsRange();
-      return;
-    } else if (ElementTy->isDependentSizedArrayType()) {
-      // The dependent expression has to be folded into a constant (TODO).
-      const DependentSizedArrayType *DSAT =
-        getASTContext().getAsDependentSizedArrayType(ElementTy);
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle this dependent-length array yet");
-      Diags.Report(DSAT->getSizeExpr()->getExprLoc(), DiagID)
-        << DSAT->getBracketsRange();
-      return;
-    } else if (ElementTy->isIncompleteArrayType()) continue;
-    else break;
-  }
-  mangleQualifiers(ElementTy.getQualifiers(), false);
-  // If there are any additional dimensions, mangle them now.
-  if (Dimensions.size() > 0) {
-    Out << 'Y';
-    // <dimension-count> ::= <number> # number of extra dimensions
-    mangleNumber(Dimensions.size());
-    for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim) {
-      mangleNumber(Dimensions[Dim].getLimitedValue());
-    }
-  }
-  mangleType(ElementTy.getLocalUnqualifiedType(), SourceRange());
-}
-
-// <type>                   ::= <pointer-to-member-type>
-// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
-//                                                          <class name> <type>
-void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
-                                         SourceRange Range) {
-  QualType PointeeType = T->getPointeeType();
-  if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
-    Out << '8';
-    mangleName(T->getClass()->castAs<RecordType>()->getDecl());
-    mangleType(FPT, NULL, false, true);
-  } else {
-    mangleQualifiers(PointeeType.getQualifiers(), true);
-    mangleName(T->getClass()->castAs<RecordType>()->getDecl());
-    mangleType(PointeeType.getLocalUnqualifiedType(), Range);
-  }
-}
-
-void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this template type parameter type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(
-                                       const SubstTemplateTypeParmPackType *T,
-                                       SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this substituted parameter pack yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-// <type> ::= <pointer-type>
-// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
-void MicrosoftCXXNameMangler::mangleType(const PointerType *T,
-                                         SourceRange Range) {
-  QualType PointeeTy = T->getPointeeType();
-  if (PointeeTy->isArrayType()) {
-    // Pointers to arrays are mangled like arrays.
-    mangleExtraDimensions(PointeeTy);
-  } else if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
-    // Function pointers are special.
-    Out << '6';
-    mangleType(FT, NULL, false, false);
-  } else {
-    mangleQualifiers(PointeeTy.getQualifiers(), false);
-    mangleType(PointeeTy, Range, false);
-  }
-}
-void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
-                                         SourceRange Range) {
-  // Object pointers never have qualifiers.
-  Out << 'A';
-  mangleType(T->getPointeeType(), Range);
-}
-
-// <type> ::= <reference-type>
-// <reference-type> ::= A <cvr-qualifiers> <type>
-void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
-                                         SourceRange Range) {
-  Out << 'A';
-  QualType PointeeTy = T->getPointeeType();
-  if (!PointeeTy.hasQualifiers())
-    // Lack of qualifiers is mangled as 'A'.
-    Out << 'A';
-  mangleType(PointeeTy, Range);
-}
-
-// <type> ::= <r-value-reference-type>
-// <r-value-reference-type> ::= $$Q <cvr-qualifiers> <type>
-void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
-                                         SourceRange Range) {
-  Out << "$$Q";
-  QualType PointeeTy = T->getPointeeType();
-  if (!PointeeTy.hasQualifiers())
-    // Lack of qualifiers is mangled as 'A'.
-    Out << 'A';
-  mangleType(PointeeTy, Range);
-}
-
-void MicrosoftCXXNameMangler::mangleType(const ComplexType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this complex number type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const VectorType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this vector type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this extended vector type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this dependent-sized extended vector type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T,
-                                         SourceRange) {
-  // ObjC interfaces have structs underlying them.
-  Out << 'U';
-  mangleName(T->getDecl());
-}
-
-void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
-                                         SourceRange Range) {
-  // We don't allow overloading by different protocol qualification,
-  // so mangling them isn't necessary.
-  mangleType(T->getBaseType(), Range);
-}
-
-void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
-                                         SourceRange Range) {
-  Out << "_E";
-
-  QualType pointee = T->getPointeeType();
-  mangleType(pointee->castAs<FunctionProtoType>(), NULL, false, false);
-}
-
-void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this injected class name type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this template specialization type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this dependent name type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(
-                                 const DependentTemplateSpecializationType *T,
-                                 SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this dependent template specialization type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this pack expansion yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this typeof(type) yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this typeof(expression) yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this decltype() yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this unary transform type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this 'auto' type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftCXXNameMangler::mangleType(const AtomicType *T,
-                                         SourceRange Range) {
-  DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this C11 atomic type yet");
-  Diags.Report(Range.getBegin(), DiagID)
-    << Range;
-}
-
-void MicrosoftMangleContext::mangleName(const NamedDecl *D,
-                                        raw_ostream &Out) {
-  assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
-         "Invalid mangleName() call, argument is not a variable or function!");
-  assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
-         "Invalid mangleName() call on 'structor decl!");
-
-  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
-                                 getASTContext().getSourceManager(),
-                                 "Mangling declaration");
-
-  MicrosoftCXXNameMangler Mangler(*this, Out);
-  return Mangler.mangle(D);
-}
-void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,
-                                         const ThunkInfo &Thunk,
-                                         raw_ostream &) {
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle thunk for this method yet");
-  getDiags().Report(MD->getLocation(), DiagID);
-}
-void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
-                                                CXXDtorType Type,
-                                                const ThisAdjustment &,
-                                                raw_ostream &) {
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle thunk for this destructor yet");
-  getDiags().Report(DD->getLocation(), DiagID);
-}
-void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
-                                             raw_ostream &Out) {
-  // <mangled-name> ::= ? <operator-name> <class-name> <storage-class>
-  //                      <cvr-qualifiers> [<name>] @
-  // <operator-name> ::= _7 # vftable
-  //                 ::= _8 # vbtable
-  // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
-  // is always '6' for vftables and '7' for vbtables. (The difference is
-  // beyond me.)
-  // TODO: vbtables.
-  MicrosoftCXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "\01??_7";
-  Mangler.mangleName(RD);
-  Mangler.getStream() << "6B";
-  // TODO: If the class has more than one vtable, mangle in the class it came
-  // from.
-  Mangler.getStream() << '@';
-}
-void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
-                                          raw_ostream &) {
-  llvm_unreachable("The MS C++ ABI does not have virtual table tables!");
-}
-void MicrosoftMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
-                                                 int64_t Offset,
-                                                 const CXXRecordDecl *Type,
-                                                 raw_ostream &) {
-  llvm_unreachable("The MS C++ ABI does not have constructor vtables!");
-}
-void MicrosoftMangleContext::mangleCXXRTTI(QualType T,
-                                           raw_ostream &) {
-  // FIXME: Give a location...
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle RTTI descriptors for type %0 yet");
-  getDiags().Report(DiagID)
-    << T.getBaseTypeIdentifier();
-}
-void MicrosoftMangleContext::mangleCXXRTTIName(QualType T,
-                                               raw_ostream &) {
-  // FIXME: Give a location...
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle the name of type %0 into RTTI descriptors yet");
-  getDiags().Report(DiagID)
-    << T.getBaseTypeIdentifier();
-}
-void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
-                                           CXXCtorType Type,
-                                           raw_ostream & Out) {
-  MicrosoftCXXNameMangler mangler(*this, Out);
-  mangler.mangle(D);
-}
-void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
-                                           CXXDtorType Type,
-                                           raw_ostream & Out) {
-  MicrosoftCXXNameMangler mangler(*this, Out);
-  mangler.mangle(D);
-}
-void MicrosoftMangleContext::mangleReferenceTemporary(const clang::VarDecl *VD,
-                                                      raw_ostream &) {
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle this reference temporary yet");
-  getDiags().Report(VD->getLocation(), DiagID);
-}
-
-MangleContext *clang::createMicrosoftMangleContext(ASTContext &Context,
-                                                   DiagnosticsEngine &Diags) {
-  return new MicrosoftMangleContext(Context, Diags);
-}
+//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This provides C++ name mangling targeting the Microsoft Visual C++ ABI.

+//

+//===----------------------------------------------------------------------===//

+

+#include "clang/AST/Mangle.h"

+#include "clang/AST/ASTContext.h"

+#include "clang/AST/Attr.h"

+#include "clang/AST/CharUnits.h"

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

+#include "clang/AST/DeclCXX.h"

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

+#include "clang/AST/DeclTemplate.h"

+#include "clang/AST/ExprCXX.h"

+#include "clang/Basic/ABI.h"

+#include "clang/Basic/DiagnosticOptions.h"

+#include <map>

+

+using namespace clang;

+

+namespace {

+

+/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the

+/// Microsoft Visual C++ ABI.

+class MicrosoftCXXNameMangler {

+  MangleContext &Context;

+  raw_ostream &Out;

+

+  // FIXME: audit the performance of BackRefMap as it might do way too many

+  // copying of strings.

+  typedef std::map<std::string, unsigned> BackRefMap;

+  BackRefMap NameBackReferences;

+  bool UseNameBackReferences;

+

+  typedef llvm::DenseMap<void*, unsigned> ArgBackRefMap;

+  ArgBackRefMap TypeBackReferences;

+

+  ASTContext &getASTContext() const { return Context.getASTContext(); }

+

+public:

+  MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)

+  : Context(C), Out(Out_), UseNameBackReferences(true) { }

+

+  raw_ostream &getStream() const { return Out; }

+

+  void mangle(const NamedDecl *D, StringRef Prefix = "\01?");

+  void mangleName(const NamedDecl *ND);

+  void mangleFunctionEncoding(const FunctionDecl *FD);

+  void mangleVariableEncoding(const VarDecl *VD);

+  void mangleNumber(int64_t Number);

+  void mangleNumber(const llvm::APSInt &Value);

+  void mangleType(QualType T, SourceRange Range, bool MangleQualifiers = true);

+

+private:

+  void disableBackReferences() { UseNameBackReferences = false; }

+  void mangleUnqualifiedName(const NamedDecl *ND) {

+    mangleUnqualifiedName(ND, ND->getDeclName());

+  }

+  void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);

+  void mangleSourceName(const IdentifierInfo *II);

+  void manglePostfix(const DeclContext *DC, bool NoFunction=false);

+  void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);

+  void mangleQualifiers(Qualifiers Quals, bool IsMember);

+  void manglePointerQualifiers(Qualifiers Quals);

+

+  void mangleUnscopedTemplateName(const TemplateDecl *ND);

+  void mangleTemplateInstantiationName(const TemplateDecl *TD,

+                      const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs);

+  void mangleObjCMethodName(const ObjCMethodDecl *MD);

+  void mangleLocalName(const FunctionDecl *FD);

+

+  void mangleArgumentType(QualType T, SourceRange Range);

+

+  // Declare manglers for every type class.

+#define ABSTRACT_TYPE(CLASS, PARENT)

+#define NON_CANONICAL_TYPE(CLASS, PARENT)

+#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \

+                                            SourceRange Range);

+#include "clang/AST/TypeNodes.def"

+#undef ABSTRACT_TYPE

+#undef NON_CANONICAL_TYPE

+#undef TYPE

+  

+  void mangleType(const TagType*);

+  void mangleType(const FunctionType *T, const FunctionDecl *D,

+                  bool IsStructor, bool IsInstMethod);

+  void mangleType(const ArrayType *T, bool IsGlobal);

+  void mangleExtraDimensions(QualType T);

+  void mangleFunctionClass(const FunctionDecl *FD);

+  void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false);

+  void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean);

+  void mangleExpression(const Expr *E);

+  void mangleThrowSpecification(const FunctionProtoType *T);

+

+  void mangleTemplateArgs(

+                      const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs);

+

+};

+

+/// MicrosoftMangleContext - Overrides the default MangleContext for the

+/// Microsoft Visual C++ ABI.

+class MicrosoftMangleContext : public MangleContext {

+public:

+  MicrosoftMangleContext(ASTContext &Context,

+                   DiagnosticsEngine &Diags) : MangleContext(Context, Diags) { }

+  virtual bool shouldMangleDeclName(const NamedDecl *D);

+  virtual void mangleName(const NamedDecl *D, raw_ostream &Out);

+  virtual void mangleThunk(const CXXMethodDecl *MD,

+                           const ThunkInfo &Thunk,

+                           raw_ostream &);

+  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,

+                                  const ThisAdjustment &ThisAdjustment,

+                                  raw_ostream &);

+  virtual void mangleCXXVTable(const CXXRecordDecl *RD,

+                               raw_ostream &);

+  virtual void mangleCXXVTT(const CXXRecordDecl *RD,

+                            raw_ostream &);

+  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,

+                                   const CXXRecordDecl *Type,

+                                   raw_ostream &);

+  virtual void mangleCXXRTTI(QualType T, raw_ostream &);

+  virtual void mangleCXXRTTIName(QualType T, raw_ostream &);

+  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,

+                             raw_ostream &);

+  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,

+                             raw_ostream &);

+  virtual void mangleReferenceTemporary(const clang::VarDecl *,

+                                        raw_ostream &);

+};

+

+}

+

+static bool isInCLinkageSpecification(const Decl *D) {

+  D = D->getCanonicalDecl();

+  for (const DeclContext *DC = D->getDeclContext();

+       !DC->isTranslationUnit(); DC = DC->getParent()) {

+    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))

+      return Linkage->getLanguage() == LinkageSpecDecl::lang_c;

+  }

+

+  return false;

+}

+

+bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {

+  // In C, functions with no attributes never need to be mangled. Fastpath them.

+  if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())

+    return false;

+

+  // Any decl can be declared with __asm("foo") on it, and this takes precedence

+  // over all other naming in the .o file.

+  if (D->hasAttr<AsmLabelAttr>())

+    return true;

+

+  // Clang's "overloadable" attribute extension to C/C++ implies name mangling

+  // (always) as does passing a C++ member function and a function

+  // whose name is not a simple identifier.

+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);

+  if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||

+             !FD->getDeclName().isIdentifier()))

+    return true;

+

+  // Otherwise, no mangling is done outside C++ mode.

+  if (!getASTContext().getLangOpts().CPlusPlus)

+    return false;

+

+  // Variables at global scope with internal linkage are not mangled.

+  if (!FD) {

+    const DeclContext *DC = D->getDeclContext();

+    if (DC->isTranslationUnit() && D->getLinkage() == InternalLinkage)

+      return false;

+  }

+

+  // C functions and "main" are not mangled.

+  if ((FD && FD->isMain()) || isInCLinkageSpecification(D))

+    return false;

+

+  return true;

+}

+

+void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,

+                                     StringRef Prefix) {

+  // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.

+  // Therefore it's really important that we don't decorate the

+  // name with leading underscores or leading/trailing at signs. So, by

+  // default, we emit an asm marker at the start so we get the name right.

+  // Callers can override this with a custom prefix.

+

+  // Any decl can be declared with __asm("foo") on it, and this takes precedence

+  // over all other naming in the .o file.

+  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {

+    // If we have an asm name, then we use it as the mangling.

+    Out << '\01' << ALA->getLabel();

+    return;

+  }

+

+  // <mangled-name> ::= ? <name> <type-encoding>

+  Out << Prefix;

+  mangleName(D);

+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))

+    mangleFunctionEncoding(FD);

+  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))

+    mangleVariableEncoding(VD);

+  else {

+    // TODO: Fields? Can MSVC even mangle them?

+    // Issue a diagnostic for now.

+    DiagnosticsEngine &Diags = Context.getDiags();

+    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+      "cannot mangle this declaration yet");

+    Diags.Report(D->getLocation(), DiagID)

+      << D->getSourceRange();

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {

+  // <type-encoding> ::= <function-class> <function-type>

+

+  // Don't mangle in the type if this isn't a decl we should typically mangle.

+  if (!Context.shouldMangleDeclName(FD))

+    return;

+  

+  // We should never ever see a FunctionNoProtoType at this point.

+  // We don't even know how to mangle their types anyway :).

+  const FunctionProtoType *FT = FD->getType()->castAs<FunctionProtoType>();

+

+  bool InStructor = false, InInstMethod = false;

+  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);

+  if (MD) {

+    if (MD->isInstance())

+      InInstMethod = true;

+    if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))

+      InStructor = true;

+  }

+

+  // First, the function class.

+  mangleFunctionClass(FD);

+

+  mangleType(FT, FD, InStructor, InInstMethod);

+}

+

+void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {

+  // <type-encoding> ::= <storage-class> <variable-type>

+  // <storage-class> ::= 0  # private static member

+  //                 ::= 1  # protected static member

+  //                 ::= 2  # public static member

+  //                 ::= 3  # global

+  //                 ::= 4  # static local

+  

+  // The first character in the encoding (after the name) is the storage class.

+  if (VD->isStaticDataMember()) {

+    // If it's a static member, it also encodes the access level.

+    switch (VD->getAccess()) {

+      default:

+      case AS_private: Out << '0'; break;

+      case AS_protected: Out << '1'; break;

+      case AS_public: Out << '2'; break;

+    }

+  }

+  else if (!VD->isStaticLocal())

+    Out << '3';

+  else

+    Out << '4';

+  // Now mangle the type.

+  // <variable-type> ::= <type> <cvr-qualifiers>

+  //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references

+  // Pointers and references are odd. The type of 'int * const foo;' gets

+  // mangled as 'QAHA' instead of 'PAHB', for example.

+  TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();

+  QualType Ty = TL.getType();

+  if (Ty->isPointerType() || Ty->isReferenceType()) {

+    mangleType(Ty, TL.getSourceRange());

+    mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);

+  } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {

+    // Global arrays are funny, too.

+    mangleType(AT, true);

+    mangleQualifiers(Ty.getQualifiers(), false);

+  } else {

+    mangleType(Ty.getLocalUnqualifiedType(), TL.getSourceRange());

+    mangleQualifiers(Ty.getLocalQualifiers(), false);

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {

+  // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @

+  const DeclContext *DC = ND->getDeclContext();

+

+  // Always start with the unqualified name.

+  mangleUnqualifiedName(ND);    

+

+  // If this is an extern variable declared locally, the relevant DeclContext

+  // is that of the containing namespace, or the translation unit.

+  if (isa<FunctionDecl>(DC) && ND->hasLinkage())

+    while (!DC->isNamespace() && !DC->isTranslationUnit())

+      DC = DC->getParent();

+

+  manglePostfix(DC);

+

+  // Terminate the whole name with an '@'.

+  Out << '@';

+}

+

+void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {

+  llvm::APSInt APSNumber(/*BitWidth=*/64, /*isUnsigned=*/false);

+  APSNumber = Number;

+  mangleNumber(APSNumber);

+}

+

+void MicrosoftCXXNameMangler::mangleNumber(const llvm::APSInt &Value) {

+  // <number> ::= [?] <decimal digit> # 1 <= Number <= 10

+  //          ::= [?] <hex digit>+ @ # 0 or > 9; A = 0, B = 1, etc...

+  //          ::= [?] @ # 0 (alternate mangling, not emitted by VC)

+  if (Value.isSigned() && Value.isNegative()) {

+    Out << '?';

+    mangleNumber(llvm::APSInt(Value.abs()));

+    return;

+  }

+  llvm::APSInt Temp(Value);

+  // There's a special shorter mangling for 0, but Microsoft

+  // chose not to use it. Instead, 0 gets mangled as "A@". Oh well...

+  if (Value.uge(1) && Value.ule(10)) {

+    --Temp;

+    Temp.print(Out, false);

+  } else {

+    // We have to build up the encoding in reverse order, so it will come

+    // out right when we write it out.

+    char Encoding[64];

+    char *EndPtr = Encoding+sizeof(Encoding);

+    char *CurPtr = EndPtr;

+    llvm::APSInt NibbleMask(Value.getBitWidth(), Value.isUnsigned());

+    NibbleMask = 0xf;

+    do {

+      *--CurPtr = 'A' + Temp.And(NibbleMask).getLimitedValue(0xf);

+      Temp = Temp.lshr(4);

+    } while (Temp != 0);

+    Out.write(CurPtr, EndPtr-CurPtr);

+    Out << '@';

+  }

+}

+

+static const TemplateDecl *

+isTemplate(const NamedDecl *ND,

+           SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {

+  // Check if we have a function template.

+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){

+    if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {

+      if (FD->getTemplateSpecializationArgsAsWritten()) {

+        const ASTTemplateArgumentListInfo *ArgList =

+          FD->getTemplateSpecializationArgsAsWritten();

+        TemplateArgs.append(ArgList->getTemplateArgs(),

+                            ArgList->getTemplateArgs() +

+                              ArgList->NumTemplateArgs);

+      } else {

+        const TemplateArgumentList *ArgList =

+          FD->getTemplateSpecializationArgs();

+        TemplateArgumentListInfo LI;

+        for (unsigned i = 0, e = ArgList->size(); i != e; ++i)

+          TemplateArgs.push_back(TemplateArgumentLoc(ArgList->get(i),

+                                                     FD->getTypeSourceInfo()));

+      }

+      return TD;

+    }

+  }

+

+  // Check if we have a class template.

+  if (const ClassTemplateSpecializationDecl *Spec =

+      dyn_cast<ClassTemplateSpecializationDecl>(ND)) {

+    TypeSourceInfo *TSI = Spec->getTypeAsWritten();

+    if (TSI) {

+      TemplateSpecializationTypeLoc TSTL =

+        cast<TemplateSpecializationTypeLoc>(TSI->getTypeLoc());

+      TemplateArgumentListInfo LI(TSTL.getLAngleLoc(), TSTL.getRAngleLoc());

+      for (unsigned i = 0, e = TSTL.getNumArgs(); i != e; ++i)

+        TemplateArgs.push_back(TSTL.getArgLoc(i));

+    } else {

+      TemplateArgumentListInfo LI;

+      const TemplateArgumentList &ArgList =

+        Spec->getTemplateArgs();

+      for (unsigned i = 0, e = ArgList.size(); i != e; ++i)

+        TemplateArgs.push_back(TemplateArgumentLoc(ArgList[i],

+                                                   TemplateArgumentLocInfo()));

+    }

+    return Spec->getSpecializedTemplate();

+  }

+

+  return 0;

+}

+

+void

+MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,

+                                               DeclarationName Name) {

+  //  <unqualified-name> ::= <operator-name>

+  //                     ::= <ctor-dtor-name>

+  //                     ::= <source-name>

+  //                     ::= <template-name>

+  SmallVector<TemplateArgumentLoc, 2> TemplateArgs;

+  // Check if we have a template.

+  if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {

+    // We have a template.

+    // Here comes the tricky thing: if we need to mangle something like

+    //   void foo(A::X<Y>, B::X<Y>),

+    // the X<Y> part is aliased. However, if you need to mangle

+    //   void foo(A::X<A::Y>, A::X<B::Y>),

+    // the A::X<> part is not aliased.

+    // That said, from the mangler's perspective we have a structure like this:

+    //   namespace[s] -> type[ -> template-parameters]

+    // but from the Clang perspective we have

+    //   type [ -> template-parameters]

+    //      \-> namespace[s]

+    // What we do is we create a new mangler, mangle the same type (without

+    // a namespace suffix) using the extra mangler with back references

+    // disabled (to avoid infinite recursion) and then use the mangled type

+    // name as a key to check the mangling of different types for aliasing.

+

+    std::string BackReferenceKey;

+    BackRefMap::iterator Found;

+    if (UseNameBackReferences) {

+      llvm::raw_string_ostream Stream(BackReferenceKey);

+      MicrosoftCXXNameMangler Extra(Context, Stream);

+      Extra.disableBackReferences();

+      Extra.mangleUnqualifiedName(ND, Name);

+      Stream.flush();

+

+      Found = NameBackReferences.find(BackReferenceKey);

+    }

+    if (!UseNameBackReferences || Found == NameBackReferences.end()) {

+      mangleTemplateInstantiationName(TD, TemplateArgs);

+      if (UseNameBackReferences && NameBackReferences.size() < 10) {

+        size_t Size = NameBackReferences.size();

+        NameBackReferences[BackReferenceKey] = Size;

+      }

+    } else {

+      Out << Found->second;

+    }

+    return;

+  }

+

+  switch (Name.getNameKind()) {

+    case DeclarationName::Identifier: {

+      if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {

+        mangleSourceName(II);

+        break;

+      }

+      

+      // Otherwise, an anonymous entity.  We must have a declaration.

+      assert(ND && "mangling empty name without declaration");

+      

+      if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {

+        if (NS->isAnonymousNamespace()) {

+          Out << "?A@";

+          break;

+        }

+      }

+      

+      // We must have an anonymous struct.

+      const TagDecl *TD = cast<TagDecl>(ND);

+      if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {

+        assert(TD->getDeclContext() == D->getDeclContext() &&

+               "Typedef should not be in another decl context!");

+        assert(D->getDeclName().getAsIdentifierInfo() &&

+               "Typedef was not named!");

+        mangleSourceName(D->getDeclName().getAsIdentifierInfo());

+        break;

+      }

+

+      // When VC encounters an anonymous type with no tag and no typedef,

+      // it literally emits '<unnamed-tag>'.

+      Out << "<unnamed-tag>";

+      break;

+    }

+      

+    case DeclarationName::ObjCZeroArgSelector:

+    case DeclarationName::ObjCOneArgSelector:

+    case DeclarationName::ObjCMultiArgSelector:

+      llvm_unreachable("Can't mangle Objective-C selector names here!");

+      

+    case DeclarationName::CXXConstructorName:

+      Out << "?0";

+      break;

+      

+    case DeclarationName::CXXDestructorName:

+      Out << "?1";

+      break;

+      

+    case DeclarationName::CXXConversionFunctionName:

+      // <operator-name> ::= ?B # (cast)

+      // The target type is encoded as the return type.

+      Out << "?B";

+      break;

+      

+    case DeclarationName::CXXOperatorName:

+      mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());

+      break;

+      

+    case DeclarationName::CXXLiteralOperatorName: {

+      // FIXME: Was this added in VS2010? Does MS even know how to mangle this?

+      DiagnosticsEngine Diags = Context.getDiags();

+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+        "cannot mangle this literal operator yet");

+      Diags.Report(ND->getLocation(), DiagID);

+      break;

+    }

+      

+    case DeclarationName::CXXUsingDirective:

+      llvm_unreachable("Can't mangle a using directive name!");

+  }

+}

+

+void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,

+                                            bool NoFunction) {

+  // <postfix> ::= <unqualified-name> [<postfix>]

+  //           ::= <substitution> [<postfix>]

+

+  if (!DC) return;

+

+  while (isa<LinkageSpecDecl>(DC))

+    DC = DC->getParent();

+

+  if (DC->isTranslationUnit())

+    return;

+

+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {

+    Context.mangleBlock(BD, Out);

+    Out << '@';

+    return manglePostfix(DC->getParent(), NoFunction);

+  }

+

+  if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))

+    return;

+  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))

+    mangleObjCMethodName(Method);

+  else if (const FunctionDecl *Func = dyn_cast<FunctionDecl>(DC))

+    mangleLocalName(Func);

+  else {

+    mangleUnqualifiedName(cast<NamedDecl>(DC));

+    manglePostfix(DC->getParent(), NoFunction);

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,

+                                                 SourceLocation Loc) {

+  switch (OO) {

+  //                     ?0 # constructor

+  //                     ?1 # destructor

+  // <operator-name> ::= ?2 # new

+  case OO_New: Out << "?2"; break;

+  // <operator-name> ::= ?3 # delete

+  case OO_Delete: Out << "?3"; break;

+  // <operator-name> ::= ?4 # =

+  case OO_Equal: Out << "?4"; break;

+  // <operator-name> ::= ?5 # >>

+  case OO_GreaterGreater: Out << "?5"; break;

+  // <operator-name> ::= ?6 # <<

+  case OO_LessLess: Out << "?6"; break;

+  // <operator-name> ::= ?7 # !

+  case OO_Exclaim: Out << "?7"; break;

+  // <operator-name> ::= ?8 # ==

+  case OO_EqualEqual: Out << "?8"; break;

+  // <operator-name> ::= ?9 # !=

+  case OO_ExclaimEqual: Out << "?9"; break;

+  // <operator-name> ::= ?A # []

+  case OO_Subscript: Out << "?A"; break;

+  //                     ?B # conversion

+  // <operator-name> ::= ?C # ->

+  case OO_Arrow: Out << "?C"; break;

+  // <operator-name> ::= ?D # *

+  case OO_Star: Out << "?D"; break;

+  // <operator-name> ::= ?E # ++

+  case OO_PlusPlus: Out << "?E"; break;

+  // <operator-name> ::= ?F # --

+  case OO_MinusMinus: Out << "?F"; break;

+  // <operator-name> ::= ?G # -

+  case OO_Minus: Out << "?G"; break;

+  // <operator-name> ::= ?H # +

+  case OO_Plus: Out << "?H"; break;

+  // <operator-name> ::= ?I # &

+  case OO_Amp: Out << "?I"; break;

+  // <operator-name> ::= ?J # ->*

+  case OO_ArrowStar: Out << "?J"; break;

+  // <operator-name> ::= ?K # /

+  case OO_Slash: Out << "?K"; break;

+  // <operator-name> ::= ?L # %

+  case OO_Percent: Out << "?L"; break;

+  // <operator-name> ::= ?M # <

+  case OO_Less: Out << "?M"; break;

+  // <operator-name> ::= ?N # <=

+  case OO_LessEqual: Out << "?N"; break;

+  // <operator-name> ::= ?O # >

+  case OO_Greater: Out << "?O"; break;

+  // <operator-name> ::= ?P # >=

+  case OO_GreaterEqual: Out << "?P"; break;

+  // <operator-name> ::= ?Q # ,

+  case OO_Comma: Out << "?Q"; break;

+  // <operator-name> ::= ?R # ()

+  case OO_Call: Out << "?R"; break;

+  // <operator-name> ::= ?S # ~

+  case OO_Tilde: Out << "?S"; break;

+  // <operator-name> ::= ?T # ^

+  case OO_Caret: Out << "?T"; break;

+  // <operator-name> ::= ?U # |

+  case OO_Pipe: Out << "?U"; break;

+  // <operator-name> ::= ?V # &&

+  case OO_AmpAmp: Out << "?V"; break;

+  // <operator-name> ::= ?W # ||

+  case OO_PipePipe: Out << "?W"; break;

+  // <operator-name> ::= ?X # *=

+  case OO_StarEqual: Out << "?X"; break;

+  // <operator-name> ::= ?Y # +=

+  case OO_PlusEqual: Out << "?Y"; break;

+  // <operator-name> ::= ?Z # -=

+  case OO_MinusEqual: Out << "?Z"; break;

+  // <operator-name> ::= ?_0 # /=

+  case OO_SlashEqual: Out << "?_0"; break;

+  // <operator-name> ::= ?_1 # %=

+  case OO_PercentEqual: Out << "?_1"; break;

+  // <operator-name> ::= ?_2 # >>=

+  case OO_GreaterGreaterEqual: Out << "?_2"; break;

+  // <operator-name> ::= ?_3 # <<=

+  case OO_LessLessEqual: Out << "?_3"; break;

+  // <operator-name> ::= ?_4 # &=

+  case OO_AmpEqual: Out << "?_4"; break;

+  // <operator-name> ::= ?_5 # |=

+  case OO_PipeEqual: Out << "?_5"; break;

+  // <operator-name> ::= ?_6 # ^=

+  case OO_CaretEqual: Out << "?_6"; break;

+  //                     ?_7 # vftable

+  //                     ?_8 # vbtable

+  //                     ?_9 # vcall

+  //                     ?_A # typeof

+  //                     ?_B # local static guard

+  //                     ?_C # string

+  //                     ?_D # vbase destructor

+  //                     ?_E # vector deleting destructor

+  //                     ?_F # default constructor closure

+  //                     ?_G # scalar deleting destructor

+  //                     ?_H # vector constructor iterator

+  //                     ?_I # vector destructor iterator

+  //                     ?_J # vector vbase constructor iterator

+  //                     ?_K # virtual displacement map

+  //                     ?_L # eh vector constructor iterator

+  //                     ?_M # eh vector destructor iterator

+  //                     ?_N # eh vector vbase constructor iterator

+  //                     ?_O # copy constructor closure

+  //                     ?_P<name> # udt returning <name>

+  //                     ?_Q # <unknown>

+  //                     ?_R0 # RTTI Type Descriptor

+  //                     ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)

+  //                     ?_R2 # RTTI Base Class Array

+  //                     ?_R3 # RTTI Class Hierarchy Descriptor

+  //                     ?_R4 # RTTI Complete Object Locator

+  //                     ?_S # local vftable

+  //                     ?_T # local vftable constructor closure

+  // <operator-name> ::= ?_U # new[]

+  case OO_Array_New: Out << "?_U"; break;

+  // <operator-name> ::= ?_V # delete[]

+  case OO_Array_Delete: Out << "?_V"; break;

+    

+  case OO_Conditional: {

+    DiagnosticsEngine &Diags = Context.getDiags();

+    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+      "cannot mangle this conditional operator yet");

+    Diags.Report(Loc, DiagID);

+    break;

+  }

+    

+  case OO_None:

+  case NUM_OVERLOADED_OPERATORS:

+    llvm_unreachable("Not an overloaded operator");

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {

+  // <source name> ::= <identifier> @

+  std::string key = II->getNameStart();

+  BackRefMap::iterator Found;

+  if (UseNameBackReferences)

+    Found = NameBackReferences.find(key);

+  if (!UseNameBackReferences || Found == NameBackReferences.end()) {

+    Out << II->getName() << '@';

+    if (UseNameBackReferences && NameBackReferences.size() < 10) {

+      size_t Size = NameBackReferences.size();

+      NameBackReferences[key] = Size;

+    }

+  } else {

+    Out << Found->second;

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {

+  Context.mangleObjCMethodName(MD, Out);

+}

+

+// Find out how many function decls live above this one and return an integer

+// suitable for use as the number in a numbered anonymous scope.

+// TODO: Memoize.

+static unsigned getLocalNestingLevel(const FunctionDecl *FD) {

+  const DeclContext *DC = FD->getParent();

+  int level = 1;

+

+  while (DC && !DC->isTranslationUnit()) {

+    if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) level++;

+    DC = DC->getParent();

+  }

+

+  return 2*level;

+}

+

+void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) {

+  // <nested-name> ::= <numbered-anonymous-scope> ? <mangled-name>

+  // <numbered-anonymous-scope> ::= ? <number>

+  // Even though the name is rendered in reverse order (e.g.

+  // A::B::C is rendered as C@B@A), VC numbers the scopes from outermost to

+  // innermost. So a method bar in class C local to function foo gets mangled

+  // as something like:

+  // ?bar@C@?1??foo@@YAXXZ@QAEXXZ

+  // This is more apparent when you have a type nested inside a method of a

+  // type nested inside a function. A method baz in class D local to method

+  // bar of class C local to function foo gets mangled as:

+  // ?baz@D@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ

+  // This scheme is general enough to support GCC-style nested

+  // functions. You could have a method baz of class C inside a function bar

+  // inside a function foo, like so:

+  // ?baz@C@?3??bar@?1??foo@@YAXXZ@YAXXZ@QAEXXZ

+  int NestLevel = getLocalNestingLevel(FD);

+  Out << '?';

+  mangleNumber(NestLevel);

+  Out << '?';

+  mangle(FD, "?");

+}

+

+void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(

+                                                         const TemplateDecl *TD,

+                     const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {

+  // <template-name> ::= <unscoped-template-name> <template-args>

+  //                 ::= <substitution>

+  // Always start with the unqualified name.

+

+  // Templates have their own context for back references.

+  ArgBackRefMap OuterArgsContext;

+  BackRefMap OuterTemplateContext;

+  NameBackReferences.swap(OuterTemplateContext);

+  TypeBackReferences.swap(OuterArgsContext);

+

+  mangleUnscopedTemplateName(TD);

+  mangleTemplateArgs(TemplateArgs);

+

+  // Restore the previous back reference contexts.

+  NameBackReferences.swap(OuterTemplateContext);

+  TypeBackReferences.swap(OuterArgsContext);

+}

+

+void

+MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) {

+  // <unscoped-template-name> ::= ?$ <unqualified-name>

+  Out << "?$";

+  mangleUnqualifiedName(TD);

+}

+

+void

+MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,

+                                              bool IsBoolean) {

+  // <integer-literal> ::= $0 <number>

+  Out << "$0";

+  // Make sure booleans are encoded as 0/1.

+  if (IsBoolean && Value.getBoolValue())

+    mangleNumber(1);

+  else

+    mangleNumber(Value);

+}

+

+void

+MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {

+  // See if this is a constant expression.

+  llvm::APSInt Value;

+  if (E->isIntegerConstantExpr(Value, Context.getASTContext())) {

+    mangleIntegerLiteral(Value, E->getType()->isBooleanType());

+    return;

+  }

+

+  // As bad as this diagnostic is, it's better than crashing.

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+                                   "cannot yet mangle expression type %0");

+  Diags.Report(E->getExprLoc(), DiagID)

+    << E->getStmtClassName() << E->getSourceRange();

+}

+

+void

+MicrosoftCXXNameMangler::mangleTemplateArgs(

+                     const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {

+  // <template-args> ::= {<type> | <integer-literal>}+ @

+  unsigned NumTemplateArgs = TemplateArgs.size();

+  for (unsigned i = 0; i < NumTemplateArgs; ++i) {

+    const TemplateArgumentLoc &TAL = TemplateArgs[i];

+    const TemplateArgument &TA = TAL.getArgument();

+    switch (TA.getKind()) {

+    case TemplateArgument::Null:

+      llvm_unreachable("Can't mangle null template arguments!");

+    case TemplateArgument::Type:

+      mangleType(TA.getAsType(), TAL.getSourceRange());

+      break;

+    case TemplateArgument::Integral:

+      mangleIntegerLiteral(TA.getAsIntegral(),

+                           TA.getIntegralType()->isBooleanType());

+      break;

+    case TemplateArgument::Expression:

+      mangleExpression(TA.getAsExpr());

+      break;

+    case TemplateArgument::Template:

+    case TemplateArgument::TemplateExpansion:

+    case TemplateArgument::Declaration:

+    case TemplateArgument::NullPtr:

+    case TemplateArgument::Pack: {

+      // Issue a diagnostic.

+      DiagnosticsEngine &Diags = Context.getDiags();

+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+        "cannot mangle this %select{ERROR|ERROR|pointer/reference|nullptr|"

+        "integral|template|template pack expansion|ERROR|parameter pack}0 "

+        "template argument yet");

+      Diags.Report(TAL.getLocation(), DiagID)

+        << TA.getKind()

+        << TAL.getSourceRange();

+    }

+    }

+  }

+  Out << '@';

+}

+

+void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,

+                                               bool IsMember) {

+  // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>

+  // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);

+  // 'I' means __restrict (32/64-bit).

+  // Note that the MSVC __restrict keyword isn't the same as the C99 restrict

+  // keyword!

+  // <base-cvr-qualifiers> ::= A  # near

+  //                       ::= B  # near const

+  //                       ::= C  # near volatile

+  //                       ::= D  # near const volatile

+  //                       ::= E  # far (16-bit)

+  //                       ::= F  # far const (16-bit)

+  //                       ::= G  # far volatile (16-bit)

+  //                       ::= H  # far const volatile (16-bit)

+  //                       ::= I  # huge (16-bit)

+  //                       ::= J  # huge const (16-bit)

+  //                       ::= K  # huge volatile (16-bit)

+  //                       ::= L  # huge const volatile (16-bit)

+  //                       ::= M <basis> # based

+  //                       ::= N <basis> # based const

+  //                       ::= O <basis> # based volatile

+  //                       ::= P <basis> # based const volatile

+  //                       ::= Q  # near member

+  //                       ::= R  # near const member

+  //                       ::= S  # near volatile member

+  //                       ::= T  # near const volatile member

+  //                       ::= U  # far member (16-bit)

+  //                       ::= V  # far const member (16-bit)

+  //                       ::= W  # far volatile member (16-bit)

+  //                       ::= X  # far const volatile member (16-bit)

+  //                       ::= Y  # huge member (16-bit)

+  //                       ::= Z  # huge const member (16-bit)

+  //                       ::= 0  # huge volatile member (16-bit)

+  //                       ::= 1  # huge const volatile member (16-bit)

+  //                       ::= 2 <basis> # based member

+  //                       ::= 3 <basis> # based const member

+  //                       ::= 4 <basis> # based volatile member

+  //                       ::= 5 <basis> # based const volatile member

+  //                       ::= 6  # near function (pointers only)

+  //                       ::= 7  # far function (pointers only)

+  //                       ::= 8  # near method (pointers only)

+  //                       ::= 9  # far method (pointers only)

+  //                       ::= _A <basis> # based function (pointers only)

+  //                       ::= _B <basis> # based function (far?) (pointers only)

+  //                       ::= _C <basis> # based method (pointers only)

+  //                       ::= _D <basis> # based method (far?) (pointers only)

+  //                       ::= _E # block (Clang)

+  // <basis> ::= 0 # __based(void)

+  //         ::= 1 # __based(segment)?

+  //         ::= 2 <name> # __based(name)

+  //         ::= 3 # ?

+  //         ::= 4 # ?

+  //         ::= 5 # not really based

+  bool HasConst = Quals.hasConst(),

+       HasVolatile = Quals.hasVolatile();

+  if (!IsMember) {

+    if (HasConst && HasVolatile) {

+      Out << 'D';

+    } else if (HasVolatile) {

+      Out << 'C';

+    } else if (HasConst) {

+      Out << 'B';

+    } else {

+      Out << 'A';

+    }

+  } else {

+    if (HasConst && HasVolatile) {

+      Out << 'T';

+    } else if (HasVolatile) {

+      Out << 'S';

+    } else if (HasConst) {

+      Out << 'R';

+    } else {

+      Out << 'Q';

+    }

+  }

+

+  // FIXME: For now, just drop all extension qualifiers on the floor.

+}

+

+void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {

+  // <pointer-cvr-qualifiers> ::= P  # no qualifiers

+  //                          ::= Q  # const

+  //                          ::= R  # volatile

+  //                          ::= S  # const volatile

+  bool HasConst = Quals.hasConst(),

+       HasVolatile = Quals.hasVolatile();

+  if (HasConst && HasVolatile) {

+    Out << 'S';

+  } else if (HasVolatile) {

+    Out << 'R';

+  } else if (HasConst) {

+    Out << 'Q';

+  } else {

+    Out << 'P';

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,

+                                                 SourceRange Range) {

+  void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();

+  ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);

+

+  if (Found == TypeBackReferences.end()) {

+    size_t OutSizeBefore = Out.GetNumBytesInBuffer();

+

+    mangleType(T, Range, false);

+

+    // See if it's worth creating a back reference.

+    // Only types longer than 1 character are considered

+    // and only 10 back references slots are available:

+    bool LongerThanOneChar = (Out.GetNumBytesInBuffer() - OutSizeBefore > 1);

+    if (LongerThanOneChar && TypeBackReferences.size() < 10) {

+      size_t Size = TypeBackReferences.size();

+      TypeBackReferences[TypePtr] = Size;

+    }

+  } else {

+    Out << Found->second;

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,

+                                         bool MangleQualifiers) {

+  // Only operate on the canonical type!

+  T = getASTContext().getCanonicalType(T);

+

+  Qualifiers Quals = T.getLocalQualifiers();

+  // We have to mangle these now, while we still have enough information.

+  if (T->isAnyPointerType() || T->isMemberPointerType() ||

+      T->isBlockPointerType()) {

+    manglePointerQualifiers(Quals);

+  } else if (Quals && MangleQualifiers) {

+    mangleQualifiers(Quals, false);

+  }

+

+  SplitQualType split = T.split();

+  const Type *ty = split.Ty;

+

+  // If we're mangling a qualified array type, push the qualifiers to

+  // the element type.

+  if (split.Quals && isa<ArrayType>(T)) {

+    ty = Context.getASTContext().getAsArrayType(T);

+  }

+

+  switch (ty->getTypeClass()) {

+#define ABSTRACT_TYPE(CLASS, PARENT)

+#define NON_CANONICAL_TYPE(CLASS, PARENT) \

+  case Type::CLASS: \

+    llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \

+    return;

+#define TYPE(CLASS, PARENT) \

+  case Type::CLASS: \

+    mangleType(cast<CLASS##Type>(ty), Range); \

+    break;

+#include "clang/AST/TypeNodes.def"

+#undef ABSTRACT_TYPE

+#undef NON_CANONICAL_TYPE

+#undef TYPE

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T,

+                                         SourceRange Range) {

+  //  <type>         ::= <builtin-type>

+  //  <builtin-type> ::= X  # void

+  //                 ::= C  # signed char

+  //                 ::= D  # char

+  //                 ::= E  # unsigned char

+  //                 ::= F  # short

+  //                 ::= G  # unsigned short (or wchar_t if it's not a builtin)

+  //                 ::= H  # int

+  //                 ::= I  # unsigned int

+  //                 ::= J  # long

+  //                 ::= K  # unsigned long

+  //                     L  # <none>

+  //                 ::= M  # float

+  //                 ::= N  # double

+  //                 ::= O  # long double (__float80 is mangled differently)

+  //                 ::= _J # long long, __int64

+  //                 ::= _K # unsigned long long, __int64

+  //                 ::= _L # __int128

+  //                 ::= _M # unsigned __int128

+  //                 ::= _N # bool

+  //                     _O # <array in parameter>

+  //                 ::= _T # __float80 (Intel)

+  //                 ::= _W # wchar_t

+  //                 ::= _Z # __float80 (Digital Mars)

+  switch (T->getKind()) {

+  case BuiltinType::Void: Out << 'X'; break;

+  case BuiltinType::SChar: Out << 'C'; break;

+  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break;

+  case BuiltinType::UChar: Out << 'E'; break;

+  case BuiltinType::Short: Out << 'F'; break;

+  case BuiltinType::UShort: Out << 'G'; break;

+  case BuiltinType::Int: Out << 'H'; break;

+  case BuiltinType::UInt: Out << 'I'; break;

+  case BuiltinType::Long: Out << 'J'; break;

+  case BuiltinType::ULong: Out << 'K'; break;

+  case BuiltinType::Float: Out << 'M'; break;

+  case BuiltinType::Double: Out << 'N'; break;

+  // TODO: Determine size and mangle accordingly

+  case BuiltinType::LongDouble: Out << 'O'; break;

+  case BuiltinType::LongLong: Out << "_J"; break;

+  case BuiltinType::ULongLong: Out << "_K"; break;

+  case BuiltinType::Int128: Out << "_L"; break;

+  case BuiltinType::UInt128: Out << "_M"; break;

+  case BuiltinType::Bool: Out << "_N"; break;

+  case BuiltinType::WChar_S:

+  case BuiltinType::WChar_U: Out << "_W"; break;

+

+#define BUILTIN_TYPE(Id, SingletonId)

+#define PLACEHOLDER_TYPE(Id, SingletonId) \

+  case BuiltinType::Id:

+#include "clang/AST/BuiltinTypes.def"

+  case BuiltinType::Dependent:

+    llvm_unreachable("placeholder types shouldn't get to name mangling");

+

+  case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break;

+  case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break;

+  case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break;

+

+  case BuiltinType::OCLImage1d: Out << "PAUocl_image1d@@"; break;

+  case BuiltinType::OCLImage1dArray: Out << "PAUocl_image1darray@@"; break;

+  case BuiltinType::OCLImage1dBuffer: Out << "PAUocl_image1dbuffer@@"; break;

+  case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break;

+  case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break;

+  case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break;

+ 

+  case BuiltinType::NullPtr: Out << "$$T"; break;

+

+  case BuiltinType::Char16:

+  case BuiltinType::Char32:

+  case BuiltinType::Half: {

+    DiagnosticsEngine &Diags = Context.getDiags();

+    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+      "cannot mangle this built-in %0 type yet");

+    Diags.Report(Range.getBegin(), DiagID)

+      << T->getName(Context.getASTContext().getPrintingPolicy())

+      << Range;

+    break;

+  }

+  }

+}

+

+// <type>          ::= <function-type>

+void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T,

+                                         SourceRange) {

+  // Structors only appear in decls, so at this point we know it's not a

+  // structor type.

+  // FIXME: This may not be lambda-friendly.

+  Out << "$$A6";

+  mangleType(T, NULL, false, false);

+}

+void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,

+                                         SourceRange) {

+  llvm_unreachable("Can't mangle K&R function prototypes");

+}

+

+void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,

+                                         const FunctionDecl *D,

+                                         bool IsStructor,

+                                         bool IsInstMethod) {

+  // <function-type> ::= <this-cvr-qualifiers> <calling-convention>

+  //                     <return-type> <argument-list> <throw-spec>

+  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);

+

+  // If this is a C++ instance method, mangle the CVR qualifiers for the

+  // this pointer.

+  if (IsInstMethod)

+    mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);

+

+  mangleCallingConvention(T, IsInstMethod);

+

+  // <return-type> ::= <type>

+  //               ::= @ # structors (they have no declared return type)

+  if (IsStructor)

+    Out << '@';

+  else {

+    QualType Result = Proto->getResultType();

+    const Type* RT = Result.getTypePtr();

+    if (!RT->isAnyPointerType() && !RT->isReferenceType()) {

+      if (Result.hasQualifiers() || !RT->isBuiltinType())

+        Out << '?';

+      if (!RT->isBuiltinType() && !Result.hasQualifiers()) {

+        // Lack of qualifiers for user types is mangled as 'A'.

+        Out << 'A';

+      }

+    }

+

+    // FIXME: Get the source range for the result type. Or, better yet,

+    // implement the unimplemented stuff so we don't need accurate source

+    // location info anymore :).

+    mangleType(Result, SourceRange());

+  }

+

+  // <argument-list> ::= X # void

+  //                 ::= <type>+ @

+  //                 ::= <type>* Z # varargs

+  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {

+    Out << 'X';

+  } else {

+    if (D) {

+      // If we got a decl, use the type-as-written to make sure arrays

+      // get mangled right.  Note that we can't rely on the TSI

+      // existing if (for example) the parameter was synthesized.

+      for (FunctionDecl::param_const_iterator Parm = D->param_begin(),

+             ParmEnd = D->param_end(); Parm != ParmEnd; ++Parm) {

+        TypeSourceInfo *TSI = (*Parm)->getTypeSourceInfo();

+        QualType Type = TSI ? TSI->getType() : (*Parm)->getType();

+        mangleArgumentType(Type, (*Parm)->getSourceRange());

+      }

+    } else {

+      // Happens for function pointer type arguments for example.

+      for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),

+           ArgEnd = Proto->arg_type_end();

+           Arg != ArgEnd; ++Arg)

+        mangleArgumentType(*Arg, SourceRange());

+    }

+    // <builtin-type>      ::= Z  # ellipsis

+    if (Proto->isVariadic())

+      Out << 'Z';

+    else

+      Out << '@';

+  }

+

+  mangleThrowSpecification(Proto);

+}

+

+void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {

+  // <function-class> ::= A # private: near

+  //                  ::= B # private: far

+  //                  ::= C # private: static near

+  //                  ::= D # private: static far

+  //                  ::= E # private: virtual near

+  //                  ::= F # private: virtual far

+  //                  ::= G # private: thunk near

+  //                  ::= H # private: thunk far

+  //                  ::= I # protected: near

+  //                  ::= J # protected: far

+  //                  ::= K # protected: static near

+  //                  ::= L # protected: static far

+  //                  ::= M # protected: virtual near

+  //                  ::= N # protected: virtual far

+  //                  ::= O # protected: thunk near

+  //                  ::= P # protected: thunk far

+  //                  ::= Q # public: near

+  //                  ::= R # public: far

+  //                  ::= S # public: static near

+  //                  ::= T # public: static far

+  //                  ::= U # public: virtual near

+  //                  ::= V # public: virtual far

+  //                  ::= W # public: thunk near

+  //                  ::= X # public: thunk far

+  //                  ::= Y # global near

+  //                  ::= Z # global far

+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {

+    switch (MD->getAccess()) {

+      default:

+      case AS_private:

+        if (MD->isStatic())

+          Out << 'C';

+        else if (MD->isVirtual())

+          Out << 'E';

+        else

+          Out << 'A';

+        break;

+      case AS_protected:

+        if (MD->isStatic())

+          Out << 'K';

+        else if (MD->isVirtual())

+          Out << 'M';

+        else

+          Out << 'I';

+        break;

+      case AS_public:

+        if (MD->isStatic())

+          Out << 'S';

+        else if (MD->isVirtual())

+          Out << 'U';

+        else

+          Out << 'Q';

+    }

+  } else

+    Out << 'Y';

+}

+void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,

+                                                      bool IsInstMethod) {

+  // <calling-convention> ::= A # __cdecl

+  //                      ::= B # __export __cdecl

+  //                      ::= C # __pascal

+  //                      ::= D # __export __pascal

+  //                      ::= E # __thiscall

+  //                      ::= F # __export __thiscall

+  //                      ::= G # __stdcall

+  //                      ::= H # __export __stdcall

+  //                      ::= I # __fastcall

+  //                      ::= J # __export __fastcall

+  // The 'export' calling conventions are from a bygone era

+  // (*cough*Win16*cough*) when functions were declared for export with

+  // that keyword. (It didn't actually export them, it just made them so

+  // that they could be in a DLL and somebody from another module could call

+  // them.)

+  CallingConv CC = T->getCallConv();

+  if (CC == CC_Default) {

+    if (IsInstMethod) {

+      const FunctionProtoType *FPT =

+        T->getCanonicalTypeUnqualified().castAs<FunctionProtoType>();

+      bool isVariadic = FPT->isVariadic();

+      CC = getASTContext().getDefaultCXXMethodCallConv(isVariadic);

+    } else {

+      CC = CC_C;

+    }

+  }

+  switch (CC) {

+    default:

+      llvm_unreachable("Unsupported CC for mangling");

+    case CC_Default:

+    case CC_C: Out << 'A'; break;

+    case CC_X86Pascal: Out << 'C'; break;

+    case CC_X86ThisCall: Out << 'E'; break;

+    case CC_X86StdCall: Out << 'G'; break;

+    case CC_X86FastCall: Out << 'I'; break;

+  }

+}

+void MicrosoftCXXNameMangler::mangleThrowSpecification(

+                                                const FunctionProtoType *FT) {

+  // <throw-spec> ::= Z # throw(...) (default)

+  //              ::= @ # throw() or __declspec/__attribute__((nothrow))

+  //              ::= <type>+

+  // NOTE: Since the Microsoft compiler ignores throw specifications, they are

+  // all actually mangled as 'Z'. (They're ignored because their associated

+  // functionality isn't implemented, and probably never will be.)

+  Out << 'Z';

+}

+

+void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,

+                                         SourceRange Range) {

+  // Probably should be mangled as a template instantiation; need to see what

+  // VC does first.

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this unresolved dependent type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+// <type>        ::= <union-type> | <struct-type> | <class-type> | <enum-type>

+// <union-type>  ::= T <name>

+// <struct-type> ::= U <name>

+// <class-type>  ::= V <name>

+// <enum-type>   ::= W <size> <name>

+void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) {

+  mangleType(cast<TagType>(T));

+}

+void MicrosoftCXXNameMangler::mangleType(const RecordType *T, SourceRange) {

+  mangleType(cast<TagType>(T));

+}

+void MicrosoftCXXNameMangler::mangleType(const TagType *T) {

+  switch (T->getDecl()->getTagKind()) {

+    case TTK_Union:

+      Out << 'T';

+      break;

+    case TTK_Struct:

+    case TTK_Interface:

+      Out << 'U';

+      break;

+    case TTK_Class:

+      Out << 'V';

+      break;

+    case TTK_Enum:

+      Out << 'W';

+      Out << getASTContext().getTypeSizeInChars(

+                cast<EnumDecl>(T->getDecl())->getIntegerType()).getQuantity();

+      break;

+  }

+  mangleName(T->getDecl());

+}

+

+// <type>       ::= <array-type>

+// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>

+//                  [Y <dimension-count> <dimension>+]

+//                  <element-type> # as global

+//              ::= Q <cvr-qualifiers> [Y <dimension-count> <dimension>+]

+//                  <element-type> # as param

+// It's supposed to be the other way around, but for some strange reason, it

+// isn't. Today this behavior is retained for the sole purpose of backwards

+// compatibility.

+void MicrosoftCXXNameMangler::mangleType(const ArrayType *T, bool IsGlobal) {

+  // This isn't a recursive mangling, so now we have to do it all in this

+  // one call.

+  if (IsGlobal) {

+    manglePointerQualifiers(T->getElementType().getQualifiers());

+  } else {

+    Out << 'Q';

+  }

+  mangleExtraDimensions(T->getElementType());

+}

+void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,

+                                         SourceRange) {

+  mangleType(cast<ArrayType>(T), false);

+}

+void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T,

+                                         SourceRange) {

+  mangleType(cast<ArrayType>(T), false);

+}

+void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,

+                                         SourceRange) {

+  mangleType(cast<ArrayType>(T), false);

+}

+void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,

+                                         SourceRange) {

+  mangleType(cast<ArrayType>(T), false);

+}

+void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) {

+  SmallVector<llvm::APInt, 3> Dimensions;

+  for (;;) {

+    if (const ConstantArrayType *CAT =

+          getASTContext().getAsConstantArrayType(ElementTy)) {

+      Dimensions.push_back(CAT->getSize());

+      ElementTy = CAT->getElementType();

+    } else if (ElementTy->isVariableArrayType()) {

+      const VariableArrayType *VAT =

+        getASTContext().getAsVariableArrayType(ElementTy);

+      DiagnosticsEngine &Diags = Context.getDiags();

+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+        "cannot mangle this variable-length array yet");

+      Diags.Report(VAT->getSizeExpr()->getExprLoc(), DiagID)

+        << VAT->getBracketsRange();

+      return;

+    } else if (ElementTy->isDependentSizedArrayType()) {

+      // The dependent expression has to be folded into a constant (TODO).

+      const DependentSizedArrayType *DSAT =

+        getASTContext().getAsDependentSizedArrayType(ElementTy);

+      DiagnosticsEngine &Diags = Context.getDiags();

+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+        "cannot mangle this dependent-length array yet");

+      Diags.Report(DSAT->getSizeExpr()->getExprLoc(), DiagID)

+        << DSAT->getBracketsRange();

+      return;

+    } else if (ElementTy->isIncompleteArrayType()) continue;

+    else break;

+  }

+  mangleQualifiers(ElementTy.getQualifiers(), false);

+  // If there are any additional dimensions, mangle them now.

+  if (Dimensions.size() > 0) {

+    Out << 'Y';

+    // <dimension-count> ::= <number> # number of extra dimensions

+    mangleNumber(Dimensions.size());

+    for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim) {

+      mangleNumber(Dimensions[Dim].getLimitedValue());

+    }

+  }

+  mangleType(ElementTy.getLocalUnqualifiedType(), SourceRange());

+}

+

+// <type>                   ::= <pointer-to-member-type>

+// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>

+//                                                          <class name> <type>

+void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,

+                                         SourceRange Range) {

+  QualType PointeeType = T->getPointeeType();

+  if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {

+    Out << '8';

+    mangleName(T->getClass()->castAs<RecordType>()->getDecl());

+    mangleType(FPT, NULL, false, true);

+  } else {

+    mangleQualifiers(PointeeType.getQualifiers(), true);

+    mangleName(T->getClass()->castAs<RecordType>()->getDecl());

+    mangleType(PointeeType.getLocalUnqualifiedType(), Range);

+  }

+}

+

+void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this template type parameter type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(

+                                       const SubstTemplateTypeParmPackType *T,

+                                       SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this substituted parameter pack yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+// <type> ::= <pointer-type>

+// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>

+void MicrosoftCXXNameMangler::mangleType(const PointerType *T,

+                                         SourceRange Range) {

+  QualType PointeeTy = T->getPointeeType();

+  if (PointeeTy->isArrayType()) {

+    // Pointers to arrays are mangled like arrays.

+    mangleExtraDimensions(PointeeTy);

+  } else if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {

+    // Function pointers are special.

+    Out << '6';

+    mangleType(FT, NULL, false, false);

+  } else {

+    mangleQualifiers(PointeeTy.getQualifiers(), false);

+    mangleType(PointeeTy, Range, false);

+  }

+}

+void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,

+                                         SourceRange Range) {

+  // Object pointers never have qualifiers.

+  Out << 'A';

+  mangleType(T->getPointeeType(), Range);

+}

+

+// <type> ::= <reference-type>

+// <reference-type> ::= A <cvr-qualifiers> <type>

+void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,

+                                         SourceRange Range) {

+  Out << 'A';

+  QualType PointeeTy = T->getPointeeType();

+  if (!PointeeTy.hasQualifiers())

+    // Lack of qualifiers is mangled as 'A'.

+    Out << 'A';

+  mangleType(PointeeTy, Range);

+}

+

+// <type> ::= <r-value-reference-type>

+// <r-value-reference-type> ::= $$Q <cvr-qualifiers> <type>

+void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,

+                                         SourceRange Range) {

+  Out << "$$Q";

+  QualType PointeeTy = T->getPointeeType();

+  if (!PointeeTy.hasQualifiers())

+    // Lack of qualifiers is mangled as 'A'.

+    Out << 'A';

+  mangleType(PointeeTy, Range);

+}

+

+void MicrosoftCXXNameMangler::mangleType(const ComplexType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this complex number type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const VectorType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this vector type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this extended vector type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this dependent-sized extended vector type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T,

+                                         SourceRange) {

+  // ObjC interfaces have structs underlying them.

+  Out << 'U';

+  mangleName(T->getDecl());

+}

+

+void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,

+                                         SourceRange Range) {

+  // We don't allow overloading by different protocol qualification,

+  // so mangling them isn't necessary.

+  mangleType(T->getBaseType(), Range);

+}

+

+void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,

+                                         SourceRange Range) {

+  Out << "_E";

+

+  QualType pointee = T->getPointeeType();

+  mangleType(pointee->castAs<FunctionProtoType>(), NULL, false, false);

+}

+

+void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this injected class name type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this template specialization type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this dependent name type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(

+                                 const DependentTemplateSpecializationType *T,

+                                 SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this dependent template specialization type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this pack expansion yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this typeof(type) yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this typeof(expression) yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this decltype() yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this unary transform type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this 'auto' type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftCXXNameMangler::mangleType(const AtomicType *T,

+                                         SourceRange Range) {

+  DiagnosticsEngine &Diags = Context.getDiags();

+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this C11 atomic type yet");

+  Diags.Report(Range.getBegin(), DiagID)

+    << Range;

+}

+

+void MicrosoftMangleContext::mangleName(const NamedDecl *D,

+                                        raw_ostream &Out) {

+  assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&

+         "Invalid mangleName() call, argument is not a variable or function!");

+  assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&

+         "Invalid mangleName() call on 'structor decl!");

+

+  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),

+                                 getASTContext().getSourceManager(),

+                                 "Mangling declaration");

+

+  MicrosoftCXXNameMangler Mangler(*this, Out);

+  return Mangler.mangle(D);

+}

+void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,

+                                         const ThunkInfo &Thunk,

+                                         raw_ostream &) {

+  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle thunk for this method yet");

+  getDiags().Report(MD->getLocation(), DiagID);

+}

+void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,

+                                                CXXDtorType Type,

+                                                const ThisAdjustment &,

+                                                raw_ostream &) {

+  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle thunk for this destructor yet");

+  getDiags().Report(DD->getLocation(), DiagID);

+}

+void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,

+                                             raw_ostream &Out) {

+  // <mangled-name> ::= ? <operator-name> <class-name> <storage-class>

+  //                      <cvr-qualifiers> [<name>] @

+  // <operator-name> ::= _7 # vftable

+  //                 ::= _8 # vbtable

+  // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>

+  // is always '6' for vftables and '7' for vbtables. (The difference is

+  // beyond me.)

+  // TODO: vbtables.

+  MicrosoftCXXNameMangler Mangler(*this, Out);

+  Mangler.getStream() << "\01??_7";

+  Mangler.mangleName(RD);

+  Mangler.getStream() << "6B";

+  // TODO: If the class has more than one vtable, mangle in the class it came

+  // from.

+  Mangler.getStream() << '@';

+}

+void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,

+                                          raw_ostream &) {

+  llvm_unreachable("The MS C++ ABI does not have virtual table tables!");

+}

+void MicrosoftMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,

+                                                 int64_t Offset,

+                                                 const CXXRecordDecl *Type,

+                                                 raw_ostream &) {

+  llvm_unreachable("The MS C++ ABI does not have constructor vtables!");

+}

+void MicrosoftMangleContext::mangleCXXRTTI(QualType T,

+                                           raw_ostream &) {

+  // FIXME: Give a location...

+  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle RTTI descriptors for type %0 yet");

+  getDiags().Report(DiagID)

+    << T.getBaseTypeIdentifier();

+}

+void MicrosoftMangleContext::mangleCXXRTTIName(QualType T,

+                                               raw_ostream &) {

+  // FIXME: Give a location...

+  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle the name of type %0 into RTTI descriptors yet");

+  getDiags().Report(DiagID)

+    << T.getBaseTypeIdentifier();

+}

+void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,

+                                           CXXCtorType Type,

+                                           raw_ostream & Out) {

+  MicrosoftCXXNameMangler mangler(*this, Out);

+  mangler.mangle(D);

+}

+void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,

+                                           CXXDtorType Type,

+                                           raw_ostream & Out) {

+  MicrosoftCXXNameMangler mangler(*this, Out);

+  mangler.mangle(D);

+}

+void MicrosoftMangleContext::mangleReferenceTemporary(const clang::VarDecl *VD,

+                                                      raw_ostream &) {

+  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,

+    "cannot mangle this reference temporary yet");

+  getDiags().Report(VD->getLocation(), DiagID);

+}

+

+MangleContext *clang::createMicrosoftMangleContext(ASTContext &Context,

+                                                   DiagnosticsEngine &Diags) {

+  return new MicrosoftMangleContext(Context, Diags);

+}

diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index 0837509..6218da2 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -1,414 +1,420 @@
-//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/NSAPI.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-
-using namespace clang;
-
-NSAPI::NSAPI(ASTContext &ctx)
-  : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0),
-    NSASCIIStringEncodingId(0), NSUTF8StringEncodingId(0) {
-}
-
-IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
-  static const char *ClassName[NumClassIds] = {
-    "NSObject",
-    "NSString",
-    "NSArray",
-    "NSMutableArray",
-    "NSDictionary",
-    "NSMutableDictionary",
-    "NSNumber"
-  };
-
-  if (!ClassIds[K])
-    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
-
-  return ClassIds[K];
-}
-
-Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
-  if (NSStringSelectors[MK].isNull()) {
-    Selector Sel;
-    switch (MK) {
-    case NSStr_stringWithString:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
-      break;
-    case NSStr_stringWithUTF8String:
-      Sel = Ctx.Selectors.getUnarySelector(
-                                       &Ctx.Idents.get("stringWithUTF8String"));
-      break;
-    case NSStr_stringWithCStringEncoding: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("stringWithCString"),
-        &Ctx.Idents.get("encoding")
-      };
-      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
-      break;
-    }
-    case NSStr_stringWithCString:
-      Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));
-      break;
-    case NSStr_initWithString:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
-      break;
-    }
-    return (NSStringSelectors[MK] = Sel);
-  }
-
-  return NSStringSelectors[MK];
-}
-
-llvm::Optional<NSAPI::NSStringMethodKind>
-NSAPI::getNSStringMethodKind(Selector Sel) const {
-  for (unsigned i = 0; i != NumNSStringMethods; ++i) {
-    NSStringMethodKind MK = NSStringMethodKind(i);
-    if (Sel == getNSStringSelector(MK))
-      return MK;
-  }
-
-  return llvm::Optional<NSStringMethodKind>();
-}
-
-Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
-  if (NSArraySelectors[MK].isNull()) {
-    Selector Sel;
-    switch (MK) {
-    case NSArr_array:
-      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
-      break;
-    case NSArr_arrayWithArray:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
-      break;
-    case NSArr_arrayWithObject:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
-      break;
-    case NSArr_arrayWithObjects:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
-      break;
-    case NSArr_arrayWithObjectsCount: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("arrayWithObjects"),
-        &Ctx.Idents.get("count")
-      };
-      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
-      break;
-    }
-    case NSArr_initWithArray:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
-      break;
-    case NSArr_initWithObjects:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
-      break;
-    case NSArr_objectAtIndex:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
-      break;
-    case NSMutableArr_replaceObjectAtIndex: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("replaceObjectAtIndex"),
-        &Ctx.Idents.get("withObject")
-      };
-      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
-      break;
-    }
-    }
-    return (NSArraySelectors[MK] = Sel);
-  }
-
-  return NSArraySelectors[MK];
-}
-
-llvm::Optional<NSAPI::NSArrayMethodKind>
-NSAPI::getNSArrayMethodKind(Selector Sel) {
-  for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
-    NSArrayMethodKind MK = NSArrayMethodKind(i);
-    if (Sel == getNSArraySelector(MK))
-      return MK;
-  }
-
-  return llvm::Optional<NSArrayMethodKind>();
-}
-
-Selector NSAPI::getNSDictionarySelector(
-                                       NSDictionaryMethodKind MK) const {
-  if (NSDictionarySelectors[MK].isNull()) {
-    Selector Sel;
-    switch (MK) {
-    case NSDict_dictionary:
-      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
-      break;
-    case NSDict_dictionaryWithDictionary:
-      Sel = Ctx.Selectors.getUnarySelector(
-                                   &Ctx.Idents.get("dictionaryWithDictionary"));
-      break;
-    case NSDict_dictionaryWithObjectForKey: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("dictionaryWithObject"),
-        &Ctx.Idents.get("forKey")
-      };
-      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
-      break;
-    }
-    case NSDict_dictionaryWithObjectsForKeys: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("dictionaryWithObjects"),
-        &Ctx.Idents.get("forKeys")
-      };
-      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
-      break;
-    }
-    case NSDict_dictionaryWithObjectsForKeysCount: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("dictionaryWithObjects"),
-        &Ctx.Idents.get("forKeys"),
-        &Ctx.Idents.get("count")
-      };
-      Sel = Ctx.Selectors.getSelector(3, KeyIdents);
-      break;
-    }
-    case NSDict_dictionaryWithObjectsAndKeys:
-      Sel = Ctx.Selectors.getUnarySelector(
-                               &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
-      break;
-    case NSDict_initWithDictionary:
-      Sel = Ctx.Selectors.getUnarySelector(
-                                         &Ctx.Idents.get("initWithDictionary"));
-      break;
-    case NSDict_initWithObjectsAndKeys:
-      Sel = Ctx.Selectors.getUnarySelector(
-                                     &Ctx.Idents.get("initWithObjectsAndKeys"));
-      break;
-    case NSDict_objectForKey:
-      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
-      break;
-    case NSMutableDict_setObjectForKey: {
-      IdentifierInfo *KeyIdents[] = {
-        &Ctx.Idents.get("setObject"),
-        &Ctx.Idents.get("forKey")
-      };
-      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
-      break;
-    }
-    }
-    return (NSDictionarySelectors[MK] = Sel);
-  }
-
-  return NSDictionarySelectors[MK];
-}
-
-llvm::Optional<NSAPI::NSDictionaryMethodKind>
-NSAPI::getNSDictionaryMethodKind(Selector Sel) {
-  for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
-    NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
-    if (Sel == getNSDictionarySelector(MK))
-      return MK;
-  }
-
-  return llvm::Optional<NSDictionaryMethodKind>();
-}
-
-Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
-                                           bool Instance) const {
-  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
-    "numberWithChar",
-    "numberWithUnsignedChar",
-    "numberWithShort",
-    "numberWithUnsignedShort",
-    "numberWithInt",
-    "numberWithUnsignedInt",
-    "numberWithLong",
-    "numberWithUnsignedLong",
-    "numberWithLongLong",
-    "numberWithUnsignedLongLong",
-    "numberWithFloat",
-    "numberWithDouble",
-    "numberWithBool",
-    "numberWithInteger",
-    "numberWithUnsignedInteger"
-  };
-  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
-    "initWithChar",
-    "initWithUnsignedChar",
-    "initWithShort",
-    "initWithUnsignedShort",
-    "initWithInt",
-    "initWithUnsignedInt",
-    "initWithLong",
-    "initWithUnsignedLong",
-    "initWithLongLong",
-    "initWithUnsignedLongLong",
-    "initWithFloat",
-    "initWithDouble",
-    "initWithBool",
-    "initWithInteger",
-    "initWithUnsignedInteger"
-  };
-
-  Selector *Sels;
-  const char **Names;
-  if (Instance) {
-    Sels = NSNumberInstanceSelectors;
-    Names = InstanceSelectorName;
-  } else {
-    Sels = NSNumberClassSelectors;
-    Names = ClassSelectorName;
-  }
-
-  if (Sels[MK].isNull())
-    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
-  return Sels[MK];
-}
-
-llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
-NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
-  for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
-    NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
-    if (isNSNumberLiteralSelector(MK, Sel))
-      return MK;
-  }
-
-  return llvm::Optional<NSNumberLiteralMethodKind>();
-}
-
-llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
-NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
-  const BuiltinType *BT = T->getAs<BuiltinType>();
-  if (!BT)
-    return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
-
-  const TypedefType *TDT = T->getAs<TypedefType>();
-  if (TDT) {
-    QualType TDTTy = QualType(TDT, 0);
-    if (isObjCBOOLType(TDTTy))
-      return NSAPI::NSNumberWithBool;
-    if (isObjCNSIntegerType(TDTTy))
-      return NSAPI::NSNumberWithInteger;
-    if (isObjCNSUIntegerType(TDTTy))
-      return NSAPI::NSNumberWithUnsignedInteger;
-  }
-
-  switch (BT->getKind()) {
-  case BuiltinType::Char_S:
-  case BuiltinType::SChar:
-    return NSAPI::NSNumberWithChar;
-  case BuiltinType::Char_U:
-  case BuiltinType::UChar:
-    return NSAPI::NSNumberWithUnsignedChar;
-  case BuiltinType::Short:
-    return NSAPI::NSNumberWithShort;
-  case BuiltinType::UShort:
-    return NSAPI::NSNumberWithUnsignedShort;
-  case BuiltinType::Int:
-    return NSAPI::NSNumberWithInt;
-  case BuiltinType::UInt:
-    return NSAPI::NSNumberWithUnsignedInt;
-  case BuiltinType::Long:
-    return NSAPI::NSNumberWithLong;
-  case BuiltinType::ULong:
-    return NSAPI::NSNumberWithUnsignedLong;
-  case BuiltinType::LongLong:
-    return NSAPI::NSNumberWithLongLong;
-  case BuiltinType::ULongLong:
-    return NSAPI::NSNumberWithUnsignedLongLong;
-  case BuiltinType::Float:
-    return NSAPI::NSNumberWithFloat;
-  case BuiltinType::Double:
-    return NSAPI::NSNumberWithDouble;
-  case BuiltinType::Bool:
-    return NSAPI::NSNumberWithBool;
-    
-  case BuiltinType::Void:
-  case BuiltinType::WChar_U:
-  case BuiltinType::WChar_S:
-  case BuiltinType::Char16:
-  case BuiltinType::Char32:
-  case BuiltinType::Int128:
-  case BuiltinType::LongDouble:
-  case BuiltinType::UInt128:
-  case BuiltinType::NullPtr:
-  case BuiltinType::ObjCClass:
-  case BuiltinType::ObjCId:
-  case BuiltinType::ObjCSel:
-  case BuiltinType::BoundMember:
-  case BuiltinType::Dependent:
-  case BuiltinType::Overload:
-  case BuiltinType::UnknownAny:
-  case BuiltinType::ARCUnbridgedCast:
-  case BuiltinType::Half:
-  case BuiltinType::PseudoObject:
-  case BuiltinType::BuiltinFn:
-    break;
-  }
-  
-  return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
-}
-
-/// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
-bool NSAPI::isObjCBOOLType(QualType T) const {
-  return isObjCTypedef(T, "BOOL", BOOLId);
-}
-/// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
-bool NSAPI::isObjCNSIntegerType(QualType T) const {
-  return isObjCTypedef(T, "NSInteger", NSIntegerId);
-}
-/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
-bool NSAPI::isObjCNSUIntegerType(QualType T) const {
-  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
-}
-
-bool NSAPI::isObjCTypedef(QualType T,
-                          StringRef name, IdentifierInfo *&II) const {
-  if (!Ctx.getLangOpts().ObjC1)
-    return false;
-  if (T.isNull())
-    return false;
-
-  if (!II)
-    II = &Ctx.Idents.get(name);
-
-  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
-    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
-      return true;
-    T = TDT->desugar();
-  }
-
-  return false;
-}
-
-bool NSAPI::isObjCEnumerator(const Expr *E,
-                             StringRef name, IdentifierInfo *&II) const {
-  if (!Ctx.getLangOpts().ObjC1)
-    return false;
-  if (!E)
-    return false;
-
-  if (!II)
-    II = &Ctx.Idents.get(name);
-
-  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
-    if (const EnumConstantDecl *
-          EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))
-      return EnumD->getIdentifier() == II;
-
-  return false;
-}
-
-Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,
-                                  Selector &Sel) const {
-  if (Sel.isNull()) {
-    SmallVector<IdentifierInfo *, 4> Idents;
-    for (ArrayRef<StringRef>::const_iterator
-           I = Ids.begin(), E = Ids.end(); I != E; ++I)
-      Idents.push_back(&Ctx.Idents.get(*I));
-    Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());
-  }
-  return Sel;
-}
+//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+

+#include "clang/AST/NSAPI.h"

+#include "clang/AST/ASTContext.h"

+#include "clang/AST/Expr.h"

+

+using namespace clang;

+

+NSAPI::NSAPI(ASTContext &ctx)

+  : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0),

+    NSASCIIStringEncodingId(0), NSUTF8StringEncodingId(0) {

+}

+

+IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {

+  static const char *ClassName[NumClassIds] = {

+    "NSObject",

+    "NSString",

+    "NSArray",

+    "NSMutableArray",

+    "NSDictionary",

+    "NSMutableDictionary",

+    "NSNumber"

+  };

+

+  if (!ClassIds[K])

+    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));

+

+  return ClassIds[K];

+}

+

+Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {

+  if (NSStringSelectors[MK].isNull()) {

+    Selector Sel;

+    switch (MK) {

+    case NSStr_stringWithString:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));

+      break;

+    case NSStr_stringWithUTF8String:

+      Sel = Ctx.Selectors.getUnarySelector(

+                                       &Ctx.Idents.get("stringWithUTF8String"));

+      break;

+    case NSStr_stringWithCStringEncoding: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("stringWithCString"),

+        &Ctx.Idents.get("encoding")

+      };

+      Sel = Ctx.Selectors.getSelector(2, KeyIdents);

+      break;

+    }

+    case NSStr_stringWithCString:

+      Sel= Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithCString"));

+      break;

+    case NSStr_initWithString:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));

+      break;

+    }

+    return (NSStringSelectors[MK] = Sel);

+  }

+

+  return NSStringSelectors[MK];

+}

+

+llvm::Optional<NSAPI::NSStringMethodKind>

+NSAPI::getNSStringMethodKind(Selector Sel) const {

+  for (unsigned i = 0; i != NumNSStringMethods; ++i) {

+    NSStringMethodKind MK = NSStringMethodKind(i);

+    if (Sel == getNSStringSelector(MK))

+      return MK;

+  }

+

+  return llvm::Optional<NSStringMethodKind>();

+}

+

+Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {

+  if (NSArraySelectors[MK].isNull()) {

+    Selector Sel;

+    switch (MK) {

+    case NSArr_array:

+      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));

+      break;

+    case NSArr_arrayWithArray:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));

+      break;

+    case NSArr_arrayWithObject:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));

+      break;

+    case NSArr_arrayWithObjects:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));

+      break;

+    case NSArr_arrayWithObjectsCount: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("arrayWithObjects"),

+        &Ctx.Idents.get("count")

+      };

+      Sel = Ctx.Selectors.getSelector(2, KeyIdents);

+      break;

+    }

+    case NSArr_initWithArray:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));

+      break;

+    case NSArr_initWithObjects:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));

+      break;

+    case NSArr_objectAtIndex:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));

+      break;

+    case NSMutableArr_replaceObjectAtIndex: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("replaceObjectAtIndex"),

+        &Ctx.Idents.get("withObject")

+      };

+      Sel = Ctx.Selectors.getSelector(2, KeyIdents);

+      break;

+    }

+    }

+    return (NSArraySelectors[MK] = Sel);

+  }

+

+  return NSArraySelectors[MK];

+}

+

+llvm::Optional<NSAPI::NSArrayMethodKind>

+NSAPI::getNSArrayMethodKind(Selector Sel) {

+  for (unsigned i = 0; i != NumNSArrayMethods; ++i) {

+    NSArrayMethodKind MK = NSArrayMethodKind(i);

+    if (Sel == getNSArraySelector(MK))

+      return MK;

+  }

+

+  return llvm::Optional<NSArrayMethodKind>();

+}

+

+Selector NSAPI::getNSDictionarySelector(

+                                       NSDictionaryMethodKind MK) const {

+  if (NSDictionarySelectors[MK].isNull()) {

+    Selector Sel;

+    switch (MK) {

+    case NSDict_dictionary:

+      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));

+      break;

+    case NSDict_dictionaryWithDictionary:

+      Sel = Ctx.Selectors.getUnarySelector(

+                                   &Ctx.Idents.get("dictionaryWithDictionary"));

+      break;

+    case NSDict_dictionaryWithObjectForKey: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("dictionaryWithObject"),

+        &Ctx.Idents.get("forKey")

+      };

+      Sel = Ctx.Selectors.getSelector(2, KeyIdents);

+      break;

+    }

+    case NSDict_dictionaryWithObjectsForKeys: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("dictionaryWithObjects"),

+        &Ctx.Idents.get("forKeys")

+      };

+      Sel = Ctx.Selectors.getSelector(2, KeyIdents);

+      break;

+    }

+    case NSDict_dictionaryWithObjectsForKeysCount: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("dictionaryWithObjects"),

+        &Ctx.Idents.get("forKeys"),

+        &Ctx.Idents.get("count")

+      };

+      Sel = Ctx.Selectors.getSelector(3, KeyIdents);

+      break;

+    }

+    case NSDict_dictionaryWithObjectsAndKeys:

+      Sel = Ctx.Selectors.getUnarySelector(

+                               &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));

+      break;

+    case NSDict_initWithDictionary:

+      Sel = Ctx.Selectors.getUnarySelector(

+                                         &Ctx.Idents.get("initWithDictionary"));

+      break;

+    case NSDict_initWithObjectsAndKeys:

+      Sel = Ctx.Selectors.getUnarySelector(

+                                     &Ctx.Idents.get("initWithObjectsAndKeys"));

+      break;

+    case NSDict_objectForKey:

+      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));

+      break;

+    case NSMutableDict_setObjectForKey: {

+      IdentifierInfo *KeyIdents[] = {

+        &Ctx.Idents.get("setObject"),

+        &Ctx.Idents.get("forKey")

+      };

+      Sel = Ctx.Selectors.getSelector(2, KeyIdents);

+      break;

+    }

+    }

+    return (NSDictionarySelectors[MK] = Sel);

+  }

+

+  return NSDictionarySelectors[MK];

+}

+

+llvm::Optional<NSAPI::NSDictionaryMethodKind>

+NSAPI::getNSDictionaryMethodKind(Selector Sel) {

+  for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {

+    NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);

+    if (Sel == getNSDictionarySelector(MK))

+      return MK;

+  }

+

+  return llvm::Optional<NSDictionaryMethodKind>();

+}

+

+Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,

+                                           bool Instance) const {

+  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {

+    "numberWithChar",

+    "numberWithUnsignedChar",

+    "numberWithShort",

+    "numberWithUnsignedShort",

+    "numberWithInt",

+    "numberWithUnsignedInt",

+    "numberWithLong",

+    "numberWithUnsignedLong",

+    "numberWithLongLong",

+    "numberWithUnsignedLongLong",

+    "numberWithFloat",

+    "numberWithDouble",

+    "numberWithBool",

+    "numberWithInteger",

+    "numberWithUnsignedInteger"

+  };

+  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {

+    "initWithChar",

+    "initWithUnsignedChar",

+    "initWithShort",

+    "initWithUnsignedShort",

+    "initWithInt",

+    "initWithUnsignedInt",

+    "initWithLong",

+    "initWithUnsignedLong",

+    "initWithLongLong",

+    "initWithUnsignedLongLong",

+    "initWithFloat",

+    "initWithDouble",

+    "initWithBool",

+    "initWithInteger",

+    "initWithUnsignedInteger"

+  };

+

+  Selector *Sels;

+  const char **Names;

+  if (Instance) {

+    Sels = NSNumberInstanceSelectors;

+    Names = InstanceSelectorName;

+  } else {

+    Sels = NSNumberClassSelectors;

+    Names = ClassSelectorName;

+  }

+

+  if (Sels[MK].isNull())

+    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));

+  return Sels[MK];

+}

+

+llvm::Optional<NSAPI::NSNumberLiteralMethodKind>

+NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {

+  for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {

+    NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);

+    if (isNSNumberLiteralSelector(MK, Sel))

+      return MK;

+  }

+

+  return llvm::Optional<NSNumberLiteralMethodKind>();

+}

+

+llvm::Optional<NSAPI::NSNumberLiteralMethodKind>

+NSAPI::getNSNumberFactoryMethodKind(QualType T) const {

+  const BuiltinType *BT = T->getAs<BuiltinType>();

+  if (!BT)

+    return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();

+

+  const TypedefType *TDT = T->getAs<TypedefType>();

+  if (TDT) {

+    QualType TDTTy = QualType(TDT, 0);

+    if (isObjCBOOLType(TDTTy))

+      return NSAPI::NSNumberWithBool;

+    if (isObjCNSIntegerType(TDTTy))

+      return NSAPI::NSNumberWithInteger;

+    if (isObjCNSUIntegerType(TDTTy))

+      return NSAPI::NSNumberWithUnsignedInteger;

+  }

+

+  switch (BT->getKind()) {

+  case BuiltinType::Char_S:

+  case BuiltinType::SChar:

+    return NSAPI::NSNumberWithChar;

+  case BuiltinType::Char_U:

+  case BuiltinType::UChar:

+    return NSAPI::NSNumberWithUnsignedChar;

+  case BuiltinType::Short:

+    return NSAPI::NSNumberWithShort;

+  case BuiltinType::UShort:

+    return NSAPI::NSNumberWithUnsignedShort;

+  case BuiltinType::Int:

+    return NSAPI::NSNumberWithInt;

+  case BuiltinType::UInt:

+    return NSAPI::NSNumberWithUnsignedInt;

+  case BuiltinType::Long:

+    return NSAPI::NSNumberWithLong;

+  case BuiltinType::ULong:

+    return NSAPI::NSNumberWithUnsignedLong;

+  case BuiltinType::LongLong:

+    return NSAPI::NSNumberWithLongLong;

+  case BuiltinType::ULongLong:

+    return NSAPI::NSNumberWithUnsignedLongLong;

+  case BuiltinType::Float:

+    return NSAPI::NSNumberWithFloat;

+  case BuiltinType::Double:

+    return NSAPI::NSNumberWithDouble;

+  case BuiltinType::Bool:

+    return NSAPI::NSNumberWithBool;

+    

+  case BuiltinType::Void:

+  case BuiltinType::WChar_U:

+  case BuiltinType::WChar_S:

+  case BuiltinType::Char16:

+  case BuiltinType::Char32:

+  case BuiltinType::Int128:

+  case BuiltinType::LongDouble:

+  case BuiltinType::UInt128:

+  case BuiltinType::NullPtr:

+  case BuiltinType::ObjCClass:

+  case BuiltinType::ObjCId:

+  case BuiltinType::ObjCSel:

+  case BuiltinType::OCLImage1d:

+  case BuiltinType::OCLImage1dArray:

+  case BuiltinType::OCLImage1dBuffer:

+  case BuiltinType::OCLImage2d:

+  case BuiltinType::OCLImage2dArray:

+  case BuiltinType::OCLImage3d:

+  case BuiltinType::BoundMember:

+  case BuiltinType::Dependent:

+  case BuiltinType::Overload:

+  case BuiltinType::UnknownAny:

+  case BuiltinType::ARCUnbridgedCast:

+  case BuiltinType::Half:

+  case BuiltinType::PseudoObject:

+  case BuiltinType::BuiltinFn:

+    break;

+  }

+  

+  return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();

+}

+

+/// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.

+bool NSAPI::isObjCBOOLType(QualType T) const {

+  return isObjCTypedef(T, "BOOL", BOOLId);

+}

+/// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.

+bool NSAPI::isObjCNSIntegerType(QualType T) const {

+  return isObjCTypedef(T, "NSInteger", NSIntegerId);

+}

+/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.

+bool NSAPI::isObjCNSUIntegerType(QualType T) const {

+  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);

+}

+

+bool NSAPI::isObjCTypedef(QualType T,

+                          StringRef name, IdentifierInfo *&II) const {

+  if (!Ctx.getLangOpts().ObjC1)

+    return false;

+  if (T.isNull())

+    return false;

+

+  if (!II)

+    II = &Ctx.Idents.get(name);

+

+  while (const TypedefType *TDT = T->getAs<TypedefType>()) {

+    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)

+      return true;

+    T = TDT->desugar();

+  }

+

+  return false;

+}

+

+bool NSAPI::isObjCEnumerator(const Expr *E,

+                             StringRef name, IdentifierInfo *&II) const {

+  if (!Ctx.getLangOpts().ObjC1)

+    return false;

+  if (!E)

+    return false;

+

+  if (!II)

+    II = &Ctx.Idents.get(name);

+

+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))

+    if (const EnumConstantDecl *

+          EnumD = dyn_cast_or_null<EnumConstantDecl>(DRE->getDecl()))

+      return EnumD->getIdentifier() == II;

+

+  return false;

+}

+

+Selector NSAPI::getOrInitSelector(ArrayRef<StringRef> Ids,

+                                  Selector &Sel) const {

+  if (Sel.isNull()) {

+    SmallVector<IdentifierInfo *, 4> Idents;

+    for (ArrayRef<StringRef>::const_iterator

+           I = Ids.begin(), E = Ids.end(); I != E; ++I)

+      Idents.push_back(&Ctx.Idents.get(*I));

+    Sel = Ctx.Selectors.getSelector(Idents.size(), Idents.data());

+  }

+  return Sel;

+}

diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 97448ee..26eee2d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1512,6 +1512,12 @@
   case ObjCId:            return "id";
   case ObjCClass:         return "Class";
   case ObjCSel:           return "SEL";
+  case OCLImage1d:        return "image1d_t";
+  case OCLImage1dArray:   return "image1d_array_t";
+  case OCLImage1dBuffer:  return "image1d_buffer_t";
+  case OCLImage2d:        return "image2d_t";
+  case OCLImage2dArray:   return "image2d_array_t";
+  case OCLImage3d:        return "image3d_t";
   }
   
   llvm_unreachable("Invalid builtin type.");
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index c021cf8..b86d226 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -1,361 +1,367 @@
-//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the TypeLoc subclasses implementations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/TypeLoc.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/TypeLocVisitor.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// TypeLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
-  public:
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
-    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
-      return TyLoc.getLocalSourceRange(); \
-    }
-#include "clang/AST/TypeLocNodes.def"
-  };
-}
-
-SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
-  if (TL.isNull()) return SourceRange();
-  return TypeLocRanger().Visit(TL);
-}
-
-namespace {
-  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
-  public:
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
-    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
-      return TyLoc.getFullDataSize(); \
-    }
-#include "clang/AST/TypeLocNodes.def"
-  };
-}
-
-/// \brief Returns the size of the type source info data block.
-unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
-  if (Ty.isNull()) return 0;
-  return TypeSizer().Visit(TypeLoc(Ty, 0));
-}
-
-namespace {
-  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
-  public:
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
-    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
-      return TyLoc.getNextTypeLoc(); \
-    }
-#include "clang/AST/TypeLocNodes.def"
-  };
-}
-
-/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
-/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
-TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
-  return NextLoc().Visit(TL);
-}
-
-/// \brief Initializes a type location, and all of its children
-/// recursively, as if the entire tree had been written in the
-/// given location.
-void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL, 
-                             SourceLocation Loc) {
-  while (true) {
-    switch (TL.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT)        \
-    case CLASS: {                     \
-      CLASS##TypeLoc TLCasted = cast<CLASS##TypeLoc>(TL); \
-      TLCasted.initializeLocal(Context, Loc);  \
-      TL = TLCasted.getNextTypeLoc(); \
-      if (!TL) return;                \
-      continue;                       \
-    }
-#include "clang/AST/TypeLocNodes.def"
-    }
-  }
-}
-
-SourceLocation TypeLoc::getBeginLoc() const {
-  TypeLoc Cur = *this;
-  TypeLoc LeftMost = Cur;
-  while (true) {
-    switch (Cur.getTypeLocClass()) {
-    case Elaborated:
-      LeftMost = Cur;
-      break;
-    case FunctionProto:
-      if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn()) {
-        LeftMost = Cur;
-        break;
-      }
-      /* Fall through */
-    case FunctionNoProto:
-    case ConstantArray:
-    case DependentSizedArray:
-    case IncompleteArray:
-    case VariableArray:
-      // FIXME: Currently QualifiedTypeLoc does not have a source range
-    case Qualified:
-      Cur = Cur.getNextTypeLoc();
-      continue;
-    default:
-      if (!Cur.getLocalSourceRange().getBegin().isInvalid())
-        LeftMost = Cur;
-      Cur = Cur.getNextTypeLoc();
-      if (Cur.isNull())
-        break;
-      continue;
-    } // switch
-    break;
-  } // while
-  return LeftMost.getLocalSourceRange().getBegin();
-}
-
-SourceLocation TypeLoc::getEndLoc() const {
-  TypeLoc Cur = *this;
-  TypeLoc Last;
-  while (true) {
-    switch (Cur.getTypeLocClass()) {
-    default:
-      if (!Last)
-	Last = Cur;
-      return Last.getLocalSourceRange().getEnd();
-    case Paren:
-    case ConstantArray:
-    case DependentSizedArray:
-    case IncompleteArray:
-    case VariableArray:
-    case FunctionNoProto:
-      Last = Cur;
-      break;
-    case FunctionProto:
-      if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn())
-        Last = TypeLoc();
-      else
-        Last = Cur;
-      break;
-    case Pointer:
-    case BlockPointer:
-    case MemberPointer:
-    case LValueReference:
-    case RValueReference:
-    case PackExpansion:
-      if (!Last)
-	Last = Cur;
-      break;
-    case Qualified:
-    case Elaborated:
-      break;
-    }
-    Cur = Cur.getNextTypeLoc();
-  }
-}
-
-
-namespace {
-  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
-    // Overload resolution does the real work for us.
-    static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
-    static bool isTypeSpec(TypeLoc _) { return false; }
-
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
-    bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
-      return isTypeSpec(TyLoc); \
-    }
-#include "clang/AST/TypeLocNodes.def"
-  };
-}
-
-
-/// \brief Determines if the given type loc corresponds to a
-/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
-/// the type hierarchy, this is made somewhat complicated.
-///
-/// There are a lot of types that currently use TypeSpecTypeLoc
-/// because it's a convenient base class.  Ideally we would not accept
-/// those here, but ideally we would have better implementations for
-/// them.
-bool TypeSpecTypeLoc::classof(const TypeLoc *TL) {
-  if (TL->getType().hasLocalQualifiers()) return false;
-  return TSTChecker().Visit(*TL);
-}
-
-// Reimplemented to account for GNU/C++ extension
-//     typeof unary-expression
-// where there are no parentheses.
-SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
-  if (getRParenLoc().isValid())
-    return SourceRange(getTypeofLoc(), getRParenLoc());
-  else
-    return SourceRange(getTypeofLoc(),
-                       getUnderlyingExpr()->getSourceRange().getEnd());
-}
-
-
-TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
-  if (needsExtraLocalData())
-    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
-  switch (getTypePtr()->getKind()) {
-  case BuiltinType::Void:
-    return TST_void;
-  case BuiltinType::Bool:
-    return TST_bool;
-  case BuiltinType::Char_U:
-  case BuiltinType::Char_S:
-    return TST_char;
-  case BuiltinType::Char16:
-    return TST_char16;
-  case BuiltinType::Char32:
-    return TST_char32;
-  case BuiltinType::WChar_S:
-  case BuiltinType::WChar_U:
-    return TST_wchar;
-  case BuiltinType::UChar:
-  case BuiltinType::UShort:
-  case BuiltinType::UInt:
-  case BuiltinType::ULong:
-  case BuiltinType::ULongLong:
-  case BuiltinType::UInt128:
-  case BuiltinType::SChar:
-  case BuiltinType::Short:
-  case BuiltinType::Int:
-  case BuiltinType::Long:
-  case BuiltinType::LongLong:
-  case BuiltinType::Int128:
-  case BuiltinType::Half:
-  case BuiltinType::Float:
-  case BuiltinType::Double:
-  case BuiltinType::LongDouble:
-    llvm_unreachable("Builtin type needs extra local data!");
-    // Fall through, if the impossible happens.
-      
-  case BuiltinType::NullPtr:
-  case BuiltinType::Overload:
-  case BuiltinType::Dependent:
-  case BuiltinType::BoundMember:
-  case BuiltinType::UnknownAny:
-  case BuiltinType::ARCUnbridgedCast:
-  case BuiltinType::PseudoObject:
-  case BuiltinType::ObjCId:
-  case BuiltinType::ObjCClass:
-  case BuiltinType::ObjCSel:
-  case BuiltinType::BuiltinFn:
-    return TST_unspecified;
-  }
-
-  llvm_unreachable("Invalid BuiltinType Kind!");
-}
-
-TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
-  while (ParenTypeLoc* PTL = dyn_cast<ParenTypeLoc>(&TL))
-    TL = PTL->getInnerLoc();
-  return TL;
-}
-
-void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 
-                                        SourceLocation Loc) {
-  setElaboratedKeywordLoc(Loc);
-  NestedNameSpecifierLocBuilder Builder;
-  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
-  setQualifierLoc(Builder.getWithLocInContext(Context));
-}
-
-void DependentNameTypeLoc::initializeLocal(ASTContext &Context, 
-                                           SourceLocation Loc) {
-  setElaboratedKeywordLoc(Loc);
-  NestedNameSpecifierLocBuilder Builder;
-  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
-  setQualifierLoc(Builder.getWithLocInContext(Context));
-  setNameLoc(Loc);
-}
-
-void
-DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
-                                                        SourceLocation Loc) {
-  setElaboratedKeywordLoc(Loc);
-  if (getTypePtr()->getQualifier()) {
-    NestedNameSpecifierLocBuilder Builder;
-    Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
-    setQualifierLoc(Builder.getWithLocInContext(Context));
-  } else {
-    setQualifierLoc(NestedNameSpecifierLoc());
-  }
-  setTemplateKeywordLoc(Loc);
-  setTemplateNameLoc(Loc);
-  setLAngleLoc(Loc);
-  setRAngleLoc(Loc);
-  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
-                                                   getTypePtr()->getArgs(),
-                                                   getArgInfos(), Loc);
-}
-
-void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, 
-                                                      unsigned NumArgs,
-                                                  const TemplateArgument *Args,
-                                              TemplateArgumentLocInfo *ArgInfos,
-                                                      SourceLocation Loc) {
-  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
-    switch (Args[i].getKind()) {
-    case TemplateArgument::Null: 
-    case TemplateArgument::Declaration:
-    case TemplateArgument::Integral:
-    case TemplateArgument::NullPtr:
-      llvm_unreachable("Impossible TemplateArgument");
-
-    case TemplateArgument::Expression:
-      ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
-      break;
-      
-    case TemplateArgument::Type:
-      ArgInfos[i] = TemplateArgumentLocInfo(
-                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(), 
-                                                           Loc));
-      break;
-
-    case TemplateArgument::Template:
-    case TemplateArgument::TemplateExpansion: {
-      NestedNameSpecifierLocBuilder Builder;
-      TemplateName Template = Args[i].getAsTemplate();
-      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
-        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
-      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
-        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
-      
-      ArgInfos[i] = TemplateArgumentLocInfo(
-                                           Builder.getWithLocInContext(Context),
-                                            Loc, 
-                                Args[i].getKind() == TemplateArgument::Template
-                                            ? SourceLocation()
-                                            : Loc);
-      break;
-    }
-
-    case TemplateArgument::Pack:
-      ArgInfos[i] = TemplateArgumentLocInfo();
-      break;
-    }
-  }
-}
+//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+//  This file defines the TypeLoc subclasses implementations.

+//

+//===----------------------------------------------------------------------===//

+

+#include "clang/AST/TypeLoc.h"

+#include "clang/AST/ASTContext.h"

+#include "clang/AST/Expr.h"

+#include "clang/AST/TypeLocVisitor.h"

+#include "llvm/Support/ErrorHandling.h"

+#include "llvm/Support/raw_ostream.h"

+using namespace clang;

+

+//===----------------------------------------------------------------------===//

+// TypeLoc Implementation

+//===----------------------------------------------------------------------===//

+

+namespace {

+  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {

+  public:

+#define ABSTRACT_TYPELOC(CLASS, PARENT)

+#define TYPELOC(CLASS, PARENT) \

+    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \

+      return TyLoc.getLocalSourceRange(); \

+    }

+#include "clang/AST/TypeLocNodes.def"

+  };

+}

+

+SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {

+  if (TL.isNull()) return SourceRange();

+  return TypeLocRanger().Visit(TL);

+}

+

+namespace {

+  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {

+  public:

+#define ABSTRACT_TYPELOC(CLASS, PARENT)

+#define TYPELOC(CLASS, PARENT) \

+    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \

+      return TyLoc.getFullDataSize(); \

+    }

+#include "clang/AST/TypeLocNodes.def"

+  };

+}

+

+/// \brief Returns the size of the type source info data block.

+unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {

+  if (Ty.isNull()) return 0;

+  return TypeSizer().Visit(TypeLoc(Ty, 0));

+}

+

+namespace {

+  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {

+  public:

+#define ABSTRACT_TYPELOC(CLASS, PARENT)

+#define TYPELOC(CLASS, PARENT) \

+    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \

+      return TyLoc.getNextTypeLoc(); \

+    }

+#include "clang/AST/TypeLocNodes.def"

+  };

+}

+

+/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the

+/// TypeLoc is a PointerLoc and next TypeLoc is for "int".

+TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {

+  return NextLoc().Visit(TL);

+}

+

+/// \brief Initializes a type location, and all of its children

+/// recursively, as if the entire tree had been written in the

+/// given location.

+void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL, 

+                             SourceLocation Loc) {

+  while (true) {

+    switch (TL.getTypeLocClass()) {

+#define ABSTRACT_TYPELOC(CLASS, PARENT)

+#define TYPELOC(CLASS, PARENT)        \

+    case CLASS: {                     \

+      CLASS##TypeLoc TLCasted = cast<CLASS##TypeLoc>(TL); \

+      TLCasted.initializeLocal(Context, Loc);  \

+      TL = TLCasted.getNextTypeLoc(); \

+      if (!TL) return;                \

+      continue;                       \

+    }

+#include "clang/AST/TypeLocNodes.def"

+    }

+  }

+}

+

+SourceLocation TypeLoc::getBeginLoc() const {

+  TypeLoc Cur = *this;

+  TypeLoc LeftMost = Cur;

+  while (true) {

+    switch (Cur.getTypeLocClass()) {

+    case Elaborated:

+      LeftMost = Cur;

+      break;

+    case FunctionProto:

+      if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn()) {

+        LeftMost = Cur;

+        break;

+      }

+      /* Fall through */

+    case FunctionNoProto:

+    case ConstantArray:

+    case DependentSizedArray:

+    case IncompleteArray:

+    case VariableArray:

+      // FIXME: Currently QualifiedTypeLoc does not have a source range

+    case Qualified:

+      Cur = Cur.getNextTypeLoc();

+      continue;

+    default:

+      if (!Cur.getLocalSourceRange().getBegin().isInvalid())

+        LeftMost = Cur;

+      Cur = Cur.getNextTypeLoc();

+      if (Cur.isNull())

+        break;

+      continue;

+    } // switch

+    break;

+  } // while

+  return LeftMost.getLocalSourceRange().getBegin();

+}

+

+SourceLocation TypeLoc::getEndLoc() const {

+  TypeLoc Cur = *this;

+  TypeLoc Last;

+  while (true) {

+    switch (Cur.getTypeLocClass()) {

+    default:

+      if (!Last)

+	Last = Cur;

+      return Last.getLocalSourceRange().getEnd();

+    case Paren:

+    case ConstantArray:

+    case DependentSizedArray:

+    case IncompleteArray:

+    case VariableArray:

+    case FunctionNoProto:

+      Last = Cur;

+      break;

+    case FunctionProto:

+      if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn())

+        Last = TypeLoc();

+      else

+        Last = Cur;

+      break;

+    case Pointer:

+    case BlockPointer:

+    case MemberPointer:

+    case LValueReference:

+    case RValueReference:

+    case PackExpansion:

+      if (!Last)

+	Last = Cur;

+      break;

+    case Qualified:

+    case Elaborated:

+      break;

+    }

+    Cur = Cur.getNextTypeLoc();

+  }

+}

+

+

+namespace {

+  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {

+    // Overload resolution does the real work for us.

+    static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }

+    static bool isTypeSpec(TypeLoc _) { return false; }

+

+#define ABSTRACT_TYPELOC(CLASS, PARENT)

+#define TYPELOC(CLASS, PARENT) \

+    bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \

+      return isTypeSpec(TyLoc); \

+    }

+#include "clang/AST/TypeLocNodes.def"

+  };

+}

+

+

+/// \brief Determines if the given type loc corresponds to a

+/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in

+/// the type hierarchy, this is made somewhat complicated.

+///

+/// There are a lot of types that currently use TypeSpecTypeLoc

+/// because it's a convenient base class.  Ideally we would not accept

+/// those here, but ideally we would have better implementations for

+/// them.

+bool TypeSpecTypeLoc::classof(const TypeLoc *TL) {

+  if (TL->getType().hasLocalQualifiers()) return false;

+  return TSTChecker().Visit(*TL);

+}

+

+// Reimplemented to account for GNU/C++ extension

+//     typeof unary-expression

+// where there are no parentheses.

+SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {

+  if (getRParenLoc().isValid())

+    return SourceRange(getTypeofLoc(), getRParenLoc());

+  else

+    return SourceRange(getTypeofLoc(),

+                       getUnderlyingExpr()->getSourceRange().getEnd());

+}

+

+

+TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {

+  if (needsExtraLocalData())

+    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);

+  switch (getTypePtr()->getKind()) {

+  case BuiltinType::Void:

+    return TST_void;

+  case BuiltinType::Bool:

+    return TST_bool;

+  case BuiltinType::Char_U:

+  case BuiltinType::Char_S:

+    return TST_char;

+  case BuiltinType::Char16:

+    return TST_char16;

+  case BuiltinType::Char32:

+    return TST_char32;

+  case BuiltinType::WChar_S:

+  case BuiltinType::WChar_U:

+    return TST_wchar;

+  case BuiltinType::UChar:

+  case BuiltinType::UShort:

+  case BuiltinType::UInt:

+  case BuiltinType::ULong:

+  case BuiltinType::ULongLong:

+  case BuiltinType::UInt128:

+  case BuiltinType::SChar:

+  case BuiltinType::Short:

+  case BuiltinType::Int:

+  case BuiltinType::Long:

+  case BuiltinType::LongLong:

+  case BuiltinType::Int128:

+  case BuiltinType::Half:

+  case BuiltinType::Float:

+  case BuiltinType::Double:

+  case BuiltinType::LongDouble:

+    llvm_unreachable("Builtin type needs extra local data!");

+    // Fall through, if the impossible happens.

+      

+  case BuiltinType::NullPtr:

+  case BuiltinType::Overload:

+  case BuiltinType::Dependent:

+  case BuiltinType::BoundMember:

+  case BuiltinType::UnknownAny:

+  case BuiltinType::ARCUnbridgedCast:

+  case BuiltinType::PseudoObject:

+  case BuiltinType::ObjCId:

+  case BuiltinType::ObjCClass:

+  case BuiltinType::ObjCSel:

+  case BuiltinType::OCLImage1d:

+  case BuiltinType::OCLImage1dArray:

+  case BuiltinType::OCLImage1dBuffer:

+  case BuiltinType::OCLImage2d:

+  case BuiltinType::OCLImage2dArray:

+  case BuiltinType::OCLImage3d:

+  case BuiltinType::BuiltinFn:

+    return TST_unspecified;

+  }

+

+  llvm_unreachable("Invalid BuiltinType Kind!");

+}

+

+TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {

+  while (ParenTypeLoc* PTL = dyn_cast<ParenTypeLoc>(&TL))

+    TL = PTL->getInnerLoc();

+  return TL;

+}

+

+void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 

+                                        SourceLocation Loc) {

+  setElaboratedKeywordLoc(Loc);

+  NestedNameSpecifierLocBuilder Builder;

+  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);

+  setQualifierLoc(Builder.getWithLocInContext(Context));

+}

+

+void DependentNameTypeLoc::initializeLocal(ASTContext &Context, 

+                                           SourceLocation Loc) {

+  setElaboratedKeywordLoc(Loc);

+  NestedNameSpecifierLocBuilder Builder;

+  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);

+  setQualifierLoc(Builder.getWithLocInContext(Context));

+  setNameLoc(Loc);

+}

+

+void

+DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,

+                                                        SourceLocation Loc) {

+  setElaboratedKeywordLoc(Loc);

+  if (getTypePtr()->getQualifier()) {

+    NestedNameSpecifierLocBuilder Builder;

+    Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);

+    setQualifierLoc(Builder.getWithLocInContext(Context));

+  } else {

+    setQualifierLoc(NestedNameSpecifierLoc());

+  }

+  setTemplateKeywordLoc(Loc);

+  setTemplateNameLoc(Loc);

+  setLAngleLoc(Loc);

+  setRAngleLoc(Loc);

+  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),

+                                                   getTypePtr()->getArgs(),

+                                                   getArgInfos(), Loc);

+}

+

+void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, 

+                                                      unsigned NumArgs,

+                                                  const TemplateArgument *Args,

+                                              TemplateArgumentLocInfo *ArgInfos,

+                                                      SourceLocation Loc) {

+  for (unsigned i = 0, e = NumArgs; i != e; ++i) {

+    switch (Args[i].getKind()) {

+    case TemplateArgument::Null: 

+    case TemplateArgument::Declaration:

+    case TemplateArgument::Integral:

+    case TemplateArgument::NullPtr:

+      llvm_unreachable("Impossible TemplateArgument");

+

+    case TemplateArgument::Expression:

+      ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());

+      break;

+      

+    case TemplateArgument::Type:

+      ArgInfos[i] = TemplateArgumentLocInfo(

+                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(), 

+                                                           Loc));

+      break;

+

+    case TemplateArgument::Template:

+    case TemplateArgument::TemplateExpansion: {

+      NestedNameSpecifierLocBuilder Builder;

+      TemplateName Template = Args[i].getAsTemplate();

+      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())

+        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);

+      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())

+        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);

+      

+      ArgInfos[i] = TemplateArgumentLocInfo(

+                                           Builder.getWithLocInContext(Context),

+                                            Loc, 

+                                Args[i].getKind() == TemplateArgument::Template

+                                            ? SourceLocation()

+                                            : Loc);

+      break;

+    }

+

+    case TemplateArgument::Pack:

+      ArgInfos[i] = TemplateArgumentLocInfo();

+      break;

+    }

+  }

+}

diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 844514b..c16081f 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1,2802 +1,2834 @@
-//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This coordinates the debug information generation while generating code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGDebugInfo.h"
-#include "CGBlocks.h"
-#include "CGObjCRuntime.h"
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Version.h"
-#include "clang/Frontend/CodeGenOptions.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Constants.h"
-#include "llvm/DataLayout.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/FileSystem.h"
-using namespace clang;
-using namespace clang::CodeGen;
-
-CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
-  : CGM(CGM), DBuilder(CGM.getModule()),
-    BlockLiteralGenericSet(false) {
-  CreateCompileUnit();
-}
-
-CGDebugInfo::~CGDebugInfo() {
-  assert(LexicalBlockStack.empty() &&
-         "Region stack mismatch, stack not empty!");
-}
-
-void CGDebugInfo::setLocation(SourceLocation Loc) {
-  // If the new location isn't valid return.
-  if (!Loc.isValid()) return;
-
-  CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);
-
-  // If we've changed files in the middle of a lexical scope go ahead
-  // and create a new lexical scope with file node if it's different
-  // from the one in the scope.
-  if (LexicalBlockStack.empty()) return;
-
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);
-  PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc);
-
-  if (PCLoc.isInvalid() || PPLoc.isInvalid() ||
-      !strcmp(PPLoc.getFilename(), PCLoc.getFilename()))
-    return;
-
-  llvm::MDNode *LB = LexicalBlockStack.back();
-  llvm::DIScope Scope = llvm::DIScope(LB);
-  if (Scope.isLexicalBlockFile()) {
-    llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(LB);
-    llvm::DIDescriptor D
-      = DBuilder.createLexicalBlockFile(LBF.getScope(),
-                                        getOrCreateFile(CurLoc));
-    llvm::MDNode *N = D;
-    LexicalBlockStack.pop_back();
-    LexicalBlockStack.push_back(N);
-  } else if (Scope.isLexicalBlock()) {
-    llvm::DIDescriptor D
-      = DBuilder.createLexicalBlockFile(Scope, getOrCreateFile(CurLoc));
-    llvm::MDNode *N = D;
-    LexicalBlockStack.pop_back();
-    LexicalBlockStack.push_back(N);
-  }
-}
-
-/// getContextDescriptor - Get context info for the decl.
-llvm::DIDescriptor CGDebugInfo::getContextDescriptor(const Decl *Context) {
-  if (!Context)
-    return TheCU;
-
-  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
-    I = RegionMap.find(Context);
-  if (I != RegionMap.end()) {
-    llvm::Value *V = I->second;
-    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));
-  }
-
-  // Check namespace.
-  if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
-    return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl));
-
-  if (const RecordDecl *RDecl = dyn_cast<RecordDecl>(Context)) {
-    if (!RDecl->isDependentType()) {
-      llvm::DIType Ty = getOrCreateType(CGM.getContext().getTypeDeclType(RDecl),
-                                        getOrCreateMainFile());
-      return llvm::DIDescriptor(Ty);
-    }
-  }
-  return TheCU;
-}
-
-/// getFunctionName - Get function name for the given FunctionDecl. If the
-/// name is constructred on demand (e.g. C++ destructor) then the name
-/// is stored on the side.
-StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {
-  assert (FD && "Invalid FunctionDecl!");
-  IdentifierInfo *FII = FD->getIdentifier();
-  FunctionTemplateSpecializationInfo *Info
-    = FD->getTemplateSpecializationInfo();
-  if (!Info && FII)
-    return FII->getName();
-
-  // Otherwise construct human readable name for debug info.
-  std::string NS = FD->getNameAsString();
-
-  // Add any template specialization args.
-  if (Info) {
-    const TemplateArgumentList *TArgs = Info->TemplateArguments;
-    const TemplateArgument *Args = TArgs->data();
-    unsigned NumArgs = TArgs->size();
-    PrintingPolicy Policy(CGM.getLangOpts());
-    NS += TemplateSpecializationType::PrintTemplateArgumentList(Args,
-                                                                NumArgs,
-                                                                Policy);
-  }
-
-  // Copy this name on the side and use its reference.
-  char *StrPtr = DebugInfoNames.Allocate<char>(NS.length());
-  memcpy(StrPtr, NS.data(), NS.length());
-  return StringRef(StrPtr, NS.length());
-}
-
-StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {
-  SmallString<256> MethodName;
-  llvm::raw_svector_ostream OS(MethodName);
-  OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
-  const DeclContext *DC = OMD->getDeclContext();
-  if (const ObjCImplementationDecl *OID = 
-      dyn_cast<const ObjCImplementationDecl>(DC)) {
-     OS << OID->getName();
-  } else if (const ObjCInterfaceDecl *OID = 
-             dyn_cast<const ObjCInterfaceDecl>(DC)) {
-      OS << OID->getName();
-  } else if (const ObjCCategoryImplDecl *OCD = 
-             dyn_cast<const ObjCCategoryImplDecl>(DC)){
-      OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '(' <<
-          OCD->getIdentifier()->getNameStart() << ')';
-  }
-  OS << ' ' << OMD->getSelector().getAsString() << ']';
-
-  char *StrPtr = DebugInfoNames.Allocate<char>(OS.tell());
-  memcpy(StrPtr, MethodName.begin(), OS.tell());
-  return StringRef(StrPtr, OS.tell());
-}
-
-/// getSelectorName - Return selector name. This is used for debugging
-/// info.
-StringRef CGDebugInfo::getSelectorName(Selector S) {
-  const std::string &SName = S.getAsString();
-  char *StrPtr = DebugInfoNames.Allocate<char>(SName.size());
-  memcpy(StrPtr, SName.data(), SName.size());
-  return StringRef(StrPtr, SName.size());
-}
-
-/// getClassName - Get class name including template argument list.
-StringRef 
-CGDebugInfo::getClassName(const RecordDecl *RD) {
-  const ClassTemplateSpecializationDecl *Spec
-    = dyn_cast<ClassTemplateSpecializationDecl>(RD);
-  if (!Spec)
-    return RD->getName();
-
-  const TemplateArgument *Args;
-  unsigned NumArgs;
-  if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
-    const TemplateSpecializationType *TST =
-      cast<TemplateSpecializationType>(TAW->getType());
-    Args = TST->getArgs();
-    NumArgs = TST->getNumArgs();
-  } else {
-    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-    Args = TemplateArgs.data();
-    NumArgs = TemplateArgs.size();
-  }
-  StringRef Name = RD->getIdentifier()->getName();
-  PrintingPolicy Policy(CGM.getLangOpts());
-  std::string TemplateArgList =
-    TemplateSpecializationType::PrintTemplateArgumentList(Args, NumArgs, Policy);
-
-  // Copy this name on the side and use its reference.
-  size_t Length = Name.size() + TemplateArgList.size();
-  char *StrPtr = DebugInfoNames.Allocate<char>(Length);
-  memcpy(StrPtr, Name.data(), Name.size());
-  memcpy(StrPtr + Name.size(), TemplateArgList.data(), TemplateArgList.size());
-  return StringRef(StrPtr, Length);
-}
-
-/// getOrCreateFile - Get the file debug info descriptor for the input location.
-llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
-  if (!Loc.isValid())
-    // If Location is not valid then use main input file.
-    return DBuilder.createFile(TheCU.getFilename(), TheCU.getDirectory());
-
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
-
-  if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty())
-    // If the location is not valid then use main input file.
-    return DBuilder.createFile(TheCU.getFilename(), TheCU.getDirectory());
-
-  // Cache the results.
-  const char *fname = PLoc.getFilename();
-  llvm::DenseMap<const char *, llvm::WeakVH>::iterator it =
-    DIFileCache.find(fname);
-
-  if (it != DIFileCache.end()) {
-    // Verify that the information still exists.
-    if (llvm::Value *V = it->second)
-      return llvm::DIFile(cast<llvm::MDNode>(V));
-  }
-
-  llvm::DIFile F = DBuilder.createFile(PLoc.getFilename(), getCurrentDirname());
-
-  DIFileCache[fname] = F;
-  return F;
-}
-
-/// getOrCreateMainFile - Get the file info for main compile unit.
-llvm::DIFile CGDebugInfo::getOrCreateMainFile() {
-  return DBuilder.createFile(TheCU.getFilename(), TheCU.getDirectory());
-}
-
-/// getLineNumber - Get line number for the location. If location is invalid
-/// then use current location.
-unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {
-  if (Loc.isInvalid() && CurLoc.isInvalid())
-    return 0;
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);
-  return PLoc.isValid()? PLoc.getLine() : 0;
-}
-
-/// getColumnNumber - Get column number for the location.
-unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc) {
-  // We may not want column information at all.
-  if (!CGM.getCodeGenOpts().DebugColumnInfo)
-    return 0;
-
-  // If the location is invalid then use the current column.
-  if (Loc.isInvalid() && CurLoc.isInvalid())
-    return 0;
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);
-  return PLoc.isValid()? PLoc.getColumn() : 0;
-}
-
-StringRef CGDebugInfo::getCurrentDirname() {
-  if (!CGM.getCodeGenOpts().DebugCompilationDir.empty())
-    return CGM.getCodeGenOpts().DebugCompilationDir;
-
-  if (!CWDName.empty())
-    return CWDName;
-  SmallString<256> CWD;
-  llvm::sys::fs::current_path(CWD);
-  char *CompDirnamePtr = DebugInfoNames.Allocate<char>(CWD.size());
-  memcpy(CompDirnamePtr, CWD.data(), CWD.size());
-  return CWDName = StringRef(CompDirnamePtr, CWD.size());
-}
-
-/// CreateCompileUnit - Create new compile unit.
-void CGDebugInfo::CreateCompileUnit() {
-
-  // Get absolute path name.
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
-  if (MainFileName.empty())
-    MainFileName = "<unknown>";
-
-  // The main file name provided via the "-main-file-name" option contains just
-  // the file name itself with no path information. This file name may have had
-  // a relative path, so we look into the actual file entry for the main
-  // file to determine the real absolute path for the file.
-  std::string MainFileDir;
-  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
-    MainFileDir = MainFile->getDir()->getName();
-    if (MainFileDir != ".")
-      MainFileName = MainFileDir + "/" + MainFileName;
-  }
-
-  // Save filename string.
-  char *FilenamePtr = DebugInfoNames.Allocate<char>(MainFileName.length());
-  memcpy(FilenamePtr, MainFileName.c_str(), MainFileName.length());
-  StringRef Filename(FilenamePtr, MainFileName.length());
-  
-  unsigned LangTag;
-  const LangOptions &LO = CGM.getLangOpts();
-  if (LO.CPlusPlus) {
-    if (LO.ObjC1)
-      LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
-    else
-      LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
-  } else if (LO.ObjC1) {
-    LangTag = llvm::dwarf::DW_LANG_ObjC;
-  } else if (LO.C99) {
-    LangTag = llvm::dwarf::DW_LANG_C99;
-  } else {
-    LangTag = llvm::dwarf::DW_LANG_C89;
-  }
-
-  std::string Producer = getClangFullVersion();
-
-  // Figure out which version of the ObjC runtime we have.
-  unsigned RuntimeVers = 0;
-  if (LO.ObjC1)
-    RuntimeVers = LO.ObjCRuntime.isNonFragile() ? 2 : 1;
-
-  // Create new compile unit.
-  DBuilder.createCompileUnit(
-    LangTag, Filename, getCurrentDirname(),
-    Producer,
-    LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers);
-  // FIXME - Eliminate TheCU.
-  TheCU = llvm::DICompileUnit(DBuilder.getCU());
-}
-
-/// CreateType - Get the Basic type from the cache or create a new
-/// one if necessary.
-llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {
-  unsigned Encoding = 0;
-  StringRef BTName;
-  switch (BT->getKind()) {
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-  case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-  case BuiltinType::Dependent:
-    llvm_unreachable("Unexpected builtin type");
-  case BuiltinType::NullPtr:
-    return DBuilder.
-      createNullPtrType(BT->getName(CGM.getLangOpts()));
-  case BuiltinType::Void:
-    return llvm::DIType();
-  case BuiltinType::ObjCClass:
-    if (ClassTy.Verify())
-      return ClassTy;
-    ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                         "objc_class", TheCU,
-                                         getOrCreateMainFile(), 0);
-    return ClassTy;
-  case BuiltinType::ObjCId: {
-    // typedef struct objc_class *Class;
-    // typedef struct objc_object {
-    //  Class isa;
-    // } *id;
-
-    if (ObjTy.Verify())
-      return ObjTy;
-
-    if (!ClassTy.Verify())
-      ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                           "objc_class", TheCU,
-                                           getOrCreateMainFile(), 0);
-
-    unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
-    
-    llvm::DIType ISATy = DBuilder.createPointerType(ClassTy, Size);
-
-    llvm::DIType FwdTy =  DBuilder.createStructType(TheCU, "objc_object", 
-                                                    getOrCreateMainFile(),
-                                                    0, 0, 0, 0,
-                                                    llvm::DIArray());
-
-    llvm::TrackingVH<llvm::MDNode> ObjNode(FwdTy);
-    SmallVector<llvm::Value *, 1> EltTys;
-    llvm::DIType FieldTy = 
-      DBuilder.createMemberType(llvm::DIDescriptor(ObjNode), "isa",
-                                getOrCreateMainFile(), 0, Size,
-                                0, 0, 0, ISATy);
-    EltTys.push_back(FieldTy);
-    llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-
-    ObjNode->replaceOperandWith(10, Elements);
-    ObjTy = llvm::DIType(ObjNode);
-    return ObjTy;
-  }
-  case BuiltinType::ObjCSel: {
-    if (SelTy.Verify())
-      return SelTy;
-    SelTy =
-      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                 "objc_selector", TheCU, getOrCreateMainFile(),
-                                 0);
-    return SelTy;
-  }
-  case BuiltinType::UChar:
-  case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
-  case BuiltinType::Char_S:
-  case BuiltinType::SChar: Encoding = llvm::dwarf::DW_ATE_signed_char; break;
-  case BuiltinType::Char16:
-  case BuiltinType::Char32: Encoding = llvm::dwarf::DW_ATE_UTF; break;
-  case BuiltinType::UShort:
-  case BuiltinType::UInt:
-  case BuiltinType::UInt128:
-  case BuiltinType::ULong:
-  case BuiltinType::WChar_U:
-  case BuiltinType::ULongLong: Encoding = llvm::dwarf::DW_ATE_unsigned; break;
-  case BuiltinType::Short:
-  case BuiltinType::Int:
-  case BuiltinType::Int128:
-  case BuiltinType::Long:
-  case BuiltinType::WChar_S:
-  case BuiltinType::LongLong:  Encoding = llvm::dwarf::DW_ATE_signed; break;
-  case BuiltinType::Bool:      Encoding = llvm::dwarf::DW_ATE_boolean; break;
-  case BuiltinType::Half:
-  case BuiltinType::Float:
-  case BuiltinType::LongDouble:
-  case BuiltinType::Double:    Encoding = llvm::dwarf::DW_ATE_float; break;
-  }
-
-  switch (BT->getKind()) {
-  case BuiltinType::Long:      BTName = "long int"; break;
-  case BuiltinType::LongLong:  BTName = "long long int"; break;
-  case BuiltinType::ULong:     BTName = "long unsigned int"; break;
-  case BuiltinType::ULongLong: BTName = "long long unsigned int"; break;
-  default:
-    BTName = BT->getName(CGM.getLangOpts());
-    break;
-  }
-  // Bit size, align and offset of the type.
-  uint64_t Size = CGM.getContext().getTypeSize(BT);
-  uint64_t Align = CGM.getContext().getTypeAlign(BT);
-  llvm::DIType DbgTy = 
-    DBuilder.createBasicType(BTName, Size, Align, Encoding);
-  return DbgTy;
-}
-
-llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) {
-  // Bit size, align and offset of the type.
-  unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
-  if (Ty->isComplexIntegerType())
-    Encoding = llvm::dwarf::DW_ATE_lo_user;
-
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
-  llvm::DIType DbgTy = 
-    DBuilder.createBasicType("complex", Size, Align, Encoding);
-
-  return DbgTy;
-}
-
-/// CreateCVRType - Get the qualified type from the cache or create
-/// a new one if necessary.
-llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
-  QualifierCollector Qc;
-  const Type *T = Qc.strip(Ty);
-
-  // Ignore these qualifiers for now.
-  Qc.removeObjCGCAttr();
-  Qc.removeAddressSpace();
-  Qc.removeObjCLifetime();
-
-  // We will create one Derived type for one qualifier and recurse to handle any
-  // additional ones.
-  unsigned Tag;
-  if (Qc.hasConst()) {
-    Tag = llvm::dwarf::DW_TAG_const_type;
-    Qc.removeConst();
-  } else if (Qc.hasVolatile()) {
-    Tag = llvm::dwarf::DW_TAG_volatile_type;
-    Qc.removeVolatile();
-  } else if (Qc.hasRestrict()) {
-    Tag = llvm::dwarf::DW_TAG_restrict_type;
-    Qc.removeRestrict();
-  } else {
-    assert(Qc.empty() && "Unknown type qualifier for debug info");
-    return getOrCreateType(QualType(T, 0), Unit);
-  }
-
-  llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
-
-  // No need to fill in the Name, Line, Size, Alignment, Offset in case of
-  // CVR derived types.
-  llvm::DIType DbgTy = DBuilder.createQualifiedType(Tag, FromTy);
-  
-  return DbgTy;
-}
-
-llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
-                                     llvm::DIFile Unit) {
-  llvm::DIType DbgTy =
-    CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, 
-                          Ty->getPointeeType(), Unit);
-  return DbgTy;
-}
-
-llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
-                                     llvm::DIFile Unit) {
-  return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, 
-                               Ty->getPointeeType(), Unit);
-}
-
-// Creates a forward declaration for a RecordDecl in the given context.
-llvm::DIType CGDebugInfo::createRecordFwdDecl(const RecordDecl *RD,
-                                              llvm::DIDescriptor Ctx) {
-  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
-  unsigned Line = getLineNumber(RD->getLocation());
-  StringRef RDName = getClassName(RD);
-
-  unsigned Tag = 0;
-  if (RD->isStruct() || RD->isInterface())
-    Tag = llvm::dwarf::DW_TAG_structure_type;
-  else if (RD->isUnion())
-    Tag = llvm::dwarf::DW_TAG_union_type;
-  else {
-    assert(RD->isClass());
-    Tag = llvm::dwarf::DW_TAG_class_type;
-  }
-
-  // Create the type.
-  return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line);
-}
-
-// Walk up the context chain and create forward decls for record decls,
-// and normal descriptors for namespaces.
-llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) {
-  if (!Context)
-    return TheCU;
-
-  // See if we already have the parent.
-  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
-    I = RegionMap.find(Context);
-  if (I != RegionMap.end()) {
-    llvm::Value *V = I->second;
-    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));
-  }
-  
-  // Check namespace.
-  if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
-    return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl));
-
-  if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) {
-    if (!RD->isDependentType()) {
-      llvm::DIType Ty = getOrCreateLimitedType(CGM.getContext().getTypeDeclType(RD),
-					       getOrCreateMainFile());
-      return llvm::DIDescriptor(Ty);
-    }
-  }
-  return TheCU;
-}
-
-/// CreatePointeeType - Create Pointee type. If Pointee is a record
-/// then emit record's fwd if debug info size reduction is enabled.
-llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy,
-                                            llvm::DIFile Unit) {
-  if (CGM.getCodeGenOpts().getDebugInfo() != CodeGenOptions::LimitedDebugInfo)
-    return getOrCreateType(PointeeTy, Unit);
-
-  // Limit debug info for the pointee type.
-
-  // If we have an existing type, use that, it's still smaller than creating
-  // a new type.
-  llvm::DIType Ty = getTypeOrNull(PointeeTy);
-  if (Ty.Verify()) return Ty;
-
-  // Handle qualifiers.
-  if (PointeeTy.hasLocalQualifiers())
-    return CreateQualifiedType(PointeeTy, Unit);
-
-  if (const RecordType *RTy = dyn_cast<RecordType>(PointeeTy)) {
-    RecordDecl *RD = RTy->getDecl();
-    llvm::DIDescriptor FDContext =
-      getContextDescriptor(cast<Decl>(RD->getDeclContext()));
-    llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext);
-    TypeCache[QualType(RTy, 0).getAsOpaquePtr()] = RetTy;
-    return RetTy;
-  }
-  return getOrCreateType(PointeeTy, Unit);
-
-}
-
-llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
-                                                const Type *Ty, 
-                                                QualType PointeeTy,
-                                                llvm::DIFile Unit) {
-  if (Tag == llvm::dwarf::DW_TAG_reference_type ||
-      Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
-    return DBuilder.createReferenceType(Tag,
-                                        CreatePointeeType(PointeeTy, Unit));
-                                    
-  // Bit size, align and offset of the type.
-  // Size is always the size of a pointer. We can't use getTypeSize here
-  // because that does not return the correct value for references.
-  unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
-  uint64_t Size = CGM.getContext().getTargetInfo().getPointerWidth(AS);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
-
-  return DBuilder.createPointerType(CreatePointeeType(PointeeTy, Unit),
-                                    Size, Align);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
-                                     llvm::DIFile Unit) {
-  if (BlockLiteralGenericSet)
-    return BlockLiteralGeneric;
-
-  SmallVector<llvm::Value *, 8> EltTys;
-  llvm::DIType FieldTy;
-  QualType FType;
-  uint64_t FieldSize, FieldOffset;
-  unsigned FieldAlign;
-  llvm::DIArray Elements;
-  llvm::DIType EltTy, DescTy;
-
-  FieldOffset = 0;
-  FType = CGM.getContext().UnsignedLongTy;
-  EltTys.push_back(CreateMemberType(Unit, FType, "reserved", &FieldOffset));
-  EltTys.push_back(CreateMemberType(Unit, FType, "Size", &FieldOffset));
-
-  Elements = DBuilder.getOrCreateArray(EltTys);
-  EltTys.clear();
-
-  unsigned Flags = llvm::DIDescriptor::FlagAppleBlock;
-  unsigned LineNo = getLineNumber(CurLoc);
-
-  EltTy = DBuilder.createStructType(Unit, "__block_descriptor",
-                                    Unit, LineNo, FieldOffset, 0,
-                                    Flags, Elements);
-
-  // Bit size, align and offset of the type.
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-
-  DescTy = DBuilder.createPointerType(EltTy, Size);
-
-  FieldOffset = 0;
-  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
-  EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));
-  FType = CGM.getContext().IntTy;
-  EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));
-  EltTys.push_back(CreateMemberType(Unit, FType, "__reserved", &FieldOffset));
-  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
-  EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset));
-
-  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
-  FieldTy = DescTy;
-  FieldSize = CGM.getContext().getTypeSize(Ty);
-  FieldAlign = CGM.getContext().getTypeAlign(Ty);
-  FieldTy = DBuilder.createMemberType(Unit, "__descriptor", Unit,
-                                      LineNo, FieldSize, FieldAlign,
-                                      FieldOffset, 0, FieldTy);
-  EltTys.push_back(FieldTy);
-
-  FieldOffset += FieldSize;
-  Elements = DBuilder.getOrCreateArray(EltTys);
-
-  EltTy = DBuilder.createStructType(Unit, "__block_literal_generic",
-                                    Unit, LineNo, FieldOffset, 0,
-                                    Flags, Elements);
-
-  BlockLiteralGenericSet = true;
-  BlockLiteralGeneric = DBuilder.createPointerType(EltTy, Size);
-  return BlockLiteralGeneric;
-}
-
-llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {
-  // Typedefs are derived from some other type.  If we have a typedef of a
-  // typedef, make sure to emit the whole chain.
-  llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
-  if (!Src.Verify())
-    return llvm::DIType();
-  // We don't set size information, but do specify where the typedef was
-  // declared.
-  unsigned Line = getLineNumber(Ty->getDecl()->getLocation());
-  const TypedefNameDecl *TyDecl = Ty->getDecl();
-  
-  llvm::DIDescriptor TypedefContext =
-    getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext()));
-  
-  return
-    DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
-                                     llvm::DIFile Unit) {
-  SmallVector<llvm::Value *, 16> EltTys;
-
-  // Add the result type at least.
-  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
-
-  // Set up remainder of arguments if there is a prototype.
-  // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
-  if (isa<FunctionNoProtoType>(Ty))
-    EltTys.push_back(DBuilder.createUnspecifiedParameter());
-  else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
-    for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
-      EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
-  }
-
-  llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
-  return DBuilder.createSubroutineType(Unit, EltTypeArray);
-}
-
-
-void CGDebugInfo::
-CollectRecordStaticVars(const RecordDecl *RD, llvm::DIType FwdDecl) {
-  
-  for (RecordDecl::decl_iterator I = RD->decls_begin(), E = RD->decls_end();
-       I != E; ++I)
-    if (const VarDecl *V = dyn_cast<VarDecl>(*I)) {
-      if (V->getInit()) {
-        const APValue *Value = V->evaluateValue();
-        if (Value && Value->isInt()) {
-          llvm::ConstantInt *CI
-            = llvm::ConstantInt::get(CGM.getLLVMContext(), Value->getInt());
-          
-          // Create the descriptor for static variable.
-          llvm::DIFile VUnit = getOrCreateFile(V->getLocation());
-          StringRef VName = V->getName();
-          llvm::DIType VTy = getOrCreateType(V->getType(), VUnit);
-          // Do not use DIGlobalVariable for enums.
-          if (VTy.getTag() != llvm::dwarf::DW_TAG_enumeration_type) {
-            DBuilder.createStaticVariable(FwdDecl, VName, VName, VUnit,
-                                          getLineNumber(V->getLocation()),
-                                          VTy, true, CI);
-          }
-        }
-      }
-    }
-}
-
-llvm::DIType CGDebugInfo::createFieldType(StringRef name,
-                                          QualType type,
-                                          uint64_t sizeInBitsOverride,
-                                          SourceLocation loc,
-                                          AccessSpecifier AS,
-                                          uint64_t offsetInBits,
-                                          llvm::DIFile tunit,
-                                          llvm::DIDescriptor scope) {
-  llvm::DIType debugType = getOrCreateType(type, tunit);
-
-  // Get the location for the field.
-  llvm::DIFile file = getOrCreateFile(loc);
-  unsigned line = getLineNumber(loc);
-
-  uint64_t sizeInBits = 0;
-  unsigned alignInBits = 0;
-  if (!type->isIncompleteArrayType()) {
-    llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
-
-    if (sizeInBitsOverride)
-      sizeInBits = sizeInBitsOverride;
-  }
-
-  unsigned flags = 0;
-  if (AS == clang::AS_private)
-    flags |= llvm::DIDescriptor::FlagPrivate;
-  else if (AS == clang::AS_protected)
-    flags |= llvm::DIDescriptor::FlagProtected;
-
-  return DBuilder.createMemberType(scope, name, file, line, sizeInBits,
-                                   alignInBits, offsetInBits, flags, debugType);
-}
-
-/// CollectRecordFields - A helper function to collect debug info for
-/// record fields. This is used while creating debug info entry for a Record.
-void CGDebugInfo::
-CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,
-                    SmallVectorImpl<llvm::Value *> &elements,
-                    llvm::DIType RecordTy) {
-  unsigned fieldNo = 0;
-  const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
-  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(record);
-
-  // For C++11 Lambdas a Field will be the same as a Capture, but the Capture
-  // has the name and the location of the variable so we should iterate over
-  // both concurrently.
-  if (CXXDecl && CXXDecl->isLambda()) {
-    RecordDecl::field_iterator Field = CXXDecl->field_begin();
-    unsigned fieldno = 0;
-    for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
-           E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) {
-      const LambdaExpr::Capture C = *I;
-      if (C.capturesVariable()) {
-        VarDecl *V = C.getCapturedVar();
-        llvm::DIFile VUnit = getOrCreateFile(C.getLocation());
-        StringRef VName = V->getName();
-        uint64_t SizeInBitsOverride = 0;
-        if (Field->isBitField()) {
-          SizeInBitsOverride = Field->getBitWidthValue(CGM.getContext());
-          assert(SizeInBitsOverride && "found named 0-width bitfield");
-        }
-        llvm::DIType fieldType
-          = createFieldType(VName, Field->getType(), SizeInBitsOverride, C.getLocation(),
-                            Field->getAccess(), layout.getFieldOffset(fieldno),
-                            VUnit, RecordTy);
-        elements.push_back(fieldType);
-      } else {
-        // TODO: Need to handle 'this' in some way by probably renaming the
-        // this of the lambda class and having a field member of 'this' or
-        // by using AT_object_pointer for the function and having that be
-        // used as 'this' for semantic references.
-        assert(C.capturesThis() && "Field that isn't captured and isn't this?");
-        FieldDecl *f = *Field;
-        llvm::DIFile VUnit = getOrCreateFile(f->getLocation());
-        QualType type = f->getType();
-        llvm::DIType fieldType
-          = createFieldType("this", type, 0, f->getLocation(), f->getAccess(),
-                            layout.getFieldOffset(fieldNo), VUnit, RecordTy);
-
-        elements.push_back(fieldType);
-      }
-    }
-  } else {
-    bool IsMsStruct = record->isMsStruct(CGM.getContext());
-    const FieldDecl *LastFD = 0;
-    for (RecordDecl::field_iterator I = record->field_begin(),
-           E = record->field_end();
-         I != E; ++I, ++fieldNo) {
-      FieldDecl *field = *I;
-
-      if (IsMsStruct) {
-        // Zero-length bitfields following non-bitfield members are ignored
-        if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) {
-          --fieldNo;
-          continue;
-        }
-        LastFD = field;
-      }
-
-      StringRef name = field->getName();
-      QualType type = field->getType();
-
-      // Ignore unnamed fields unless they're anonymous structs/unions.
-      if (name.empty() && !type->isRecordType()) {
-        LastFD = field;
-        continue;
-      }
-
-      uint64_t SizeInBitsOverride = 0;
-      if (field->isBitField()) {
-        SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
-        assert(SizeInBitsOverride && "found named 0-width bitfield");
-      }
-
-      llvm::DIType fieldType
-        = createFieldType(name, type, SizeInBitsOverride,
-                          field->getLocation(), field->getAccess(),
-                          layout.getFieldOffset(fieldNo), tunit, RecordTy);
-
-      elements.push_back(fieldType);
-    }
-  }
-}
-
-/// getOrCreateMethodType - CXXMethodDecl's type is a FunctionType. This
-/// function type is not updated to include implicit "this" pointer. Use this
-/// routine to get a method type which includes "this" pointer.
-llvm::DIType
-CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
-                                   llvm::DIFile Unit) {
-  llvm::DIType FnTy
-    = getOrCreateType(QualType(Method->getType()->getAs<FunctionProtoType>(),
-                               0),
-                      Unit);
-
-  // Add "this" pointer.
-  llvm::DIArray Args = llvm::DICompositeType(FnTy).getTypeArray();
-  assert (Args.getNumElements() && "Invalid number of arguments!");
-
-  SmallVector<llvm::Value *, 16> Elts;
-
-  // First element is always return type. For 'void' functions it is NULL.
-  Elts.push_back(Args.getElement(0));
-
-  if (!Method->isStatic()) {
-    // "this" pointer is always first argument.
-    QualType ThisPtr = Method->getThisType(CGM.getContext());
-
-    const CXXRecordDecl *RD = Method->getParent();
-    if (isa<ClassTemplateSpecializationDecl>(RD)) {
-      // Create pointer type directly in this case.
-      const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
-      QualType PointeeTy = ThisPtrTy->getPointeeType();
-      unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
-      uint64_t Size = CGM.getContext().getTargetInfo().getPointerWidth(AS);
-      uint64_t Align = CGM.getContext().getTypeAlign(ThisPtrTy);
-      llvm::DIType PointeeType = getOrCreateType(PointeeTy, Unit);
-      llvm::DIType ThisPtrType = DBuilder.createPointerType(PointeeType, Size, Align);
-      TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;
-      // TODO: This and the artificial type below are misleading, the
-      // types aren't artificial the argument is, but the current
-      // metadata doesn't represent that.
-      ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
-      Elts.push_back(ThisPtrType);
-    } else {
-      llvm::DIType ThisPtrType = getOrCreateType(ThisPtr, Unit);
-      TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;
-      ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
-      Elts.push_back(ThisPtrType);
-    }
-  }
-
-  // Copy rest of the arguments.
-  for (unsigned i = 1, e = Args.getNumElements(); i != e; ++i)
-    Elts.push_back(Args.getElement(i));
-
-  llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
-
-  return DBuilder.createSubroutineType(Unit, EltTypeArray);
-}
-
-/// isFunctionLocalClass - Return true if CXXRecordDecl is defined 
-/// inside a function.
-static bool isFunctionLocalClass(const CXXRecordDecl *RD) {
-  if (const CXXRecordDecl *NRD = dyn_cast<CXXRecordDecl>(RD->getDeclContext()))
-    return isFunctionLocalClass(NRD);
-  if (isa<FunctionDecl>(RD->getDeclContext()))
-    return true;
-  return false;
-}
-
-/// CreateCXXMemberFunction - A helper function to create a DISubprogram for
-/// a single member function GlobalDecl.
-llvm::DISubprogram
-CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
-                                     llvm::DIFile Unit,
-                                     llvm::DIType RecordTy) {
-  bool IsCtorOrDtor = 
-    isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
-  
-  StringRef MethodName = getFunctionName(Method);
-  llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);
-
-  // Since a single ctor/dtor corresponds to multiple functions, it doesn't
-  // make sense to give a single ctor/dtor a linkage name.
-  StringRef MethodLinkageName;
-  if (!IsCtorOrDtor && !isFunctionLocalClass(Method->getParent()))
-    MethodLinkageName = CGM.getMangledName(Method);
-
-  // Get the location for the method.
-  llvm::DIFile MethodDefUnit = getOrCreateFile(Method->getLocation());
-  unsigned MethodLine = getLineNumber(Method->getLocation());
-
-  // Collect virtual method info.
-  llvm::DIType ContainingType;
-  unsigned Virtuality = 0; 
-  unsigned VIndex = 0;
-  
-  if (Method->isVirtual()) {
-    if (Method->isPure())
-      Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;
-    else
-      Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual;
-    
-    // It doesn't make sense to give a virtual destructor a vtable index,
-    // since a single destructor has two entries in the vtable.
-    if (!isa<CXXDestructorDecl>(Method))
-      VIndex = CGM.getVTableContext().getMethodVTableIndex(Method);
-    ContainingType = RecordTy;
-  }
-
-  unsigned Flags = 0;
-  if (Method->isImplicit())
-    Flags |= llvm::DIDescriptor::FlagArtificial;
-  AccessSpecifier Access = Method->getAccess();
-  if (Access == clang::AS_private)
-    Flags |= llvm::DIDescriptor::FlagPrivate;
-  else if (Access == clang::AS_protected)
-    Flags |= llvm::DIDescriptor::FlagProtected;
-  if (const CXXConstructorDecl *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
-    if (CXXC->isExplicit())
-      Flags |= llvm::DIDescriptor::FlagExplicit;
-  } else if (const CXXConversionDecl *CXXC = 
-             dyn_cast<CXXConversionDecl>(Method)) {
-    if (CXXC->isExplicit())
-      Flags |= llvm::DIDescriptor::FlagExplicit;
-  }
-  if (Method->hasPrototype())
-    Flags |= llvm::DIDescriptor::FlagPrototyped;
-
-  llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
-  llvm::DISubprogram SP =
-    DBuilder.createMethod(RecordTy, MethodName, MethodLinkageName, 
-                          MethodDefUnit, MethodLine,
-                          MethodTy, /*isLocalToUnit=*/false, 
-                          /* isDefinition=*/ false,
-                          Virtuality, VIndex, ContainingType,
-                          Flags, CGM.getLangOpts().Optimize, NULL,
-                          TParamsArray);
-  
-  SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP);
-
-  return SP;
-}
-
-/// CollectCXXMemberFunctions - A helper function to collect debug info for
-/// C++ member functions. This is used while creating debug info entry for 
-/// a Record.
-void CGDebugInfo::
-CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
-                          SmallVectorImpl<llvm::Value *> &EltTys,
-                          llvm::DIType RecordTy) {
-
-  // Since we want more than just the individual member decls if we
-  // have templated functions iterate over every declaration to gather
-  // the functions.
-  for(DeclContext::decl_iterator I = RD->decls_begin(),
-        E = RD->decls_end(); I != E; ++I) {
-    Decl *D = *I;
-    if (D->isImplicit() && !D->isUsed())
-      continue;
-
-    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
-      EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
-    else if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
-      for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(),
-             SE = FTD->spec_end(); SI != SE; ++SI)
-        EltTys.push_back(CreateCXXMemberFunction(cast<CXXMethodDecl>(*SI), Unit,
-                                                 RecordTy));
-  }
-}                                 
-
-/// CollectCXXFriends - A helper function to collect debug info for
-/// C++ base classes. This is used while creating debug info entry for
-/// a Record.
-void CGDebugInfo::
-CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit,
-                SmallVectorImpl<llvm::Value *> &EltTys,
-                llvm::DIType RecordTy) {
-  for (CXXRecordDecl::friend_iterator BI = RD->friend_begin(),
-         BE = RD->friend_end(); BI != BE; ++BI) {
-    if ((*BI)->isUnsupportedFriend())
-      continue;
-    if (TypeSourceInfo *TInfo = (*BI)->getFriendType())
-      EltTys.push_back(DBuilder.createFriend(RecordTy, 
-                                             getOrCreateType(TInfo->getType(), 
-                                                             Unit)));
-  }
-}
-
-/// CollectCXXBases - A helper function to collect debug info for
-/// C++ base classes. This is used while creating debug info entry for 
-/// a Record.
-void CGDebugInfo::
-CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,
-                SmallVectorImpl<llvm::Value *> &EltTys,
-                llvm::DIType RecordTy) {
-
-  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-  for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
-         BE = RD->bases_end(); BI != BE; ++BI) {
-    unsigned BFlags = 0;
-    uint64_t BaseOffset;
-    
-    const CXXRecordDecl *Base =
-      cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl());
-    
-    if (BI->isVirtual()) {
-      // virtual base offset offset is -ve. The code generator emits dwarf
-      // expression where it expects +ve number.
-      BaseOffset = 
-        0 - CGM.getVTableContext()
-               .getVirtualBaseOffsetOffset(RD, Base).getQuantity();
-      BFlags = llvm::DIDescriptor::FlagVirtual;
-    } else
-      BaseOffset = CGM.getContext().toBits(RL.getBaseClassOffset(Base));
-    // FIXME: Inconsistent units for BaseOffset. It is in bytes when
-    // BI->isVirtual() and bits when not.
-    
-    AccessSpecifier Access = BI->getAccessSpecifier();
-    if (Access == clang::AS_private)
-      BFlags |= llvm::DIDescriptor::FlagPrivate;
-    else if (Access == clang::AS_protected)
-      BFlags |= llvm::DIDescriptor::FlagProtected;
-    
-    llvm::DIType DTy = 
-      DBuilder.createInheritance(RecordTy,                                     
-                                 getOrCreateType(BI->getType(), Unit),
-                                 BaseOffset, BFlags);
-    EltTys.push_back(DTy);
-  }
-}
-
-/// CollectTemplateParams - A helper function to collect template parameters.
-llvm::DIArray CGDebugInfo::
-CollectTemplateParams(const TemplateParameterList *TPList,
-                      const TemplateArgumentList &TAList,
-                      llvm::DIFile Unit) {
-  SmallVector<llvm::Value *, 16> TemplateParams;  
-  for (unsigned i = 0, e = TAList.size(); i != e; ++i) {
-    const TemplateArgument &TA = TAList[i];
-    const NamedDecl *ND = TPList->getParam(i);
-    if (TA.getKind() == TemplateArgument::Type) {
-      llvm::DIType TTy = getOrCreateType(TA.getAsType(), Unit);
-      llvm::DITemplateTypeParameter TTP =
-        DBuilder.createTemplateTypeParameter(TheCU, ND->getName(), TTy);
-      TemplateParams.push_back(TTP);
-    } else if (TA.getKind() == TemplateArgument::Integral) {
-      llvm::DIType TTy = getOrCreateType(TA.getIntegralType(), Unit);
-      llvm::DITemplateValueParameter TVP =
-        DBuilder.createTemplateValueParameter(TheCU, ND->getName(), TTy,
-                                             TA.getAsIntegral().getZExtValue());
-      TemplateParams.push_back(TVP);          
-    }
-  }
-  return DBuilder.getOrCreateArray(TemplateParams);
-}
-
-/// CollectFunctionTemplateParams - A helper function to collect debug
-/// info for function template parameters.
-llvm::DIArray CGDebugInfo::
-CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit) {
-  if (FD->getTemplatedKind() ==
-      FunctionDecl::TK_FunctionTemplateSpecialization) {
-    const TemplateParameterList *TList =
-      FD->getTemplateSpecializationInfo()->getTemplate()
-      ->getTemplateParameters();
-    return 
-      CollectTemplateParams(TList, *FD->getTemplateSpecializationArgs(), Unit);
-  }
-  return llvm::DIArray();
-}
-
-/// CollectCXXTemplateParams - A helper function to collect debug info for
-/// template parameters.
-llvm::DIArray CGDebugInfo::
-CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,
-                         llvm::DIFile Unit) {
-  llvm::PointerUnion<ClassTemplateDecl *,
-                     ClassTemplatePartialSpecializationDecl *>
-    PU = TSpecial->getSpecializedTemplateOrPartial();
-  
-  TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?
-    PU.get<ClassTemplateDecl *>()->getTemplateParameters() :
-    PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();
-  const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();
-  return CollectTemplateParams(TPList, TAList, Unit);
-}
-
-/// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
-llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) {
-  if (VTablePtrType.isValid())
-    return VTablePtrType;
-
-  ASTContext &Context = CGM.getContext();
-
-  /* Function type */
-  llvm::Value *STy = getOrCreateType(Context.IntTy, Unit);
-  llvm::DIArray SElements = DBuilder.getOrCreateArray(STy);
-  llvm::DIType SubTy = DBuilder.createSubroutineType(Unit, SElements);
-  unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
-  llvm::DIType vtbl_ptr_type = DBuilder.createPointerType(SubTy, Size, 0,
-                                                          "__vtbl_ptr_type");
-  VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
-  return VTablePtrType;
-}
-
-/// getVTableName - Get vtable name for the given Class.
-StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {
-  // Construct gdb compatible name name.
-  std::string Name = "_vptr$" + RD->getNameAsString();
-
-  // Copy this name on the side and use its reference.
-  char *StrPtr = DebugInfoNames.Allocate<char>(Name.length());
-  memcpy(StrPtr, Name.data(), Name.length());
-  return StringRef(StrPtr, Name.length());
-}
-
-
-/// CollectVTableInfo - If the C++ class has vtable info then insert appropriate
-/// debug info entry in EltTys vector.
-void CGDebugInfo::
-CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit,
-                  SmallVectorImpl<llvm::Value *> &EltTys) {
-  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-
-  // If there is a primary base then it will hold vtable info.
-  if (RL.getPrimaryBase())
-    return;
-
-  // If this class is not dynamic then there is not any vtable info to collect.
-  if (!RD->isDynamicClass())
-    return;
-
-  unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
-  llvm::DIType VPTR
-    = DBuilder.createMemberType(Unit, getVTableName(RD), Unit,
-                                0, Size, 0, 0, llvm::DIDescriptor::FlagArtificial,
-                                getOrCreateVTablePtrType(Unit));
-  EltTys.push_back(VPTR);
-}
-
-/// getOrCreateRecordType - Emit record type's standalone debug info. 
-llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy, 
-                                                SourceLocation Loc) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  llvm::DIType T = getOrCreateType(RTy, getOrCreateFile(Loc));
-  return T;
-}
-
-/// getOrCreateInterfaceType - Emit an objective c interface type standalone
-/// debug info.
-llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D,
-						   SourceLocation Loc) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  llvm::DIType T = getOrCreateType(D, getOrCreateFile(Loc));
-  DBuilder.retainType(T);
-  return T;
-}
-
-/// CreateType - get structure or union type.
-llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
-  RecordDecl *RD = Ty->getDecl();
-
-  // Get overall information about the record type for the debug info.
-  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
-
-  // Records and classes and unions can all be recursive.  To handle them, we
-  // first generate a debug descriptor for the struct as a forward declaration.
-  // Then (if it is a definition) we go through and get debug info for all of
-  // its members.  Finally, we create a descriptor for the complete type (which
-  // may refer to the forward decl if the struct is recursive) and replace all
-  // uses of the forward declaration with the final definition.
-
-  llvm::DIType FwdDecl = getOrCreateLimitedType(QualType(Ty, 0), DefUnit);
-
-  if (FwdDecl.isForwardDecl())
-    return FwdDecl;
-
-  llvm::TrackingVH<llvm::MDNode> FwdDeclNode(FwdDecl);
-
-  // Push the struct on region stack.
-  LexicalBlockStack.push_back(FwdDeclNode);
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
-
-  // Add this to the completed types cache since we're completing it.
-  CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
-
-  // Convert all the elements.
-  SmallVector<llvm::Value *, 16> EltTys;
-
-  // Note: The split of CXXDecl information here is intentional, the
-  // gdb tests will depend on a certain ordering at printout. The debug
-  // information offsets are still correct if we merge them all together
-  // though.
-  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
-  if (CXXDecl) {
-    CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
-    CollectVTableInfo(CXXDecl, DefUnit, EltTys);
-  }
-
-  // Collect static variables with initializers and other fields.
-  CollectRecordStaticVars(RD, FwdDecl);
-  CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
-  llvm::DIArray TParamsArray;
-  if (CXXDecl) {
-    CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
-    CollectCXXFriends(CXXDecl, DefUnit, EltTys, FwdDecl);
-    if (const ClassTemplateSpecializationDecl *TSpecial
-        = dyn_cast<ClassTemplateSpecializationDecl>(RD))
-      TParamsArray = CollectCXXTemplateParams(TSpecial, DefUnit);
-  }
-
-  LexicalBlockStack.pop_back();
-  RegionMap.erase(Ty->getDecl());
-
-  llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-  // FIXME: Magic numbers ahoy! These should be changed when we
-  // get some enums in llvm/Analysis/DebugInfo.h to refer to
-  // them.
-  if (RD->isUnion())
-    FwdDeclNode->replaceOperandWith(10, Elements);
-  else if (CXXDecl) {
-    FwdDeclNode->replaceOperandWith(10, Elements);
-    FwdDeclNode->replaceOperandWith(13, TParamsArray);
-  } else
-    FwdDeclNode->replaceOperandWith(10, Elements);
-
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDeclNode);
-  return llvm::DIType(FwdDeclNode);
-}
-
-/// CreateType - get objective-c object type.
-llvm::DIType CGDebugInfo::CreateType(const ObjCObjectType *Ty,
-                                     llvm::DIFile Unit) {
-  // Ignore protocols.
-  return getOrCreateType(Ty->getBaseType(), Unit);
-}
-
-/// CreateType - get objective-c interface type.
-llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
-                                     llvm::DIFile Unit) {
-  ObjCInterfaceDecl *ID = Ty->getDecl();
-  if (!ID)
-    return llvm::DIType();
-
-  // Get overall information about the record type for the debug info.
-  llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
-  unsigned Line = getLineNumber(ID->getLocation());
-  unsigned RuntimeLang = TheCU.getLanguage();
-
-  // If this is just a forward declaration return a special forward-declaration
-  // debug type since we won't be able to lay out the entire type.
-  ObjCInterfaceDecl *Def = ID->getDefinition();
-  if (!Def) {
-    llvm::DIType FwdDecl =
-      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-				 ID->getName(), TheCU, DefUnit, Line,
-				 RuntimeLang);
-    return FwdDecl;
-  }
-
-  ID = Def;
-
-  // Bit size, align and offset of the type.
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
-
-  unsigned Flags = 0;
-  if (ID->getImplementation())
-    Flags |= llvm::DIDescriptor::FlagObjcClassComplete;
-
-  llvm::DIType RealDecl =
-    DBuilder.createStructType(Unit, ID->getName(), DefUnit,
-                              Line, Size, Align, Flags,
-                              llvm::DIArray(), RuntimeLang);
-
-  // Otherwise, insert it into the CompletedTypeCache so that recursive uses
-  // will find it and we're emitting the complete type.
-  CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;
-  // Push the struct on region stack.
-  llvm::TrackingVH<llvm::MDNode> FwdDeclNode(RealDecl);
-
-  LexicalBlockStack.push_back(FwdDeclNode);
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
-
-  // Convert all the elements.
-  SmallVector<llvm::Value *, 16> EltTys;
-
-  ObjCInterfaceDecl *SClass = ID->getSuperClass();
-  if (SClass) {
-    llvm::DIType SClassTy =
-      getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
-    if (!SClassTy.isValid())
-      return llvm::DIType();
-    
-    llvm::DIType InhTag =
-      DBuilder.createInheritance(RealDecl, SClassTy, 0, 0);
-    EltTys.push_back(InhTag);
-  }
-
-  for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(),
-         E = ID->prop_end(); I != E; ++I) {
-    const ObjCPropertyDecl *PD = *I;
-    SourceLocation Loc = PD->getLocation();
-    llvm::DIFile PUnit = getOrCreateFile(Loc);
-    unsigned PLine = getLineNumber(Loc);
-    ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
-    ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
-    llvm::MDNode *PropertyNode =
-      DBuilder.createObjCProperty(PD->getName(),
-				  PUnit, PLine,
-                                  (Getter && Getter->isImplicit()) ? "" :
-                                  getSelectorName(PD->getGetterName()),
-                                  (Setter && Setter->isImplicit()) ? "" :
-                                  getSelectorName(PD->getSetterName()),
-                                  PD->getPropertyAttributes(),
-				  getOrCreateType(PD->getType(), PUnit));
-    EltTys.push_back(PropertyNode);
-  }
-
-  const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
-  unsigned FieldNo = 0;
-  for (ObjCIvarDecl *Field = ID->all_declared_ivar_begin(); Field;
-       Field = Field->getNextIvar(), ++FieldNo) {
-    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
-    if (!FieldTy.isValid())
-      return llvm::DIType();
-    
-    StringRef FieldName = Field->getName();
-
-    // Ignore unnamed fields.
-    if (FieldName.empty())
-      continue;
-
-    // Get the location for the field.
-    llvm::DIFile FieldDefUnit = getOrCreateFile(Field->getLocation());
-    unsigned FieldLine = getLineNumber(Field->getLocation());
-    QualType FType = Field->getType();
-    uint64_t FieldSize = 0;
-    unsigned FieldAlign = 0;
-
-    if (!FType->isIncompleteArrayType()) {
-
-      // Bit size, align and offset of the type.
-      FieldSize = Field->isBitField()
-        ? Field->getBitWidthValue(CGM.getContext())
-        : CGM.getContext().getTypeSize(FType);
-      FieldAlign = CGM.getContext().getTypeAlign(FType);
-    }
-
-    uint64_t FieldOffset;
-    if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
-      // We don't know the runtime offset of an ivar if we're using the
-      // non-fragile ABI.  For bitfields, use the bit offset into the first
-      // byte of storage of the bitfield.  For other fields, use zero.
-      if (Field->isBitField()) {
-        FieldOffset = CGM.getObjCRuntime().ComputeBitfieldBitOffset(
-            CGM, ID, Field);
-        FieldOffset %= CGM.getContext().getCharWidth();
-      } else {
-        FieldOffset = 0;
-      }
-    } else {
-      FieldOffset = RL.getFieldOffset(FieldNo);
-    }
-
-    unsigned Flags = 0;
-    if (Field->getAccessControl() == ObjCIvarDecl::Protected)
-      Flags = llvm::DIDescriptor::FlagProtected;
-    else if (Field->getAccessControl() == ObjCIvarDecl::Private)
-      Flags = llvm::DIDescriptor::FlagPrivate;
-
-    llvm::MDNode *PropertyNode = NULL;
-    if (ObjCImplementationDecl *ImpD = ID->getImplementation()) {
-      if (ObjCPropertyImplDecl *PImpD = 
-          ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
-        if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
-	  SourceLocation Loc = PD->getLocation();
-	  llvm::DIFile PUnit = getOrCreateFile(Loc);
-	  unsigned PLine = getLineNumber(Loc);
-          ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
-          ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
-          PropertyNode =
-            DBuilder.createObjCProperty(PD->getName(),
-                                        PUnit, PLine,
-                                        (Getter && Getter->isImplicit()) ? "" :
-                                        getSelectorName(PD->getGetterName()),
-                                        (Setter && Setter->isImplicit()) ? "" :
-                                        getSelectorName(PD->getSetterName()),
-                                        PD->getPropertyAttributes(),
-                                        getOrCreateType(PD->getType(), PUnit));
-        }
-      }
-    }
-    FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit,
-                                      FieldLine, FieldSize, FieldAlign,
-                                      FieldOffset, Flags, FieldTy,
-                                      PropertyNode);
-    EltTys.push_back(FieldTy);
-  }
-
-  llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-  FwdDeclNode->replaceOperandWith(10, Elements);
-  
-  LexicalBlockStack.pop_back();
-  return llvm::DIType(FwdDeclNode);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) {
-  llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);
-  int64_t Count = Ty->getNumElements();
-  if (Count == 0)
-    // If number of elements are not known then this is an unbounded array.
-    // Use Count == -1 to express such arrays.
-    Count = -1;
-
-  llvm::Value *Subscript = DBuilder.getOrCreateSubrange(0, Count);
-  llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
-
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
-
-  return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
-                                     llvm::DIFile Unit) {
-  uint64_t Size;
-  uint64_t Align;
-
-  // FIXME: make getTypeAlign() aware of VLAs and incomplete array types
-  if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) {
-    Size = 0;
-    Align =
-      CGM.getContext().getTypeAlign(CGM.getContext().getBaseElementType(VAT));
-  } else if (Ty->isIncompleteArrayType()) {
-    Size = 0;
-    if (Ty->getElementType()->isIncompleteType())
-      Align = 0;
-    else
-      Align = CGM.getContext().getTypeAlign(Ty->getElementType());
-  } else if (Ty->isDependentSizedArrayType() || Ty->isIncompleteType()) {
-    Size = 0;
-    Align = 0;
-  } else {
-    // Size and align of the whole array, not the element type.
-    Size = CGM.getContext().getTypeSize(Ty);
-    Align = CGM.getContext().getTypeAlign(Ty);
-  }
-
-  // Add the dimensions of the array.  FIXME: This loses CV qualifiers from
-  // interior arrays, do we care?  Why aren't nested arrays represented the
-  // obvious/recursive way?
-  SmallVector<llvm::Value *, 8> Subscripts;
-  QualType EltTy(Ty, 0);
-  while ((Ty = dyn_cast<ArrayType>(EltTy))) {
-    // If the number of elements is known, then count is that number. Otherwise,
-    // it's -1. This allows us to represent a subrange with an array of 0
-    // elements, like this:
-    //
-    //   struct foo {
-    //     int x[0];
-    //   };
-    int64_t Count = -1;         // Count == -1 is an unbounded array.
-    if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
-      Count = CAT->getSize().getZExtValue();
-    
-    // FIXME: Verify this is right for VLAs.
-    Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
-    EltTy = Ty->getElementType();
-  }
-
-  llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);
-
-  llvm::DIType DbgTy = 
-    DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),
-                             SubscriptArray);
-  return DbgTy;
-}
-
-llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty, 
-                                     llvm::DIFile Unit) {
-  return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, 
-                               Ty, Ty->getPointeeType(), Unit);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const RValueReferenceType *Ty, 
-                                     llvm::DIFile Unit) {
-  return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type, 
-                               Ty, Ty->getPointeeType(), Unit);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, 
-                                     llvm::DIFile U) {
-  QualType PointerDiffTy = CGM.getContext().getPointerDiffType();
-  llvm::DIType PointerDiffDITy = getOrCreateType(PointerDiffTy, U);
-  
-  if (!Ty->getPointeeType()->isFunctionType()) {
-    // We have a data member pointer type.
-    return PointerDiffDITy;
-  }
-  
-  // We have a member function pointer type. Treat it as a struct with two
-  // ptrdiff_t members.
-  std::pair<uint64_t, unsigned> Info = CGM.getContext().getTypeInfo(Ty);
-
-  uint64_t FieldOffset = 0;
-  llvm::Value *ElementTypes[2];
-  
-  // FIXME: This should be a DW_TAG_pointer_to_member type.
-  ElementTypes[0] =
-    DBuilder.createMemberType(U, "ptr", U, 0,
-                              Info.first, Info.second, FieldOffset, 0,
-                              PointerDiffDITy);
-  FieldOffset += Info.first;
-  
-  ElementTypes[1] =
-    DBuilder.createMemberType(U, "ptr", U, 0,
-                              Info.first, Info.second, FieldOffset, 0,
-                              PointerDiffDITy);
-  
-  llvm::DIArray Elements = DBuilder.getOrCreateArray(ElementTypes);
-
-  return DBuilder.createStructType(U, StringRef("test"), 
-                                   U, 0, FieldOffset, 
-                                   0, 0, Elements);
-}
-
-llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty, 
-                                     llvm::DIFile U) {
-  // Ignore the atomic wrapping
-  // FIXME: What is the correct representation?
-  return getOrCreateType(Ty->getValueType(), U);
-}
-
-/// CreateEnumType - get enumeration type.
-llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {
-  uint64_t Size = 0;
-  uint64_t Align = 0;
-  if (!ED->getTypeForDecl()->isIncompleteType()) {
-    Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
-    Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());
-  }
-
-  // If this is just a forward declaration, construct an appropriately
-  // marked node and just return it.
-  if (!ED->getDefinition()) {
-    llvm::DIDescriptor EDContext;
-    EDContext = getContextDescriptor(cast<Decl>(ED->getDeclContext()));
-    llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());
-    unsigned Line = getLineNumber(ED->getLocation());
-    StringRef EDName = ED->getName();
-    return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type,
-                                      EDName, EDContext, DefUnit, Line, 0,
-                                      Size, Align);
-  }
-
-  // Create DIEnumerator elements for each enumerator.
-  SmallVector<llvm::Value *, 16> Enumerators;
-  ED = ED->getDefinition();
-  for (EnumDecl::enumerator_iterator
-         Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end();
-       Enum != EnumEnd; ++Enum) {
-    Enumerators.push_back(
-      DBuilder.createEnumerator(Enum->getName(),
-                                Enum->getInitVal().getZExtValue()));
-  }
-
-  // Return a CompositeType for the enum itself.
-  llvm::DIArray EltArray = DBuilder.getOrCreateArray(Enumerators);
-
-  llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());
-  unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIDescriptor EnumContext = 
-    getContextDescriptor(cast<Decl>(ED->getDeclContext()));
-  llvm::DIType ClassTy = ED->isScopedUsingClassTag() ?
-    getOrCreateType(ED->getIntegerType(), DefUnit) : llvm::DIType();
-  llvm::DIType DbgTy = 
-    DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, Line,
-                                   Size, Align, EltArray,
-                                   ClassTy);
-  return DbgTy;
-}
-
-static QualType UnwrapTypeForDebugInfo(QualType T) {
-  do {
-    QualType LastT = T;
-    switch (T->getTypeClass()) {
-    default:
-      return T;
-    case Type::TemplateSpecialization:
-      T = cast<TemplateSpecializationType>(T)->desugar();
-      break;
-    case Type::TypeOfExpr:
-      T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
-      break;
-    case Type::TypeOf:
-      T = cast<TypeOfType>(T)->getUnderlyingType();
-      break;
-    case Type::Decltype:
-      T = cast<DecltypeType>(T)->getUnderlyingType();
-      break;
-    case Type::UnaryTransform:
-      T = cast<UnaryTransformType>(T)->getUnderlyingType();
-      break;
-    case Type::Attributed:
-      T = cast<AttributedType>(T)->getEquivalentType();
-      break;
-    case Type::Elaborated:
-      T = cast<ElaboratedType>(T)->getNamedType();
-      break;
-    case Type::Paren:
-      T = cast<ParenType>(T)->getInnerType();
-      break;
-    case Type::SubstTemplateTypeParm: {
-      // We need to keep the qualifiers handy since getReplacementType()
-      // will strip them away.
-      unsigned Quals = T.getLocalFastQualifiers();
-      T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
-      T.addFastQualifiers(Quals);
-    }
-      break;
-    case Type::Auto:
-      T = cast<AutoType>(T)->getDeducedType();
-      break;
-    }
-    
-    assert(T != LastT && "Type unwrapping failed to unwrap!");
-    if (T == LastT)
-      return T;
-  } while (true);
-}
-
-/// getType - Get the type from the cache or return null type if it doesn't exist.
-llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {
-
-  // Unwrap the type as needed for debug information.
-  Ty = UnwrapTypeForDebugInfo(Ty);
-  
-  // Check for existing entry.
-  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-    TypeCache.find(Ty.getAsOpaquePtr());
-  if (it != TypeCache.end()) {
-    // Verify that the debug info still exists.
-    if (llvm::Value *V = it->second)
-      return llvm::DIType(cast<llvm::MDNode>(V));
-  }
-
-  return llvm::DIType();
-}
-
-/// getCompletedTypeOrNull - Get the type from the cache or return null if it
-/// doesn't exist.
-llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
-
-  // Unwrap the type as needed for debug information.
-  Ty = UnwrapTypeForDebugInfo(Ty);
-
-  // Check for existing entry.
-  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-    CompletedTypeCache.find(Ty.getAsOpaquePtr());
-  if (it != CompletedTypeCache.end()) {
-    // Verify that the debug info still exists.
-    if (llvm::Value *V = it->second)
-      return llvm::DIType(cast<llvm::MDNode>(V));
-  }
-
-  return llvm::DIType();
-}
-
-
-/// getOrCreateType - Get the type from the cache or create a new
-/// one if necessary.
-llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
-  if (Ty.isNull())
-    return llvm::DIType();
-
-  // Unwrap the type as needed for debug information.
-  Ty = UnwrapTypeForDebugInfo(Ty);
-
-  llvm::DIType T = getCompletedTypeOrNull(Ty);
-
-  if (T.Verify())
-    return T;
-
-  // Otherwise create the type.
-  llvm::DIType Res = CreateTypeNode(Ty, Unit);
-
-  llvm::DIType TC = getTypeOrNull(Ty);
-  if (TC.Verify() && TC.isForwardDecl())
-    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(),
-                                        static_cast<llvm::Value*>(TC)));
-  
-  // And update the type cache.
-  TypeCache[Ty.getAsOpaquePtr()] = Res;
-
-  if (!Res.isForwardDecl())
-    CompletedTypeCache[Ty.getAsOpaquePtr()] = Res;
-
-  return Res;
-}
-
-/// CreateTypeNode - Create a new debug type node.
-llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
-  // Handle qualifiers, which recursively handles what they refer to.
-  if (Ty.hasLocalQualifiers())
-    return CreateQualifiedType(Ty, Unit);
-
-  const char *Diag = 0;
-  
-  // Work out details of type.
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base)
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Dependent types cannot show up in debug information");
-
-  case Type::ExtVector:
-  case Type::Vector:
-    return CreateType(cast<VectorType>(Ty), Unit);
-  case Type::ObjCObjectPointer:
-    return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
-  case Type::ObjCObject:
-    return CreateType(cast<ObjCObjectType>(Ty), Unit);
-  case Type::ObjCInterface:
-    return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
-  case Type::Builtin:
-    return CreateType(cast<BuiltinType>(Ty));
-  case Type::Complex:
-    return CreateType(cast<ComplexType>(Ty));
-  case Type::Pointer:
-    return CreateType(cast<PointerType>(Ty), Unit);
-  case Type::BlockPointer:
-    return CreateType(cast<BlockPointerType>(Ty), Unit);
-  case Type::Typedef:
-    return CreateType(cast<TypedefType>(Ty), Unit);
-  case Type::Record:
-    return CreateType(cast<RecordType>(Ty));
-  case Type::Enum:
-    return CreateEnumType(cast<EnumType>(Ty)->getDecl());
-  case Type::FunctionProto:
-  case Type::FunctionNoProto:
-    return CreateType(cast<FunctionType>(Ty), Unit);
-  case Type::ConstantArray:
-  case Type::VariableArray:
-  case Type::IncompleteArray:
-    return CreateType(cast<ArrayType>(Ty), Unit);
-
-  case Type::LValueReference:
-    return CreateType(cast<LValueReferenceType>(Ty), Unit);
-  case Type::RValueReference:
-    return CreateType(cast<RValueReferenceType>(Ty), Unit);
-
-  case Type::MemberPointer:
-    return CreateType(cast<MemberPointerType>(Ty), Unit);
-
-  case Type::Atomic:
-    return CreateType(cast<AtomicType>(Ty), Unit);
-
-  case Type::Attributed:
-  case Type::TemplateSpecialization:
-  case Type::Elaborated:
-  case Type::Paren:
-  case Type::SubstTemplateTypeParm:
-  case Type::TypeOfExpr:
-  case Type::TypeOf:
-  case Type::Decltype:
-  case Type::UnaryTransform:
-  case Type::Auto:
-    llvm_unreachable("type should have been unwrapped!");
-  }
-  
-  assert(Diag && "Fall through without a diagnostic?");
-  unsigned DiagID = CGM.getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-                               "debug information for %0 is not yet supported");
-  CGM.getDiags().Report(DiagID)
-    << Diag;
-  return llvm::DIType();
-}
-
-/// getOrCreateLimitedType - Get the type from the cache or create a new
-/// limited type if necessary.
-llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty,
-						 llvm::DIFile Unit) {
-  if (Ty.isNull())
-    return llvm::DIType();
-
-  // Unwrap the type as needed for debug information.
-  Ty = UnwrapTypeForDebugInfo(Ty);
-
-  llvm::DIType T = getTypeOrNull(Ty);
-
-  // We may have cached a forward decl when we could have created
-  // a non-forward decl. Go ahead and create a non-forward decl
-  // now.
-  if (T.Verify() && !T.isForwardDecl()) return T;
-
-  // Otherwise create the type.
-  llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);
-
-  if (T.Verify() && T.isForwardDecl())
-    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(),
-                                        static_cast<llvm::Value*>(T)));
-
-  // And update the type cache.
-  TypeCache[Ty.getAsOpaquePtr()] = Res;
-  return Res;
-}
-
-// TODO: Currently used for context chains when limiting debug info.
-llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
-  RecordDecl *RD = Ty->getDecl();
-  
-  // Get overall information about the record type for the debug info.
-  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
-  unsigned Line = getLineNumber(RD->getLocation());
-  StringRef RDName = getClassName(RD);
-
-  llvm::DIDescriptor RDContext;
-  if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo)
-    RDContext = createContextChain(cast<Decl>(RD->getDeclContext()));
-  else
-    RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));
-
-  // If this is just a forward declaration, construct an appropriately
-  // marked node and just return it.
-  if (!RD->getDefinition())
-    return createRecordFwdDecl(RD, RDContext);
-
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
-  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
-  llvm::TrackingVH<llvm::MDNode> RealDecl;
-  
-  if (RD->isUnion())
-    RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line,
-					Size, Align, 0, llvm::DIArray());
-  else if (RD->isClass()) {
-    // FIXME: This could be a struct type giving a default visibility different
-    // than C++ class type, but needs llvm metadata changes first.
-    RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,
-					Size, Align, 0, 0, llvm::DIType(),
-					llvm::DIArray(), llvm::DIType(),
-					llvm::DIArray());
-  } else
-    RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
-					 Size, Align, 0, llvm::DIArray());
-
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
-  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = llvm::DIType(RealDecl);
-
-  if (CXXDecl) {
-    // A class's primary base or the class itself contains the vtable.
-    llvm::MDNode *ContainingType = NULL;
-    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-    if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
-      // Seek non virtual primary base root.
-      while (1) {
-	const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
-	const CXXRecordDecl *PBT = BRL.getPrimaryBase();
-	if (PBT && !BRL.isPrimaryBaseVirtual())
-	  PBase = PBT;
-	else
-	  break;
-      }
-      ContainingType =
-	getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit);
-    }
-    else if (CXXDecl->isDynamicClass())
-      ContainingType = RealDecl;
-
-    RealDecl->replaceOperandWith(12, ContainingType);
-  }
-  return llvm::DIType(RealDecl);
-}
-
-/// CreateLimitedTypeNode - Create a new debug type node, but only forward
-/// declare composite types that haven't been processed yet.
-llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) {
-
-  // Work out details of type.
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base)
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-        #include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Dependent types cannot show up in debug information");
-
-  case Type::Record:
-    return CreateLimitedType(cast<RecordType>(Ty));
-  default:
-    return CreateTypeNode(Ty, Unit);
-  }
-}
-
-/// CreateMemberType - Create new member and increase Offset by FType's size.
-llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,
-                                           StringRef Name,
-                                           uint64_t *Offset) {
-  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
-  uint64_t FieldSize = CGM.getContext().getTypeSize(FType);
-  unsigned FieldAlign = CGM.getContext().getTypeAlign(FType);
-  llvm::DIType Ty = DBuilder.createMemberType(Unit, Name, Unit, 0,
-                                              FieldSize, FieldAlign,
-                                              *Offset, 0, FieldTy);
-  *Offset += FieldSize;
-  return Ty;
-}
-
-/// getFunctionDeclaration - Return debug info descriptor to describe method
-/// declaration for the given method definition.
-llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {
-  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (!FD) return llvm::DISubprogram();
-
-  // Setup context.
-  getContextDescriptor(cast<Decl>(D->getDeclContext()));
-
-  llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
-    MI = SPCache.find(FD->getCanonicalDecl());
-  if (MI != SPCache.end()) {
-    llvm::Value *V = MI->second;
-    llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V));
-    if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition())
-      return SP;
-  }
-
-  for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),
-         E = FD->redecls_end(); I != E; ++I) {
-    const FunctionDecl *NextFD = *I;
-    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
-      MI = SPCache.find(NextFD->getCanonicalDecl());
-    if (MI != SPCache.end()) {
-      llvm::Value *V = MI->second;
-      llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V));
-      if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition())
-        return SP;
-    }
-  }
-  return llvm::DISubprogram();
-}
-
-// getOrCreateFunctionType - Construct DIType. If it is a c++ method, include
-// implicit parameter "this".
-llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl *D,
-                                                  QualType FnType,
-                                                  llvm::DIFile F) {
-
-  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
-    return getOrCreateMethodType(Method, F);
-  if (const ObjCMethodDecl *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
-    // Add "self" and "_cmd"
-    SmallVector<llvm::Value *, 16> Elts;
-
-    // First element is always return type. For 'void' functions it is NULL.
-    Elts.push_back(getOrCreateType(OMethod->getResultType(), F));
-    // "self" pointer is always first argument.
-    llvm::DIType SelfTy = getOrCreateType(OMethod->getSelfDecl()->getType(), F);
-    Elts.push_back(DBuilder.createObjectPointerType(SelfTy));
-    // "_cmd" pointer is always second argument.
-    llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F);
-    Elts.push_back(DBuilder.createArtificialType(CmdTy));
-    // Get rest of the arguments.
-    for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(), 
-           PE = OMethod->param_end(); PI != PE; ++PI)
-      Elts.push_back(getOrCreateType((*PI)->getType(), F));
-
-    llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
-    return DBuilder.createSubroutineType(F, EltTypeArray);
-  }
-  return getOrCreateType(FnType, F);
-}
-
-/// EmitFunctionStart - Constructs the debug code for entering a function.
-void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
-                                    llvm::Function *Fn,
-                                    CGBuilderTy &Builder) {
-
-  StringRef Name;
-  StringRef LinkageName;
-
-  FnBeginRegionCount.push_back(LexicalBlockStack.size());
-
-  const Decl *D = GD.getDecl();
-  // Function may lack declaration in source code if it is created by Clang
-  // CodeGen (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
-  bool HasDecl = (D != 0);
-  // Use the location of the declaration.
-  SourceLocation Loc;
-  if (HasDecl)
-    Loc = D->getLocation();
-
-  unsigned Flags = 0;
-  llvm::DIFile Unit = getOrCreateFile(Loc);
-  llvm::DIDescriptor FDContext(Unit);
-  llvm::DIArray TParamsArray;
-  if (!HasDecl) {
-    // Use llvm function name.
-    Name = Fn->getName();
-  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    // If there is a DISubprogram for this function available then use it.
-    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
-      FI = SPCache.find(FD->getCanonicalDecl());
-    if (FI != SPCache.end()) {
-      llvm::Value *V = FI->second;
-      llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(V));
-      if (SP.isSubprogram() && llvm::DISubprogram(SP).isDefinition()) {
-        llvm::MDNode *SPN = SP;
-        LexicalBlockStack.push_back(SPN);
-        RegionMap[D] = llvm::WeakVH(SP);
-        return;
-      }
-    }
-    Name = getFunctionName(FD);
-    // Use mangled name as linkage name for c/c++ functions.
-    if (FD->hasPrototype()) {
-      LinkageName = CGM.getMangledName(GD);
-      Flags |= llvm::DIDescriptor::FlagPrototyped;
-    }
-    if (LinkageName == Name ||
-        CGM.getCodeGenOpts().getDebugInfo() <= CodeGenOptions::DebugLineTablesOnly)
-      LinkageName = StringRef();
-
-    if (CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) {
-      if (const NamespaceDecl *NSDecl =
-          dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
-        FDContext = getOrCreateNameSpace(NSDecl);
-      else if (const RecordDecl *RDecl =
-               dyn_cast_or_null<RecordDecl>(FD->getDeclContext()))
-        FDContext = getContextDescriptor(cast<Decl>(RDecl->getDeclContext()));
-
-      // Collect template parameters.
-      TParamsArray = CollectFunctionTemplateParams(FD, Unit);
-    }
-  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
-    Name = getObjCMethodName(OMD);
-    Flags |= llvm::DIDescriptor::FlagPrototyped;
-  } else {
-    // Use llvm function name.
-    Name = Fn->getName();
-    Flags |= llvm::DIDescriptor::FlagPrototyped;
-  }
-  if (!Name.empty() && Name[0] == '\01')
-    Name = Name.substr(1);
-
-  unsigned LineNo = getLineNumber(Loc);
-  if (!HasDecl || D->isImplicit())
-    Flags |= llvm::DIDescriptor::FlagArtificial;
-
-  llvm::DIType DIFnType;
-  llvm::DISubprogram SPDecl;
-  if (HasDecl &&
-      CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) {
-    DIFnType = getOrCreateFunctionType(D, FnType, Unit);
-    SPDecl = getFunctionDeclaration(D);
-  } else {
-    // Create fake but valid subroutine type. Otherwise
-    // llvm::DISubprogram::Verify() would return false, and
-    // subprogram DIE will miss DW_AT_decl_file and
-    // DW_AT_decl_line fields.
-    SmallVector<llvm::Value*, 16> Elts;
-    llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
-    DIFnType = DBuilder.createSubroutineType(Unit, EltTypeArray);
-  }
-  llvm::DISubprogram SP;
-  SP = DBuilder.createFunction(FDContext, Name, LinkageName, Unit,
-                               LineNo, DIFnType,
-                               Fn->hasInternalLinkage(), true/*definition*/,
-                               getLineNumber(CurLoc), Flags,
-                               CGM.getLangOpts().Optimize,
-                               Fn, TParamsArray, SPDecl);
-
-  // Push function on region stack.
-  llvm::MDNode *SPN = SP;
-  LexicalBlockStack.push_back(SPN);
-  if (HasDecl)
-    RegionMap[D] = llvm::WeakVH(SP);
-}
-
-/// EmitLocation - Emit metadata to indicate a change in line/column
-/// information in the source file.
-void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
-  
-  // Update our current location
-  setLocation(Loc);
-
-  if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
-
-  // Don't bother if things are the same as last time.
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  if (CurLoc == PrevLoc ||
-      SM.getExpansionLoc(CurLoc) == SM.getExpansionLoc(PrevLoc))
-    // New Builder may not be in sync with CGDebugInfo.
-    if (!Builder.getCurrentDebugLocation().isUnknown())
-      return;
-  
-  // Update last state.
-  PrevLoc = CurLoc;
-
-  llvm::MDNode *Scope = LexicalBlockStack.back();
-  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(CurLoc),
-                                                      getColumnNumber(CurLoc),
-                                                      Scope));
-}
-
-/// CreateLexicalBlock - Creates a new lexical block node and pushes it on
-/// the stack.
-void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
-  llvm::DIDescriptor D =
-    DBuilder.createLexicalBlock(LexicalBlockStack.empty() ?
-                                llvm::DIDescriptor() :
-                                llvm::DIDescriptor(LexicalBlockStack.back()),
-                                getOrCreateFile(CurLoc),
-                                getLineNumber(CurLoc),
-                                getColumnNumber(CurLoc));
-  llvm::MDNode *DN = D;
-  LexicalBlockStack.push_back(DN);
-}
-
-/// EmitLexicalBlockStart - Constructs the debug code for entering a declarative
-/// region - beginning of a DW_TAG_lexical_block.
-void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc) {
-  // Set our current location.
-  setLocation(Loc);
-
-  // Create a new lexical block and push it on the stack.
-  CreateLexicalBlock(Loc);
-
-  // Emit a line table change for the current location inside the new scope.
-  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(Loc),
-                                  getColumnNumber(Loc),
-                                  LexicalBlockStack.back()));
-}
-
-/// EmitLexicalBlockEnd - Constructs the debug code for exiting a declarative
-/// region - end of a DW_TAG_lexical_block.
-void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc) {
-  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
-
-  // Provide an entry in the line table for the end of the block.
-  EmitLocation(Builder, Loc);
-
-  LexicalBlockStack.pop_back();
-}
-
-/// EmitFunctionEnd - Constructs the debug code for exiting a function.
-void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
-  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
-  unsigned RCount = FnBeginRegionCount.back();
-  assert(RCount <= LexicalBlockStack.size() && "Region stack mismatch");
-
-  // Pop all regions for this function.
-  while (LexicalBlockStack.size() != RCount)
-    EmitLexicalBlockEnd(Builder, CurLoc);
-  FnBeginRegionCount.pop_back();
-}
-
-// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  
-// See BuildByRefType.
-llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
-                                                       uint64_t *XOffset) {
-
-  SmallVector<llvm::Value *, 5> EltTys;
-  QualType FType;
-  uint64_t FieldSize, FieldOffset;
-  unsigned FieldAlign;
-  
-  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
-  QualType Type = VD->getType();  
-
-  FieldOffset = 0;
-  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
-  EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));
-  EltTys.push_back(CreateMemberType(Unit, FType, "__forwarding", &FieldOffset));
-  FType = CGM.getContext().IntTy;
-  EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));
-  EltTys.push_back(CreateMemberType(Unit, FType, "__size", &FieldOffset));
-
-  bool HasCopyAndDispose = CGM.getContext().BlockRequiresCopying(Type, VD);
-  if (HasCopyAndDispose) {
-    FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
-    EltTys.push_back(CreateMemberType(Unit, FType, "__copy_helper",
-                                      &FieldOffset));
-    EltTys.push_back(CreateMemberType(Unit, FType, "__destroy_helper",
-                                      &FieldOffset));
-  }
-  bool HasByrefExtendedLayout;
-  Qualifiers::ObjCLifetime Lifetime;
-  if (CGM.getContext().getByrefLifetime(Type,
-                                        Lifetime, HasByrefExtendedLayout)
-      && HasByrefExtendedLayout)
-    EltTys.push_back(CreateMemberType(Unit, FType,
-                                      "__byref_variable_layout",
-                                      &FieldOffset));
-  
-  CharUnits Align = CGM.getContext().getDeclAlign(VD);
-  if (Align > CGM.getContext().toCharUnitsFromBits(
-        CGM.getContext().getTargetInfo().getPointerAlign(0))) {
-    CharUnits FieldOffsetInBytes 
-      = CGM.getContext().toCharUnitsFromBits(FieldOffset);
-    CharUnits AlignedOffsetInBytes
-      = FieldOffsetInBytes.RoundUpToAlignment(Align);
-    CharUnits NumPaddingBytes
-      = AlignedOffsetInBytes - FieldOffsetInBytes;
-    
-    if (NumPaddingBytes.isPositive()) {
-      llvm::APInt pad(32, NumPaddingBytes.getQuantity());
-      FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
-                                                    pad, ArrayType::Normal, 0);
-      EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset));
-    }
-  }
-  
-  FType = Type;
-  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
-  FieldSize = CGM.getContext().getTypeSize(FType);
-  FieldAlign = CGM.getContext().toBits(Align);
-
-  *XOffset = FieldOffset;  
-  FieldTy = DBuilder.createMemberType(Unit, VD->getName(), Unit,
-                                      0, FieldSize, FieldAlign,
-                                      FieldOffset, 0, FieldTy);
-  EltTys.push_back(FieldTy);
-  FieldOffset += FieldSize;
-  
-  llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-  
-  unsigned Flags = llvm::DIDescriptor::FlagBlockByrefStruct;
-  
-  return DBuilder.createStructType(Unit, "", Unit, 0, FieldOffset, 0, Flags,
-                                   Elements);
-}
-
-/// EmitDeclare - Emit local variable declaration debug info.
-void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
-                              llvm::Value *Storage, 
-                              unsigned ArgNo, CGBuilderTy &Builder) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
-
-  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
-  llvm::DIType Ty;
-  uint64_t XOffset = 0;
-  if (VD->hasAttr<BlocksAttr>())
-    Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
-  else 
-    Ty = getOrCreateType(VD->getType(), Unit);
-
-  // If there is no debug info for this type then do not emit debug info
-  // for this variable.
-  if (!Ty)
-    return;
-
-  if (llvm::Argument *Arg = dyn_cast<llvm::Argument>(Storage)) {
-    // If Storage is an aggregate returned as 'sret' then let debugger know
-    // about this.
-    if (Arg->hasStructRetAttr())
-      Ty = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, Ty);
-    else if (CXXRecordDecl *Record = VD->getType()->getAsCXXRecordDecl()) {
-      // If an aggregate variable has non trivial destructor or non trivial copy
-      // constructor than it is pass indirectly. Let debug info know about this
-      // by using reference of the aggregate type as a argument type.
-      if (Record->hasNonTrivialCopyConstructor() ||
-          !Record->hasTrivialDestructor())
-        Ty = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, Ty);
-    }
-  }
-      
-  // Get location information.
-  unsigned Line = getLineNumber(VD->getLocation());
-  unsigned Column = getColumnNumber(VD->getLocation());
-  unsigned Flags = 0;
-  if (VD->isImplicit())
-    Flags |= llvm::DIDescriptor::FlagArtificial;
-  // If this is the first argument and it is implicit then
-  // give it an object pointer flag.
-  // FIXME: There has to be a better way to do this, but for static
-  // functions there won't be an implicit param at arg1 and
-  // otherwise it is 'self' or 'this'.
-  if (isa<ImplicitParamDecl>(VD) && ArgNo == 1)
-    Flags |= llvm::DIDescriptor::FlagObjectPointer;
-
-  llvm::MDNode *Scope = LexicalBlockStack.back();
-
-  StringRef Name = VD->getName();
-  if (!Name.empty()) {
-    if (VD->hasAttr<BlocksAttr>()) {
-      CharUnits offset = CharUnits::fromQuantity(32);
-      SmallVector<llvm::Value *, 9> addr;
-      llvm::Type *Int64Ty = CGM.Int64Ty;
-      addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
-      // offset of __forwarding field
-      offset = CGM.getContext().toCharUnitsFromBits(
-        CGM.getContext().getTargetInfo().getPointerWidth(0));
-      addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
-      addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));
-      addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
-      // offset of x field
-      offset = CGM.getContext().toCharUnitsFromBits(XOffset);
-      addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
-
-      // Create the descriptor for the variable.
-      llvm::DIVariable D =
-        DBuilder.createComplexVariable(Tag, 
-                                       llvm::DIDescriptor(Scope),
-                                       VD->getName(), Unit, Line, Ty,
-                                       addr, ArgNo);
-      
-      // Insert an llvm.dbg.declare into the current block.
-      llvm::Instruction *Call =
-        DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
-      Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
-      return;
-    } else if (isa<VariableArrayType>(VD->getType())) {
-      // These are "complex" variables in that they need an op_deref.
-      // Create the descriptor for the variable.
-      llvm::Value *Addr = llvm::ConstantInt::get(CGM.Int64Ty,
-                                                 llvm::DIBuilder::OpDeref);
-      llvm::DIVariable D =
-        DBuilder.createComplexVariable(Tag,
-                                       llvm::DIDescriptor(Scope),
-                                       Name, Unit, Line, Ty,
-                                       Addr, ArgNo);
-
-      // Insert an llvm.dbg.declare into the current block.
-      llvm::Instruction *Call =
-        DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
-      Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
-      return;
-    }
-    
-    // Create the descriptor for the variable.
-    llvm::DIVariable D =
-      DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope), 
-                                   Name, Unit, Line, Ty, 
-                                   CGM.getLangOpts().Optimize, Flags, ArgNo);
-    
-    // Insert an llvm.dbg.declare into the current block.
-    llvm::Instruction *Call =
-      DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
-    Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
-    return;
-  }
-  
-  // If VD is an anonymous union then Storage represents value for
-  // all union fields.
-  if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) {
-    const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
-    if (RD->isUnion()) {
-      for (RecordDecl::field_iterator I = RD->field_begin(),
-             E = RD->field_end();
-           I != E; ++I) {
-        FieldDecl *Field = *I;
-        llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
-        StringRef FieldName = Field->getName();
-          
-        // Ignore unnamed fields. Do not ignore unnamed records.
-        if (FieldName.empty() && !isa<RecordType>(Field->getType()))
-          continue;
-          
-        // Use VarDecl's Tag, Scope and Line number.
-        llvm::DIVariable D =
-          DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
-                                       FieldName, Unit, Line, FieldTy, 
-                                       CGM.getLangOpts().Optimize, Flags,
-                                       ArgNo);
-          
-        // Insert an llvm.dbg.declare into the current block.
-        llvm::Instruction *Call =
-          DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
-        Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
-      }
-    }
-  }
-}
-
-void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
-                                            llvm::Value *Storage,
-                                            CGBuilderTy &Builder) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, 0, Builder);
-}
-
-void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD,
-                                                    llvm::Value *Storage,
-                                                    CGBuilderTy &Builder,
-                                                 const CGBlockInfo &blockInfo) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
-  
-  if (Builder.GetInsertBlock() == 0)
-    return;
-  
-  bool isByRef = VD->hasAttr<BlocksAttr>();
-  
-  uint64_t XOffset = 0;
-  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
-  llvm::DIType Ty;
-  if (isByRef)
-    Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
-  else 
-    Ty = getOrCreateType(VD->getType(), Unit);
-
-  // Self is passed along as an implicit non-arg variable in a
-  // block. Mark it as the object pointer.
-  if (isa<ImplicitParamDecl>(VD) && VD->getName() == "self")
-    Ty = DBuilder.createObjectPointerType(Ty);
-
-  // Get location information.
-  unsigned Line = getLineNumber(VD->getLocation());
-  unsigned Column = getColumnNumber(VD->getLocation());
-
-  const llvm::DataLayout &target = CGM.getDataLayout();
-
-  CharUnits offset = CharUnits::fromQuantity(
-    target.getStructLayout(blockInfo.StructureType)
-          ->getElementOffset(blockInfo.getCapture(VD).getIndex()));
-
-  SmallVector<llvm::Value *, 9> addr;
-  llvm::Type *Int64Ty = CGM.Int64Ty;
-  addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
-  addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
-  if (isByRef) {
-    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));
-    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
-    // offset of __forwarding field
-    offset = CGM.getContext()
-                .toCharUnitsFromBits(target.getPointerSizeInBits(0));
-    addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
-    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));
-    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
-    // offset of x field
-    offset = CGM.getContext().toCharUnitsFromBits(XOffset);
-    addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
-  }
-
-  // Create the descriptor for the variable.
-  llvm::DIVariable D =
-    DBuilder.createComplexVariable(llvm::dwarf::DW_TAG_auto_variable, 
-                                   llvm::DIDescriptor(LexicalBlockStack.back()),
-                                   VD->getName(), Unit, Line, Ty, addr);
-  // Insert an llvm.dbg.declare into the current block.
-  llvm::Instruction *Call =
-    DBuilder.insertDeclare(Storage, D, Builder.GetInsertPoint());
-  Call->setDebugLoc(llvm::DebugLoc::get(Line, Column,
-                                        LexicalBlockStack.back()));
-}
-
-/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
-/// variable declaration.
-void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
-                                           unsigned ArgNo,
-                                           CGBuilderTy &Builder) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, ArgNo, Builder);
-}
-
-namespace {
-  struct BlockLayoutChunk {
-    uint64_t OffsetInBits;
-    const BlockDecl::Capture *Capture;
-  };
-  bool operator<(const BlockLayoutChunk &l, const BlockLayoutChunk &r) {
-    return l.OffsetInBits < r.OffsetInBits;
-  }
-}
-
-void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
-                                                       llvm::Value *addr,
-                                                       CGBuilderTy &Builder) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  ASTContext &C = CGM.getContext();
-  const BlockDecl *blockDecl = block.getBlockDecl();
-
-  // Collect some general information about the block's location.
-  SourceLocation loc = blockDecl->getCaretLocation();
-  llvm::DIFile tunit = getOrCreateFile(loc);
-  unsigned line = getLineNumber(loc);
-  unsigned column = getColumnNumber(loc);
-  
-  // Build the debug-info type for the block literal.
-  getContextDescriptor(cast<Decl>(blockDecl->getDeclContext()));
-
-  const llvm::StructLayout *blockLayout =
-    CGM.getDataLayout().getStructLayout(block.StructureType);
-
-  SmallVector<llvm::Value*, 16> fields;
-  fields.push_back(createFieldType("__isa", C.VoidPtrTy, 0, loc, AS_public,
-                                   blockLayout->getElementOffsetInBits(0),
-                                   tunit, tunit));
-  fields.push_back(createFieldType("__flags", C.IntTy, 0, loc, AS_public,
-                                   blockLayout->getElementOffsetInBits(1),
-                                   tunit, tunit));
-  fields.push_back(createFieldType("__reserved", C.IntTy, 0, loc, AS_public,
-                                   blockLayout->getElementOffsetInBits(2),
-                                   tunit, tunit));
-  fields.push_back(createFieldType("__FuncPtr", C.VoidPtrTy, 0, loc, AS_public,
-                                   blockLayout->getElementOffsetInBits(3),
-                                   tunit, tunit));
-  fields.push_back(createFieldType("__descriptor",
-                                   C.getPointerType(block.NeedsCopyDispose ?
-                                        C.getBlockDescriptorExtendedType() :
-                                        C.getBlockDescriptorType()),
-                                   0, loc, AS_public,
-                                   blockLayout->getElementOffsetInBits(4),
-                                   tunit, tunit));
-
-  // We want to sort the captures by offset, not because DWARF
-  // requires this, but because we're paranoid about debuggers.
-  SmallVector<BlockLayoutChunk, 8> chunks;
-
-  // 'this' capture.
-  if (blockDecl->capturesCXXThis()) {
-    BlockLayoutChunk chunk;
-    chunk.OffsetInBits =
-      blockLayout->getElementOffsetInBits(block.CXXThisIndex);
-    chunk.Capture = 0;
-    chunks.push_back(chunk);
-  }
-
-  // Variable captures.
-  for (BlockDecl::capture_const_iterator
-         i = blockDecl->capture_begin(), e = blockDecl->capture_end();
-       i != e; ++i) {
-    const BlockDecl::Capture &capture = *i;
-    const VarDecl *variable = capture.getVariable();
-    const CGBlockInfo::Capture &captureInfo = block.getCapture(variable);
-
-    // Ignore constant captures.
-    if (captureInfo.isConstant())
-      continue;
-
-    BlockLayoutChunk chunk;
-    chunk.OffsetInBits =
-      blockLayout->getElementOffsetInBits(captureInfo.getIndex());
-    chunk.Capture = &capture;
-    chunks.push_back(chunk);
-  }
-
-  // Sort by offset.
-  llvm::array_pod_sort(chunks.begin(), chunks.end());
-
-  for (SmallVectorImpl<BlockLayoutChunk>::iterator
-         i = chunks.begin(), e = chunks.end(); i != e; ++i) {
-    uint64_t offsetInBits = i->OffsetInBits;
-    const BlockDecl::Capture *capture = i->Capture;
-
-    // If we have a null capture, this must be the C++ 'this' capture.
-    if (!capture) {
-      const CXXMethodDecl *method =
-        cast<CXXMethodDecl>(blockDecl->getNonClosureContext());
-      QualType type = method->getThisType(C);
-
-      fields.push_back(createFieldType("this", type, 0, loc, AS_public,
-                                       offsetInBits, tunit, tunit));
-      continue;
-    }
-
-    const VarDecl *variable = capture->getVariable();
-    StringRef name = variable->getName();
-
-    llvm::DIType fieldType;
-    if (capture->isByRef()) {
-      std::pair<uint64_t,unsigned> ptrInfo = C.getTypeInfo(C.VoidPtrTy);
-
-      // FIXME: this creates a second copy of this type!
-      uint64_t xoffset;
-      fieldType = EmitTypeForVarWithBlocksAttr(variable, &xoffset);
-      fieldType = DBuilder.createPointerType(fieldType, ptrInfo.first);
-      fieldType = DBuilder.createMemberType(tunit, name, tunit, line,
-                                            ptrInfo.first, ptrInfo.second,
-                                            offsetInBits, 0, fieldType);
-    } else {
-      fieldType = createFieldType(name, variable->getType(), 0,
-                                  loc, AS_public, offsetInBits, tunit, tunit);
-    }
-    fields.push_back(fieldType);
-  }
-
-  SmallString<36> typeName;
-  llvm::raw_svector_ostream(typeName)
-    << "__block_literal_" << CGM.getUniqueBlockCount();
-
-  llvm::DIArray fieldsArray = DBuilder.getOrCreateArray(fields);
-
-  llvm::DIType type =
-    DBuilder.createStructType(tunit, typeName.str(), tunit, line,
-                              CGM.getContext().toBits(block.BlockSize),
-                              CGM.getContext().toBits(block.BlockAlign),
-                              0, fieldsArray);
-  type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);
-
-  // Get overall information about the block.
-  unsigned flags = llvm::DIDescriptor::FlagArtificial;
-  llvm::MDNode *scope = LexicalBlockStack.back();
-  StringRef name = ".block_descriptor";
-
-  // Create the descriptor for the parameter.
-  llvm::DIVariable debugVar =
-    DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_arg_variable,
-                                 llvm::DIDescriptor(scope), 
-                                 name, tunit, line, type, 
-                                 CGM.getLangOpts().Optimize, flags,
-                                 cast<llvm::Argument>(addr)->getArgNo() + 1);
-    
-  // Insert an llvm.dbg.value into the current block.
-  llvm::Instruction *declare =
-    DBuilder.insertDbgValueIntrinsic(addr, 0, debugVar,
-                                     Builder.GetInsertBlock());
-  declare->setDebugLoc(llvm::DebugLoc::get(line, column, scope));
-}
-
-/// EmitGlobalVariable - Emit information about a global variable.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
-                                     const VarDecl *D) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  // Create global variable debug descriptor.
-  llvm::DIFile Unit = getOrCreateFile(D->getLocation());
-  unsigned LineNo = getLineNumber(D->getLocation());
-
-  setLocation(D->getLocation());
-
-  QualType T = D->getType();
-  if (T->isIncompleteArrayType()) {
-
-    // CodeGen turns int[] into int[1] so we'll do the same here.
-    llvm::APInt ConstVal(32, 1);
-    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
-
-    T = CGM.getContext().getConstantArrayType(ET, ConstVal,
-                                              ArrayType::Normal, 0);
-  }
-  StringRef DeclName = D->getName();
-  StringRef LinkageName;
-  if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext())
-      && !isa<ObjCMethodDecl>(D->getDeclContext()))
-    LinkageName = Var->getName();
-  if (LinkageName == DeclName)
-    LinkageName = StringRef();
-  llvm::DIDescriptor DContext = 
-    getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()));
-  DBuilder.createStaticVariable(DContext, DeclName, LinkageName,
-                                Unit, LineNo, getOrCreateType(T, Unit),
-                                Var->hasInternalLinkage(), Var);
-}
-
-/// EmitGlobalVariable - Emit information about an objective-c interface.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
-                                     ObjCInterfaceDecl *ID) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  // Create global variable debug descriptor.
-  llvm::DIFile Unit = getOrCreateFile(ID->getLocation());
-  unsigned LineNo = getLineNumber(ID->getLocation());
-
-  StringRef Name = ID->getName();
-
-  QualType T = CGM.getContext().getObjCInterfaceType(ID);
-  if (T->isIncompleteArrayType()) {
-
-    // CodeGen turns int[] into int[1] so we'll do the same here.
-    llvm::APInt ConstVal(32, 1);
-    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
-
-    T = CGM.getContext().getConstantArrayType(ET, ConstVal,
-                                           ArrayType::Normal, 0);
-  }
-
-  DBuilder.createGlobalVariable(Name, Unit, LineNo,
-                                getOrCreateType(T, Unit),
-                                Var->hasInternalLinkage(), Var);
-}
-
-/// EmitGlobalVariable - Emit global variable's debug info.
-void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, 
-                                     llvm::Constant *Init) {
-  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);
-  // Create the descriptor for the variable.
-  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
-  StringRef Name = VD->getName();
-  llvm::DIType Ty = getOrCreateType(VD->getType(), Unit);
-  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(VD)) {
-    const EnumDecl *ED = cast<EnumDecl>(ECD->getDeclContext());
-    assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?");
-    Ty = getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit);
-  }
-  // Do not use DIGlobalVariable for enums.
-  if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type)
-    return;
-  DBuilder.createStaticVariable(Unit, Name, Name, Unit,
-                                getLineNumber(VD->getLocation()),
-                                Ty, true, Init);
-}
-
-/// getOrCreateNamesSpace - Return namespace descriptor for the given
-/// namespace decl.
-llvm::DINameSpace 
-CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {
-  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH>::iterator I = 
-    NameSpaceCache.find(NSDecl);
-  if (I != NameSpaceCache.end())
-    return llvm::DINameSpace(cast<llvm::MDNode>(I->second));
-  
-  unsigned LineNo = getLineNumber(NSDecl->getLocation());
-  llvm::DIFile FileD = getOrCreateFile(NSDecl->getLocation());
-  llvm::DIDescriptor Context = 
-    getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()));
-  llvm::DINameSpace NS =
-    DBuilder.createNameSpace(Context, NSDecl->getName(), FileD, LineNo);
-  NameSpaceCache[NSDecl] = llvm::WeakVH(NS);
-  return NS;
-}
-
-void CGDebugInfo::finalize() {
-  for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI
-         = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {
-    llvm::DIType Ty, RepTy;
-    // Verify that the debug info still exists.
-    if (llvm::Value *V = VI->second)
-      Ty = llvm::DIType(cast<llvm::MDNode>(V));
-    
-    llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-      TypeCache.find(VI->first);
-    if (it != TypeCache.end()) {
-      // Verify that the debug info still exists.
-      if (llvm::Value *V = it->second)
-        RepTy = llvm::DIType(cast<llvm::MDNode>(V));
-    }
-    
-    if (Ty.Verify() && Ty.isForwardDecl() && RepTy.Verify()) {
-      Ty.replaceAllUsesWith(RepTy);
-    }
-  }
-  DBuilder.finalize();
-}
+//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This coordinates the debug information generation while generating code.

+//

+//===----------------------------------------------------------------------===//

+

+#include "CGDebugInfo.h"

+#include "CGBlocks.h"

+#include "CGObjCRuntime.h"

+#include "CodeGenFunction.h"

+#include "CodeGenModule.h"

+#include "clang/AST/ASTContext.h"

+#include "clang/AST/DeclFriend.h"

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

+#include "clang/AST/DeclTemplate.h"

+#include "clang/AST/Expr.h"

+#include "clang/AST/RecordLayout.h"

+#include "clang/Basic/FileManager.h"

+#include "clang/Basic/SourceManager.h"

+#include "clang/Basic/Version.h"

+#include "clang/Frontend/CodeGenOptions.h"

+#include "llvm/ADT/SmallVector.h"

+#include "llvm/ADT/StringExtras.h"

+#include "llvm/Constants.h"

+#include "llvm/DataLayout.h"

+#include "llvm/DerivedTypes.h"

+#include "llvm/Instructions.h"

+#include "llvm/Intrinsics.h"

+#include "llvm/Module.h"

+#include "llvm/Support/Dwarf.h"

+#include "llvm/Support/FileSystem.h"

+using namespace clang;

+using namespace clang::CodeGen;

+

+CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)

+  : CGM(CGM), DBuilder(CGM.getModule()),

+    BlockLiteralGenericSet(false) {

+  CreateCompileUnit();

+}

+

+CGDebugInfo::~CGDebugInfo() {

+  assert(LexicalBlockStack.empty() &&

+         "Region stack mismatch, stack not empty!");

+}

+

+void CGDebugInfo::setLocation(SourceLocation Loc) {

+  // If the new location isn't valid return.

+  if (!Loc.isValid()) return;

+

+  CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);

+

+  // If we've changed files in the middle of a lexical scope go ahead

+  // and create a new lexical scope with file node if it's different

+  // from the one in the scope.

+  if (LexicalBlockStack.empty()) return;

+

+  SourceManager &SM = CGM.getContext().getSourceManager();

+  PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);

+  PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc);

+

+  if (PCLoc.isInvalid() || PPLoc.isInvalid() ||

+      !strcmp(PPLoc.getFilename(), PCLoc.getFilename()))

+    return;

+

+  llvm::MDNode *LB = LexicalBlockStack.back();

+  llvm::DIScope Scope = llvm::DIScope(LB);

+  if (Scope.isLexicalBlockFile()) {

+    llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(LB);

+    llvm::DIDescriptor D

+      = DBuilder.createLexicalBlockFile(LBF.getScope(),

+                                        getOrCreateFile(CurLoc));

+    llvm::MDNode *N = D;

+    LexicalBlockStack.pop_back();

+    LexicalBlockStack.push_back(N);

+  } else if (Scope.isLexicalBlock()) {

+    llvm::DIDescriptor D

+      = DBuilder.createLexicalBlockFile(Scope, getOrCreateFile(CurLoc));

+    llvm::MDNode *N = D;

+    LexicalBlockStack.pop_back();

+    LexicalBlockStack.push_back(N);

+  }

+}

+

+/// getContextDescriptor - Get context info for the decl.

+llvm::DIDescriptor CGDebugInfo::getContextDescriptor(const Decl *Context) {

+  if (!Context)

+    return TheCU;

+

+  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator

+    I = RegionMap.find(Context);

+  if (I != RegionMap.end()) {

+    llvm::Value *V = I->second;

+    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));

+  }

+

+  // Check namespace.

+  if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))

+    return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl));

+

+  if (const RecordDecl *RDecl = dyn_cast<RecordDecl>(Context)) {

+    if (!RDecl->isDependentType()) {

+      llvm::DIType Ty = getOrCreateType(CGM.getContext().getTypeDeclType(RDecl),

+                                        getOrCreateMainFile());

+      return llvm::DIDescriptor(Ty);

+    }

+  }

+  return TheCU;

+}

+

+/// getFunctionName - Get function name for the given FunctionDecl. If the

+/// name is constructred on demand (e.g. C++ destructor) then the name

+/// is stored on the side.

+StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {

+  assert (FD && "Invalid FunctionDecl!");

+  IdentifierInfo *FII = FD->getIdentifier();

+  FunctionTemplateSpecializationInfo *Info

+    = FD->getTemplateSpecializationInfo();

+  if (!Info && FII)

+    return FII->getName();

+

+  // Otherwise construct human readable name for debug info.

+  std::string NS = FD->getNameAsString();

+

+  // Add any template specialization args.

+  if (Info) {

+    const TemplateArgumentList *TArgs = Info->TemplateArguments;

+    const TemplateArgument *Args = TArgs->data();

+    unsigned NumArgs = TArgs->size();

+    PrintingPolicy Policy(CGM.getLangOpts());

+    NS += TemplateSpecializationType::PrintTemplateArgumentList(Args,

+                                                                NumArgs,

+                                                                Policy);

+  }

+

+  // Copy this name on the side and use its reference.

+  char *StrPtr = DebugInfoNames.Allocate<char>(NS.length());

+  memcpy(StrPtr, NS.data(), NS.length());

+  return StringRef(StrPtr, NS.length());

+}

+

+StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {

+  SmallString<256> MethodName;

+  llvm::raw_svector_ostream OS(MethodName);

+  OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';

+  const DeclContext *DC = OMD->getDeclContext();

+  if (const ObjCImplementationDecl *OID = 

+      dyn_cast<const ObjCImplementationDecl>(DC)) {

+     OS << OID->getName();

+  } else if (const ObjCInterfaceDecl *OID = 

+             dyn_cast<const ObjCInterfaceDecl>(DC)) {

+      OS << OID->getName();

+  } else if (const ObjCCategoryImplDecl *OCD = 

+             dyn_cast<const ObjCCategoryImplDecl>(DC)){

+      OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '(' <<

+          OCD->getIdentifier()->getNameStart() << ')';

+  }

+  OS << ' ' << OMD->getSelector().getAsString() << ']';

+

+  char *StrPtr = DebugInfoNames.Allocate<char>(OS.tell());

+  memcpy(StrPtr, MethodName.begin(), OS.tell());

+  return StringRef(StrPtr, OS.tell());

+}

+

+/// getSelectorName - Return selector name. This is used for debugging

+/// info.

+StringRef CGDebugInfo::getSelectorName(Selector S) {

+  const std::string &SName = S.getAsString();

+  char *StrPtr = DebugInfoNames.Allocate<char>(SName.size());

+  memcpy(StrPtr, SName.data(), SName.size());

+  return StringRef(StrPtr, SName.size());

+}

+

+/// getClassName - Get class name including template argument list.

+StringRef 

+CGDebugInfo::getClassName(const RecordDecl *RD) {

+  const ClassTemplateSpecializationDecl *Spec

+    = dyn_cast<ClassTemplateSpecializationDecl>(RD);

+  if (!Spec)

+    return RD->getName();

+

+  const TemplateArgument *Args;

+  unsigned NumArgs;

+  if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {

+    const TemplateSpecializationType *TST =

+      cast<TemplateSpecializationType>(TAW->getType());

+    Args = TST->getArgs();

+    NumArgs = TST->getNumArgs();

+  } else {

+    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();

+    Args = TemplateArgs.data();

+    NumArgs = TemplateArgs.size();

+  }

+  StringRef Name = RD->getIdentifier()->getName();

+  PrintingPolicy Policy(CGM.getLangOpts());

+  std::string TemplateArgList =

+    TemplateSpecializationType::PrintTemplateArgumentList(Args, NumArgs, Policy);

+

+  // Copy this name on the side and use its reference.

+  size_t Length = Name.size() + TemplateArgList.size();

+  char *StrPtr = DebugInfoNames.Allocate<char>(Length);

+  memcpy(StrPtr, Name.data(), Name.size());

+  memcpy(StrPtr + Name.size(), TemplateArgList.data(), TemplateArgList.size());

+  return StringRef(StrPtr, Length);

+}

+

+/// getOrCreateFile - Get the file debug info descriptor for the input location.

+llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) {

+  if (!Loc.isValid())

+    // If Location is not valid then use main input file.

+    return DBuilder.createFile(TheCU.getFilename(), TheCU.getDirectory());

+

+  SourceManager &SM = CGM.getContext().getSourceManager();

+  PresumedLoc PLoc = SM.getPresumedLoc(Loc);

+

+  if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty())

+    // If the location is not valid then use main input file.

+    return DBuilder.createFile(TheCU.getFilename(), TheCU.getDirectory());

+

+  // Cache the results.

+  const char *fname = PLoc.getFilename();

+  llvm::DenseMap<const char *, llvm::WeakVH>::iterator it =

+    DIFileCache.find(fname);

+

+  if (it != DIFileCache.end()) {

+    // Verify that the information still exists.

+    if (llvm::Value *V = it->second)

+      return llvm::DIFile(cast<llvm::MDNode>(V));

+  }

+

+  llvm::DIFile F = DBuilder.createFile(PLoc.getFilename(), getCurrentDirname());

+

+  DIFileCache[fname] = F;

+  return F;

+}

+

+/// getOrCreateMainFile - Get the file info for main compile unit.

+llvm::DIFile CGDebugInfo::getOrCreateMainFile() {

+  return DBuilder.createFile(TheCU.getFilename(), TheCU.getDirectory());

+}

+

+/// getLineNumber - Get line number for the location. If location is invalid

+/// then use current location.

+unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {

+  if (Loc.isInvalid() && CurLoc.isInvalid())

+    return 0;

+  SourceManager &SM = CGM.getContext().getSourceManager();

+  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);

+  return PLoc.isValid()? PLoc.getLine() : 0;

+}

+

+/// getColumnNumber - Get column number for the location.

+unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc) {

+  // We may not want column information at all.

+  if (!CGM.getCodeGenOpts().DebugColumnInfo)

+    return 0;

+

+  // If the location is invalid then use the current column.

+  if (Loc.isInvalid() && CurLoc.isInvalid())

+    return 0;

+  SourceManager &SM = CGM.getContext().getSourceManager();

+  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);

+  return PLoc.isValid()? PLoc.getColumn() : 0;

+}

+

+StringRef CGDebugInfo::getCurrentDirname() {

+  if (!CGM.getCodeGenOpts().DebugCompilationDir.empty())

+    return CGM.getCodeGenOpts().DebugCompilationDir;

+

+  if (!CWDName.empty())

+    return CWDName;

+  SmallString<256> CWD;

+  llvm::sys::fs::current_path(CWD);

+  char *CompDirnamePtr = DebugInfoNames.Allocate<char>(CWD.size());

+  memcpy(CompDirnamePtr, CWD.data(), CWD.size());

+  return CWDName = StringRef(CompDirnamePtr, CWD.size());

+}

+

+/// CreateCompileUnit - Create new compile unit.

+void CGDebugInfo::CreateCompileUnit() {

+

+  // Get absolute path name.

+  SourceManager &SM = CGM.getContext().getSourceManager();

+  std::string MainFileName = CGM.getCodeGenOpts().MainFileName;

+  if (MainFileName.empty())

+    MainFileName = "<unknown>";

+

+  // The main file name provided via the "-main-file-name" option contains just

+  // the file name itself with no path information. This file name may have had

+  // a relative path, so we look into the actual file entry for the main

+  // file to determine the real absolute path for the file.

+  std::string MainFileDir;

+  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {

+    MainFileDir = MainFile->getDir()->getName();

+    if (MainFileDir != ".")

+      MainFileName = MainFileDir + "/" + MainFileName;

+  }

+

+  // Save filename string.

+  char *FilenamePtr = DebugInfoNames.Allocate<char>(MainFileName.length());

+  memcpy(FilenamePtr, MainFileName.c_str(), MainFileName.length());

+  StringRef Filename(FilenamePtr, MainFileName.length());

+  

+  unsigned LangTag;

+  const LangOptions &LO = CGM.getLangOpts();

+  if (LO.CPlusPlus) {

+    if (LO.ObjC1)

+      LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;

+    else

+      LangTag = llvm::dwarf::DW_LANG_C_plus_plus;

+  } else if (LO.ObjC1) {

+    LangTag = llvm::dwarf::DW_LANG_ObjC;

+  } else if (LO.C99) {

+    LangTag = llvm::dwarf::DW_LANG_C99;

+  } else {

+    LangTag = llvm::dwarf::DW_LANG_C89;

+  }

+

+  std::string Producer = getClangFullVersion();

+

+  // Figure out which version of the ObjC runtime we have.

+  unsigned RuntimeVers = 0;

+  if (LO.ObjC1)

+    RuntimeVers = LO.ObjCRuntime.isNonFragile() ? 2 : 1;

+

+  // Create new compile unit.

+  DBuilder.createCompileUnit(

+    LangTag, Filename, getCurrentDirname(),

+    Producer,

+    LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers);

+  // FIXME - Eliminate TheCU.

+  TheCU = llvm::DICompileUnit(DBuilder.getCU());

+}

+

+/// CreateType - Get the Basic type from the cache or create a new

+/// one if necessary.

+llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {

+  unsigned Encoding = 0;

+  StringRef BTName;

+  switch (BT->getKind()) {

+#define BUILTIN_TYPE(Id, SingletonId)

+#define PLACEHOLDER_TYPE(Id, SingletonId) \

+  case BuiltinType::Id:

+#include "clang/AST/BuiltinTypes.def"

+  case BuiltinType::Dependent:

+    llvm_unreachable("Unexpected builtin type");

+  case BuiltinType::NullPtr:

+    return DBuilder.

+      createNullPtrType(BT->getName(CGM.getLangOpts()));

+  case BuiltinType::Void:

+    return llvm::DIType();

+  case BuiltinType::ObjCClass:

+    if (ClassTy.Verify())

+      return ClassTy;

+    ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

+                                         "objc_class", TheCU,

+                                         getOrCreateMainFile(), 0);

+    return ClassTy;

+  case BuiltinType::ObjCId: {

+    // typedef struct objc_class *Class;

+    // typedef struct objc_object {

+    //  Class isa;

+    // } *id;

+

+    if (ObjTy.Verify())

+      return ObjTy;

+

+    if (!ClassTy.Verify())

+      ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

+                                           "objc_class", TheCU,

+                                           getOrCreateMainFile(), 0);

+

+    unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);

+    

+    llvm::DIType ISATy = DBuilder.createPointerType(ClassTy, Size);

+

+    llvm::DIType FwdTy =  DBuilder.createStructType(TheCU, "objc_object", 

+                                                    getOrCreateMainFile(),

+                                                    0, 0, 0, 0,

+                                                    llvm::DIArray());

+

+    llvm::TrackingVH<llvm::MDNode> ObjNode(FwdTy);

+    SmallVector<llvm::Value *, 1> EltTys;

+    llvm::DIType FieldTy = 

+      DBuilder.createMemberType(llvm::DIDescriptor(ObjNode), "isa",

+                                getOrCreateMainFile(), 0, Size,

+                                0, 0, 0, ISATy);

+    EltTys.push_back(FieldTy);

+    llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);

+

+    ObjNode->replaceOperandWith(10, Elements);

+    ObjTy = llvm::DIType(ObjNode);

+    return ObjTy;

+  }

+  case BuiltinType::ObjCSel: {

+    if (SelTy.Verify())

+      return SelTy;

+    SelTy =

+      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

+                                 "objc_selector", TheCU, getOrCreateMainFile(),

+                                 0);

+    return SelTy;

+  }

+

+  case BuiltinType::OCLImage1d:

+    return getOrCreateStructPtrType("opencl_image1d_t",

+                                    OCLImage1dDITy);

+  case BuiltinType::OCLImage1dArray:

+    return getOrCreateStructPtrType("opencl_image1d_array_t", 

+                                    OCLImage1dArrayDITy);

+  case BuiltinType::OCLImage1dBuffer:

+    return getOrCreateStructPtrType("opencl_image1d_buffer_t",

+                                    OCLImage1dBufferDITy);

+  case BuiltinType::OCLImage2d:

+    return getOrCreateStructPtrType("opencl_image2d_t",

+                                    OCLImage2dDITy);

+  case BuiltinType::OCLImage2dArray:

+    return getOrCreateStructPtrType("opencl_image2d_array_t",

+                                    OCLImage2dArrayDITy);

+  case BuiltinType::OCLImage3d:

+    return getOrCreateStructPtrType("opencl_image3d_t",

+                                    OCLImage3dDITy);

+

+  case BuiltinType::UChar:

+  case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;

+  case BuiltinType::Char_S:

+  case BuiltinType::SChar: Encoding = llvm::dwarf::DW_ATE_signed_char; break;

+  case BuiltinType::Char16:

+  case BuiltinType::Char32: Encoding = llvm::dwarf::DW_ATE_UTF; break;

+  case BuiltinType::UShort:

+  case BuiltinType::UInt:

+  case BuiltinType::UInt128:

+  case BuiltinType::ULong:

+  case BuiltinType::WChar_U:

+  case BuiltinType::ULongLong: Encoding = llvm::dwarf::DW_ATE_unsigned; break;

+  case BuiltinType::Short:

+  case BuiltinType::Int:

+  case BuiltinType::Int128:

+  case BuiltinType::Long:

+  case BuiltinType::WChar_S:

+  case BuiltinType::LongLong:  Encoding = llvm::dwarf::DW_ATE_signed; break;

+  case BuiltinType::Bool:      Encoding = llvm::dwarf::DW_ATE_boolean; break;

+  case BuiltinType::Half:

+  case BuiltinType::Float:

+  case BuiltinType::LongDouble:

+  case BuiltinType::Double:    Encoding = llvm::dwarf::DW_ATE_float; break;

+  }

+

+  switch (BT->getKind()) {

+  case BuiltinType::Long:      BTName = "long int"; break;

+  case BuiltinType::LongLong:  BTName = "long long int"; break;

+  case BuiltinType::ULong:     BTName = "long unsigned int"; break;

+  case BuiltinType::ULongLong: BTName = "long long unsigned int"; break;

+  default:

+    BTName = BT->getName(CGM.getLangOpts());

+    break;

+  }

+  // Bit size, align and offset of the type.

+  uint64_t Size = CGM.getContext().getTypeSize(BT);

+  uint64_t Align = CGM.getContext().getTypeAlign(BT);

+  llvm::DIType DbgTy = 

+    DBuilder.createBasicType(BTName, Size, Align, Encoding);

+  return DbgTy;

+}

+

+llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) {

+  // Bit size, align and offset of the type.

+  unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;

+  if (Ty->isComplexIntegerType())

+    Encoding = llvm::dwarf::DW_ATE_lo_user;

+

+  uint64_t Size = CGM.getContext().getTypeSize(Ty);

+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);

+  llvm::DIType DbgTy = 

+    DBuilder.createBasicType("complex", Size, Align, Encoding);

+

+  return DbgTy;

+}

+

+/// CreateCVRType - Get the qualified type from the cache or create

+/// a new one if necessary.

+llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {

+  QualifierCollector Qc;

+  const Type *T = Qc.strip(Ty);

+

+  // Ignore these qualifiers for now.

+  Qc.removeObjCGCAttr();

+  Qc.removeAddressSpace();

+  Qc.removeObjCLifetime();

+

+  // We will create one Derived type for one qualifier and recurse to handle any

+  // additional ones.

+  unsigned Tag;

+  if (Qc.hasConst()) {

+    Tag = llvm::dwarf::DW_TAG_const_type;

+    Qc.removeConst();

+  } else if (Qc.hasVolatile()) {

+    Tag = llvm::dwarf::DW_TAG_volatile_type;

+    Qc.removeVolatile();

+  } else if (Qc.hasRestrict()) {

+    Tag = llvm::dwarf::DW_TAG_restrict_type;

+    Qc.removeRestrict();

+  } else {

+    assert(Qc.empty() && "Unknown type qualifier for debug info");

+    return getOrCreateType(QualType(T, 0), Unit);

+  }

+

+  llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);

+

+  // No need to fill in the Name, Line, Size, Alignment, Offset in case of

+  // CVR derived types.

+  llvm::DIType DbgTy = DBuilder.createQualifiedType(Tag, FromTy);

+  

+  return DbgTy;

+}

+

+llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,

+                                     llvm::DIFile Unit) {

+  llvm::DIType DbgTy =

+    CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, 

+                          Ty->getPointeeType(), Unit);

+  return DbgTy;

+}

+

+llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,

+                                     llvm::DIFile Unit) {

+  return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, 

+                               Ty->getPointeeType(), Unit);

+}

+

+// Creates a forward declaration for a RecordDecl in the given context.

+llvm::DIType CGDebugInfo::createRecordFwdDecl(const RecordDecl *RD,

+                                              llvm::DIDescriptor Ctx) {

+  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());

+  unsigned Line = getLineNumber(RD->getLocation());

+  StringRef RDName = getClassName(RD);

+

+  unsigned Tag = 0;

+  if (RD->isStruct() || RD->isInterface())

+    Tag = llvm::dwarf::DW_TAG_structure_type;

+  else if (RD->isUnion())

+    Tag = llvm::dwarf::DW_TAG_union_type;

+  else {

+    assert(RD->isClass());

+    Tag = llvm::dwarf::DW_TAG_class_type;

+  }

+

+  // Create the type.

+  return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line);

+}

+

+// Walk up the context chain and create forward decls for record decls,

+// and normal descriptors for namespaces.

+llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) {

+  if (!Context)

+    return TheCU;

+

+  // See if we already have the parent.

+  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator

+    I = RegionMap.find(Context);

+  if (I != RegionMap.end()) {

+    llvm::Value *V = I->second;

+    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));

+  }

+  

+  // Check namespace.

+  if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))

+    return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl));

+

+  if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) {

+    if (!RD->isDependentType()) {

+      llvm::DIType Ty = getOrCreateLimitedType(CGM.getContext().getTypeDeclType(RD),

+					       getOrCreateMainFile());

+      return llvm::DIDescriptor(Ty);

+    }

+  }

+  return TheCU;

+}

+

+/// CreatePointeeType - Create Pointee type. If Pointee is a record

+/// then emit record's fwd if debug info size reduction is enabled.

+llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy,

+                                            llvm::DIFile Unit) {

+  if (CGM.getCodeGenOpts().getDebugInfo() != CodeGenOptions::LimitedDebugInfo)

+    return getOrCreateType(PointeeTy, Unit);

+

+  // Limit debug info for the pointee type.

+

+  // If we have an existing type, use that, it's still smaller than creating

+  // a new type.

+  llvm::DIType Ty = getTypeOrNull(PointeeTy);

+  if (Ty.Verify()) return Ty;

+

+  // Handle qualifiers.

+  if (PointeeTy.hasLocalQualifiers())

+    return CreateQualifiedType(PointeeTy, Unit);

+

+  if (const RecordType *RTy = dyn_cast<RecordType>(PointeeTy)) {

+    RecordDecl *RD = RTy->getDecl();

+    llvm::DIDescriptor FDContext =

+      getContextDescriptor(cast<Decl>(RD->getDeclContext()));

+    llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext);

+    TypeCache[QualType(RTy, 0).getAsOpaquePtr()] = RetTy;

+    return RetTy;

+  }

+  return getOrCreateType(PointeeTy, Unit);

+

+}

+

+llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,

+                                                const Type *Ty, 

+                                                QualType PointeeTy,

+                                                llvm::DIFile Unit) {

+  if (Tag == llvm::dwarf::DW_TAG_reference_type ||

+      Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)

+    return DBuilder.createReferenceType(Tag,

+                                        CreatePointeeType(PointeeTy, Unit));

+                                    

+  // Bit size, align and offset of the type.

+  // Size is always the size of a pointer. We can't use getTypeSize here

+  // because that does not return the correct value for references.

+  unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);

+  uint64_t Size = CGM.getContext().getTargetInfo().getPointerWidth(AS);

+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);

+

+  return DBuilder.createPointerType(CreatePointeeType(PointeeTy, Unit),

+                                    Size, Align);

+}

+

+llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name, llvm::DIType &Cache) {

+    if (Cache.Verify())

+      return Cache;

+    Cache =

+      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

+                                 Name, TheCU, getOrCreateMainFile(),

+                                 0);

+    unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);

+    Cache = DBuilder.createPointerType(Cache, Size);

+    return Cache;

+}

+

+llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,

+                                     llvm::DIFile Unit) {

+  if (BlockLiteralGenericSet)

+    return BlockLiteralGeneric;

+

+  SmallVector<llvm::Value *, 8> EltTys;

+  llvm::DIType FieldTy;

+  QualType FType;

+  uint64_t FieldSize, FieldOffset;

+  unsigned FieldAlign;

+  llvm::DIArray Elements;

+  llvm::DIType EltTy, DescTy;

+

+  FieldOffset = 0;

+  FType = CGM.getContext().UnsignedLongTy;

+  EltTys.push_back(CreateMemberType(Unit, FType, "reserved", &FieldOffset));

+  EltTys.push_back(CreateMemberType(Unit, FType, "Size", &FieldOffset));

+

+  Elements = DBuilder.getOrCreateArray(EltTys);

+  EltTys.clear();

+

+  unsigned Flags = llvm::DIDescriptor::FlagAppleBlock;

+  unsigned LineNo = getLineNumber(CurLoc);

+

+  EltTy = DBuilder.createStructType(Unit, "__block_descriptor",

+                                    Unit, LineNo, FieldOffset, 0,

+                                    Flags, Elements);

+

+  // Bit size, align and offset of the type.

+  uint64_t Size = CGM.getContext().getTypeSize(Ty);

+

+  DescTy = DBuilder.createPointerType(EltTy, Size);

+

+  FieldOffset = 0;

+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);

+  EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));

+  FType = CGM.getContext().IntTy;

+  EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));

+  EltTys.push_back(CreateMemberType(Unit, FType, "__reserved", &FieldOffset));

+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);

+  EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset));

+

+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);

+  FieldTy = DescTy;

+  FieldSize = CGM.getContext().getTypeSize(Ty);

+  FieldAlign = CGM.getContext().getTypeAlign(Ty);

+  FieldTy = DBuilder.createMemberType(Unit, "__descriptor", Unit,

+                                      LineNo, FieldSize, FieldAlign,

+                                      FieldOffset, 0, FieldTy);

+  EltTys.push_back(FieldTy);

+

+  FieldOffset += FieldSize;

+  Elements = DBuilder.getOrCreateArray(EltTys);

+

+  EltTy = DBuilder.createStructType(Unit, "__block_literal_generic",

+                                    Unit, LineNo, FieldOffset, 0,

+                                    Flags, Elements);

+

+  BlockLiteralGenericSet = true;

+  BlockLiteralGeneric = DBuilder.createPointerType(EltTy, Size);

+  return BlockLiteralGeneric;

+}

+

+llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {

+  // Typedefs are derived from some other type.  If we have a typedef of a

+  // typedef, make sure to emit the whole chain.

+  llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);

+  if (!Src.Verify())

+    return llvm::DIType();

+  // We don't set size information, but do specify where the typedef was

+  // declared.

+  unsigned Line = getLineNumber(Ty->getDecl()->getLocation());

+  const TypedefNameDecl *TyDecl = Ty->getDecl();

+  

+  llvm::DIDescriptor TypedefContext =

+    getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext()));

+  

+  return

+    DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);

+}

+

+llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,

+                                     llvm::DIFile Unit) {

+  SmallVector<llvm::Value *, 16> EltTys;

+

+  // Add the result type at least.

+  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));

+

+  // Set up remainder of arguments if there is a prototype.

+  // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!

+  if (isa<FunctionNoProtoType>(Ty))

+    EltTys.push_back(DBuilder.createUnspecifiedParameter());

+  else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {

+    for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)

+      EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));

+  }

+

+  llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);

+  return DBuilder.createSubroutineType(Unit, EltTypeArray);

+}

+

+

+void CGDebugInfo::

+CollectRecordStaticVars(const RecordDecl *RD, llvm::DIType FwdDecl) {

+  

+  for (RecordDecl::decl_iterator I = RD->decls_begin(), E = RD->decls_end();

+       I != E; ++I)

+    if (const VarDecl *V = dyn_cast<VarDecl>(*I)) {

+      if (V->getInit()) {

+        const APValue *Value = V->evaluateValue();

+        if (Value && Value->isInt()) {

+          llvm::ConstantInt *CI

+            = llvm::ConstantInt::get(CGM.getLLVMContext(), Value->getInt());

+          

+          // Create the descriptor for static variable.

+          llvm::DIFile VUnit = getOrCreateFile(V->getLocation());

+          StringRef VName = V->getName();

+          llvm::DIType VTy = getOrCreateType(V->getType(), VUnit);

+          // Do not use DIGlobalVariable for enums.

+          if (VTy.getTag() != llvm::dwarf::DW_TAG_enumeration_type) {

+            DBuilder.createStaticVariable(FwdDecl, VName, VName, VUnit,

+                                          getLineNumber(V->getLocation()),

+                                          VTy, true, CI);

+          }

+        }

+      }

+    }

+}

+

+llvm::DIType CGDebugInfo::createFieldType(StringRef name,

+                                          QualType type,

+                                          uint64_t sizeInBitsOverride,

+                                          SourceLocation loc,

+                                          AccessSpecifier AS,

+                                          uint64_t offsetInBits,

+                                          llvm::DIFile tunit,

+                                          llvm::DIDescriptor scope) {

+  llvm::DIType debugType = getOrCreateType(type, tunit);

+

+  // Get the location for the field.

+  llvm::DIFile file = getOrCreateFile(loc);

+  unsigned line = getLineNumber(loc);

+

+  uint64_t sizeInBits = 0;

+  unsigned alignInBits = 0;

+  if (!type->isIncompleteArrayType()) {

+    llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);

+

+    if (sizeInBitsOverride)

+      sizeInBits = sizeInBitsOverride;

+  }

+

+  unsigned flags = 0;

+  if (AS == clang::AS_private)

+    flags |= llvm::DIDescriptor::FlagPrivate;

+  else if (AS == clang::AS_protected)

+    flags |= llvm::DIDescriptor::FlagProtected;

+

+  return DBuilder.createMemberType(scope, name, file, line, sizeInBits,

+                                   alignInBits, offsetInBits, flags, debugType);

+}

+

+/// CollectRecordFields - A helper function to collect debug info for

+/// record fields. This is used while creating debug info entry for a Record.

+void CGDebugInfo::

+CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,

+                    SmallVectorImpl<llvm::Value *> &elements,

+                    llvm::DIType RecordTy) {

+  unsigned fieldNo = 0;

+  const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);

+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(record);

+

+  // For C++11 Lambdas a Field will be the same as a Capture, but the Capture

+  // has the name and the location of the variable so we should iterate over

+  // both concurrently.

+  if (CXXDecl && CXXDecl->isLambda()) {

+    RecordDecl::field_iterator Field = CXXDecl->field_begin();

+    unsigned fieldno = 0;

+    for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),

+           E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) {

+      const LambdaExpr::Capture C = *I;

+      if (C.capturesVariable()) {

+        VarDecl *V = C.getCapturedVar();

+        llvm::DIFile VUnit = getOrCreateFile(C.getLocation());

+        StringRef VName = V->getName();

+        uint64_t SizeInBitsOverride = 0;

+        if (Field->isBitField()) {

+          SizeInBitsOverride = Field->getBitWidthValue(CGM.getContext());

+          assert(SizeInBitsOverride && "found named 0-width bitfield");

+        }

+        llvm::DIType fieldType

+          = createFieldType(VName, Field->getType(), SizeInBitsOverride, C.getLocation(),

+                            Field->getAccess(), layout.getFieldOffset(fieldno),

+                            VUnit, RecordTy);

+        elements.push_back(fieldType);

+      } else {

+        // TODO: Need to handle 'this' in some way by probably renaming the

+        // this of the lambda class and having a field member of 'this' or

+        // by using AT_object_pointer for the function and having that be

+        // used as 'this' for semantic references.

+        assert(C.capturesThis() && "Field that isn't captured and isn't this?");

+        FieldDecl *f = *Field;

+        llvm::DIFile VUnit = getOrCreateFile(f->getLocation());

+        QualType type = f->getType();

+        llvm::DIType fieldType

+          = createFieldType("this", type, 0, f->getLocation(), f->getAccess(),

+                            layout.getFieldOffset(fieldNo), VUnit, RecordTy);

+

+        elements.push_back(fieldType);

+      }

+    }

+  } else {

+    bool IsMsStruct = record->isMsStruct(CGM.getContext());

+    const FieldDecl *LastFD = 0;

+    for (RecordDecl::field_iterator I = record->field_begin(),

+           E = record->field_end();

+         I != E; ++I, ++fieldNo) {

+      FieldDecl *field = *I;

+

+      if (IsMsStruct) {

+        // Zero-length bitfields following non-bitfield members are ignored

+        if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) {

+          --fieldNo;

+          continue;

+        }

+        LastFD = field;

+      }

+

+      StringRef name = field->getName();

+      QualType type = field->getType();

+

+      // Ignore unnamed fields unless they're anonymous structs/unions.

+      if (name.empty() && !type->isRecordType()) {

+        LastFD = field;

+        continue;

+      }

+

+      uint64_t SizeInBitsOverride = 0;

+      if (field->isBitField()) {

+        SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());

+        assert(SizeInBitsOverride && "found named 0-width bitfield");

+      }

+

+      llvm::DIType fieldType

+        = createFieldType(name, type, SizeInBitsOverride,

+                          field->getLocation(), field->getAccess(),

+                          layout.getFieldOffset(fieldNo), tunit, RecordTy);

+

+      elements.push_back(fieldType);

+    }

+  }

+}

+

+/// getOrCreateMethodType - CXXMethodDecl's type is a FunctionType. This

+/// function type is not updated to include implicit "this" pointer. Use this

+/// routine to get a method type which includes "this" pointer.

+llvm::DIType

+CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,

+                                   llvm::DIFile Unit) {

+  llvm::DIType FnTy

+    = getOrCreateType(QualType(Method->getType()->getAs<FunctionProtoType>(),

+                               0),

+                      Unit);

+

+  // Add "this" pointer.

+  llvm::DIArray Args = llvm::DICompositeType(FnTy).getTypeArray();

+  assert (Args.getNumElements() && "Invalid number of arguments!");

+

+  SmallVector<llvm::Value *, 16> Elts;

+

+  // First element is always return type. For 'void' functions it is NULL.

+  Elts.push_back(Args.getElement(0));

+

+  if (!Method->isStatic()) {

+    // "this" pointer is always first argument.

+    QualType ThisPtr = Method->getThisType(CGM.getContext());

+

+    const CXXRecordDecl *RD = Method->getParent();

+    if (isa<ClassTemplateSpecializationDecl>(RD)) {

+      // Create pointer type directly in this case.

+      const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);

+      QualType PointeeTy = ThisPtrTy->getPointeeType();

+      unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);

+      uint64_t Size = CGM.getContext().getTargetInfo().getPointerWidth(AS);

+      uint64_t Align = CGM.getContext().getTypeAlign(ThisPtrTy);

+      llvm::DIType PointeeType = getOrCreateType(PointeeTy, Unit);

+      llvm::DIType ThisPtrType = DBuilder.createPointerType(PointeeType, Size, Align);

+      TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;

+      // TODO: This and the artificial type below are misleading, the

+      // types aren't artificial the argument is, but the current

+      // metadata doesn't represent that.

+      ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);

+      Elts.push_back(ThisPtrType);

+    } else {

+      llvm::DIType ThisPtrType = getOrCreateType(ThisPtr, Unit);

+      TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;

+      ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);

+      Elts.push_back(ThisPtrType);

+    }

+  }

+

+  // Copy rest of the arguments.

+  for (unsigned i = 1, e = Args.getNumElements(); i != e; ++i)

+    Elts.push_back(Args.getElement(i));

+

+  llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);

+

+  return DBuilder.createSubroutineType(Unit, EltTypeArray);

+}

+

+/// isFunctionLocalClass - Return true if CXXRecordDecl is defined 

+/// inside a function.

+static bool isFunctionLocalClass(const CXXRecordDecl *RD) {

+  if (const CXXRecordDecl *NRD = dyn_cast<CXXRecordDecl>(RD->getDeclContext()))

+    return isFunctionLocalClass(NRD);

+  if (isa<FunctionDecl>(RD->getDeclContext()))

+    return true;

+  return false;

+}

+

+/// CreateCXXMemberFunction - A helper function to create a DISubprogram for

+/// a single member function GlobalDecl.

+llvm::DISubprogram

+CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,

+                                     llvm::DIFile Unit,

+                                     llvm::DIType RecordTy) {

+  bool IsCtorOrDtor = 

+    isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);

+  

+  StringRef MethodName = getFunctionName(Method);

+  llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);

+

+  // Since a single ctor/dtor corresponds to multiple functions, it doesn't

+  // make sense to give a single ctor/dtor a linkage name.

+  StringRef MethodLinkageName;

+  if (!IsCtorOrDtor && !isFunctionLocalClass(Method->getParent()))

+    MethodLinkageName = CGM.getMangledName(Method);

+

+  // Get the location for the method.

+  llvm::DIFile MethodDefUnit = getOrCreateFile(Method->getLocation());

+  unsigned MethodLine = getLineNumber(Method->getLocation());

+

+  // Collect virtual method info.

+  llvm::DIType ContainingType;

+  unsigned Virtuality = 0; 

+  unsigned VIndex = 0;

+  

+  if (Method->isVirtual()) {

+    if (Method->isPure())

+      Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;

+    else

+      Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual;

+    

+    // It doesn't make sense to give a virtual destructor a vtable index,

+    // since a single destructor has two entries in the vtable.

+    if (!isa<CXXDestructorDecl>(Method))

+      VIndex = CGM.getVTableContext().getMethodVTableIndex(Method);

+    ContainingType = RecordTy;

+  }

+

+  unsigned Flags = 0;

+  if (Method->isImplicit())

+    Flags |= llvm::DIDescriptor::FlagArtificial;

+  AccessSpecifier Access = Method->getAccess();

+  if (Access == clang::AS_private)

+    Flags |= llvm::DIDescriptor::FlagPrivate;

+  else if (Access == clang::AS_protected)

+    Flags |= llvm::DIDescriptor::FlagProtected;

+  if (const CXXConstructorDecl *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {

+    if (CXXC->isExplicit())

+      Flags |= llvm::DIDescriptor::FlagExplicit;

+  } else if (const CXXConversionDecl *CXXC = 

+             dyn_cast<CXXConversionDecl>(Method)) {

+    if (CXXC->isExplicit())

+      Flags |= llvm::DIDescriptor::FlagExplicit;

+  }

+  if (Method->hasPrototype())

+    Flags |= llvm::DIDescriptor::FlagPrototyped;

+

+  llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);

+  llvm::DISubprogram SP =

+    DBuilder.createMethod(RecordTy, MethodName, MethodLinkageName, 

+                          MethodDefUnit, MethodLine,

+                          MethodTy, /*isLocalToUnit=*/false, 

+                          /* isDefinition=*/ false,

+                          Virtuality, VIndex, ContainingType,

+                          Flags, CGM.getLangOpts().Optimize, NULL,

+                          TParamsArray);

+  

+  SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP);

+

+  return SP;

+}

+

+/// CollectCXXMemberFunctions - A helper function to collect debug info for

+/// C++ member functions. This is used while creating debug info entry for 

+/// a Record.

+void CGDebugInfo::

+CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,

+                          SmallVectorImpl<llvm::Value *> &EltTys,

+                          llvm::DIType RecordTy) {

+

+  // Since we want more than just the individual member decls if we

+  // have templated functions iterate over every declaration to gather

+  // the functions.

+  for(DeclContext::decl_iterator I = RD->decls_begin(),

+        E = RD->decls_end(); I != E; ++I) {

+    Decl *D = *I;

+    if (D->isImplicit() && !D->isUsed())

+      continue;

+

+    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))

+      EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));

+    else if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))

+      for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(),

+             SE = FTD->spec_end(); SI != SE; ++SI)

+        EltTys.push_back(CreateCXXMemberFunction(cast<CXXMethodDecl>(*SI), Unit,

+                                                 RecordTy));

+  }

+}                                 

+

+/// CollectCXXFriends - A helper function to collect debug info for

+/// C++ base classes. This is used while creating debug info entry for

+/// a Record.

+void CGDebugInfo::

+CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit,

+                SmallVectorImpl<llvm::Value *> &EltTys,

+                llvm::DIType RecordTy) {

+  for (CXXRecordDecl::friend_iterator BI = RD->friend_begin(),

+         BE = RD->friend_end(); BI != BE; ++BI) {

+    if ((*BI)->isUnsupportedFriend())

+      continue;

+    if (TypeSourceInfo *TInfo = (*BI)->getFriendType())

+      EltTys.push_back(DBuilder.createFriend(RecordTy, 

+                                             getOrCreateType(TInfo->getType(), 

+                                                             Unit)));

+  }

+}

+

+/// CollectCXXBases - A helper function to collect debug info for

+/// C++ base classes. This is used while creating debug info entry for 

+/// a Record.

+void CGDebugInfo::

+CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,

+                SmallVectorImpl<llvm::Value *> &EltTys,

+                llvm::DIType RecordTy) {

+

+  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);

+  for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),

+         BE = RD->bases_end(); BI != BE; ++BI) {

+    unsigned BFlags = 0;

+    uint64_t BaseOffset;

+    

+    const CXXRecordDecl *Base =

+      cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl());

+    

+    if (BI->isVirtual()) {

+      // virtual base offset offset is -ve. The code generator emits dwarf

+      // expression where it expects +ve number.

+      BaseOffset = 

+        0 - CGM.getVTableContext()

+               .getVirtualBaseOffsetOffset(RD, Base).getQuantity();

+      BFlags = llvm::DIDescriptor::FlagVirtual;

+    } else

+      BaseOffset = CGM.getContext().toBits(RL.getBaseClassOffset(Base));

+    // FIXME: Inconsistent units for BaseOffset. It is in bytes when

+    // BI->isVirtual() and bits when not.

+    

+    AccessSpecifier Access = BI->getAccessSpecifier();

+    if (Access == clang::AS_private)

+      BFlags |= llvm::DIDescriptor::FlagPrivate;

+    else if (Access == clang::AS_protected)

+      BFlags |= llvm::DIDescriptor::FlagProtected;

+    

+    llvm::DIType DTy = 

+      DBuilder.createInheritance(RecordTy,                                     

+                                 getOrCreateType(BI->getType(), Unit),

+                                 BaseOffset, BFlags);

+    EltTys.push_back(DTy);

+  }

+}

+

+/// CollectTemplateParams - A helper function to collect template parameters.

+llvm::DIArray CGDebugInfo::

+CollectTemplateParams(const TemplateParameterList *TPList,

+                      const TemplateArgumentList &TAList,

+                      llvm::DIFile Unit) {

+  SmallVector<llvm::Value *, 16> TemplateParams;  

+  for (unsigned i = 0, e = TAList.size(); i != e; ++i) {

+    const TemplateArgument &TA = TAList[i];

+    const NamedDecl *ND = TPList->getParam(i);

+    if (TA.getKind() == TemplateArgument::Type) {

+      llvm::DIType TTy = getOrCreateType(TA.getAsType(), Unit);

+      llvm::DITemplateTypeParameter TTP =

+        DBuilder.createTemplateTypeParameter(TheCU, ND->getName(), TTy);

+      TemplateParams.push_back(TTP);

+    } else if (TA.getKind() == TemplateArgument::Integral) {

+      llvm::DIType TTy = getOrCreateType(TA.getIntegralType(), Unit);

+      llvm::DITemplateValueParameter TVP =

+        DBuilder.createTemplateValueParameter(TheCU, ND->getName(), TTy,

+                                             TA.getAsIntegral().getZExtValue());

+      TemplateParams.push_back(TVP);          

+    }

+  }

+  return DBuilder.getOrCreateArray(TemplateParams);

+}

+

+/// CollectFunctionTemplateParams - A helper function to collect debug

+/// info for function template parameters.

+llvm::DIArray CGDebugInfo::

+CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit) {

+  if (FD->getTemplatedKind() ==

+      FunctionDecl::TK_FunctionTemplateSpecialization) {

+    const TemplateParameterList *TList =

+      FD->getTemplateSpecializationInfo()->getTemplate()

+      ->getTemplateParameters();

+    return 

+      CollectTemplateParams(TList, *FD->getTemplateSpecializationArgs(), Unit);

+  }

+  return llvm::DIArray();

+}

+

+/// CollectCXXTemplateParams - A helper function to collect debug info for

+/// template parameters.

+llvm::DIArray CGDebugInfo::

+CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,

+                         llvm::DIFile Unit) {

+  llvm::PointerUnion<ClassTemplateDecl *,

+                     ClassTemplatePartialSpecializationDecl *>

+    PU = TSpecial->getSpecializedTemplateOrPartial();

+  

+  TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?

+    PU.get<ClassTemplateDecl *>()->getTemplateParameters() :

+    PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();

+  const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();

+  return CollectTemplateParams(TPList, TAList, Unit);

+}

+

+/// getOrCreateVTablePtrType - Return debug info descriptor for vtable.

+llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) {

+  if (VTablePtrType.isValid())

+    return VTablePtrType;

+

+  ASTContext &Context = CGM.getContext();

+

+  /* Function type */

+  llvm::Value *STy = getOrCreateType(Context.IntTy, Unit);

+  llvm::DIArray SElements = DBuilder.getOrCreateArray(STy);

+  llvm::DIType SubTy = DBuilder.createSubroutineType(Unit, SElements);

+  unsigned Size = Context.getTypeSize(Context.VoidPtrTy);

+  llvm::DIType vtbl_ptr_type = DBuilder.createPointerType(SubTy, Size, 0,

+                                                          "__vtbl_ptr_type");

+  VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);

+  return VTablePtrType;

+}

+

+/// getVTableName - Get vtable name for the given Class.

+StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {

+  // Construct gdb compatible name name.

+  std::string Name = "_vptr$" + RD->getNameAsString();

+

+  // Copy this name on the side and use its reference.

+  char *StrPtr = DebugInfoNames.Allocate<char>(Name.length());

+  memcpy(StrPtr, Name.data(), Name.length());

+  return StringRef(StrPtr, Name.length());

+}

+

+

+/// CollectVTableInfo - If the C++ class has vtable info then insert appropriate

+/// debug info entry in EltTys vector.

+void CGDebugInfo::

+CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit,

+                  SmallVectorImpl<llvm::Value *> &EltTys) {

+  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);

+

+  // If there is a primary base then it will hold vtable info.

+  if (RL.getPrimaryBase())

+    return;

+

+  // If this class is not dynamic then there is not any vtable info to collect.

+  if (!RD->isDynamicClass())

+    return;

+

+  unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);

+  llvm::DIType VPTR

+    = DBuilder.createMemberType(Unit, getVTableName(RD), Unit,

+                                0, Size, 0, 0, llvm::DIDescriptor::FlagArtificial,

+                                getOrCreateVTablePtrType(Unit));

+  EltTys.push_back(VPTR);

+}

+

+/// getOrCreateRecordType - Emit record type's standalone debug info. 

+llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy, 

+                                                SourceLocation Loc) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  llvm::DIType T = getOrCreateType(RTy, getOrCreateFile(Loc));

+  return T;

+}

+

+/// getOrCreateInterfaceType - Emit an objective c interface type standalone

+/// debug info.

+llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D,

+						   SourceLocation Loc) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  llvm::DIType T = getOrCreateType(D, getOrCreateFile(Loc));

+  DBuilder.retainType(T);

+  return T;

+}

+

+/// CreateType - get structure or union type.

+llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {

+  RecordDecl *RD = Ty->getDecl();

+

+  // Get overall information about the record type for the debug info.

+  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());

+

+  // Records and classes and unions can all be recursive.  To handle them, we

+  // first generate a debug descriptor for the struct as a forward declaration.

+  // Then (if it is a definition) we go through and get debug info for all of

+  // its members.  Finally, we create a descriptor for the complete type (which

+  // may refer to the forward decl if the struct is recursive) and replace all

+  // uses of the forward declaration with the final definition.

+

+  llvm::DIType FwdDecl = getOrCreateLimitedType(QualType(Ty, 0), DefUnit);

+

+  if (FwdDecl.isForwardDecl())

+    return FwdDecl;

+

+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode(FwdDecl);

+

+  // Push the struct on region stack.

+  LexicalBlockStack.push_back(FwdDeclNode);

+  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);

+

+  // Add this to the completed types cache since we're completing it.

+  CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;

+

+  // Convert all the elements.

+  SmallVector<llvm::Value *, 16> EltTys;

+

+  // Note: The split of CXXDecl information here is intentional, the

+  // gdb tests will depend on a certain ordering at printout. The debug

+  // information offsets are still correct if we merge them all together

+  // though.

+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);

+  if (CXXDecl) {

+    CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);

+    CollectVTableInfo(CXXDecl, DefUnit, EltTys);

+  }

+

+  // Collect static variables with initializers and other fields.

+  CollectRecordStaticVars(RD, FwdDecl);

+  CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);

+  llvm::DIArray TParamsArray;

+  if (CXXDecl) {

+    CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);

+    CollectCXXFriends(CXXDecl, DefUnit, EltTys, FwdDecl);

+    if (const ClassTemplateSpecializationDecl *TSpecial

+        = dyn_cast<ClassTemplateSpecializationDecl>(RD))

+      TParamsArray = CollectCXXTemplateParams(TSpecial, DefUnit);

+  }

+

+  LexicalBlockStack.pop_back();

+  RegionMap.erase(Ty->getDecl());

+

+  llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);

+  // FIXME: Magic numbers ahoy! These should be changed when we

+  // get some enums in llvm/Analysis/DebugInfo.h to refer to

+  // them.

+  if (RD->isUnion())

+    FwdDeclNode->replaceOperandWith(10, Elements);

+  else if (CXXDecl) {

+    FwdDeclNode->replaceOperandWith(10, Elements);

+    FwdDeclNode->replaceOperandWith(13, TParamsArray);

+  } else

+    FwdDeclNode->replaceOperandWith(10, Elements);

+

+  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDeclNode);

+  return llvm::DIType(FwdDeclNode);

+}

+

+/// CreateType - get objective-c object type.

+llvm::DIType CGDebugInfo::CreateType(const ObjCObjectType *Ty,

+                                     llvm::DIFile Unit) {

+  // Ignore protocols.

+  return getOrCreateType(Ty->getBaseType(), Unit);

+}

+

+/// CreateType - get objective-c interface type.

+llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,

+                                     llvm::DIFile Unit) {

+  ObjCInterfaceDecl *ID = Ty->getDecl();

+  if (!ID)

+    return llvm::DIType();

+

+  // Get overall information about the record type for the debug info.

+  llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());

+  unsigned Line = getLineNumber(ID->getLocation());

+  unsigned RuntimeLang = TheCU.getLanguage();

+

+  // If this is just a forward declaration return a special forward-declaration

+  // debug type since we won't be able to lay out the entire type.

+  ObjCInterfaceDecl *Def = ID->getDefinition();

+  if (!Def) {

+    llvm::DIType FwdDecl =

+      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,

+				 ID->getName(), TheCU, DefUnit, Line,

+				 RuntimeLang);

+    return FwdDecl;

+  }

+

+  ID = Def;

+

+  // Bit size, align and offset of the type.

+  uint64_t Size = CGM.getContext().getTypeSize(Ty);

+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);

+

+  unsigned Flags = 0;

+  if (ID->getImplementation())

+    Flags |= llvm::DIDescriptor::FlagObjcClassComplete;

+

+  llvm::DIType RealDecl =

+    DBuilder.createStructType(Unit, ID->getName(), DefUnit,

+                              Line, Size, Align, Flags,

+                              llvm::DIArray(), RuntimeLang);

+

+  // Otherwise, insert it into the CompletedTypeCache so that recursive uses

+  // will find it and we're emitting the complete type.

+  CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;

+  // Push the struct on region stack.

+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode(RealDecl);

+

+  LexicalBlockStack.push_back(FwdDeclNode);

+  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);

+

+  // Convert all the elements.

+  SmallVector<llvm::Value *, 16> EltTys;

+

+  ObjCInterfaceDecl *SClass = ID->getSuperClass();

+  if (SClass) {

+    llvm::DIType SClassTy =

+      getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);

+    if (!SClassTy.isValid())

+      return llvm::DIType();

+    

+    llvm::DIType InhTag =

+      DBuilder.createInheritance(RealDecl, SClassTy, 0, 0);

+    EltTys.push_back(InhTag);

+  }

+

+  for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(),

+         E = ID->prop_end(); I != E; ++I) {

+    const ObjCPropertyDecl *PD = *I;

+    SourceLocation Loc = PD->getLocation();

+    llvm::DIFile PUnit = getOrCreateFile(Loc);

+    unsigned PLine = getLineNumber(Loc);

+    ObjCMethodDecl *Getter = PD->getGetterMethodDecl();

+    ObjCMethodDecl *Setter = PD->getSetterMethodDecl();

+    llvm::MDNode *PropertyNode =

+      DBuilder.createObjCProperty(PD->getName(),

+				  PUnit, PLine,

+                                  (Getter && Getter->isImplicit()) ? "" :

+                                  getSelectorName(PD->getGetterName()),

+                                  (Setter && Setter->isImplicit()) ? "" :

+                                  getSelectorName(PD->getSetterName()),

+                                  PD->getPropertyAttributes(),

+				  getOrCreateType(PD->getType(), PUnit));

+    EltTys.push_back(PropertyNode);

+  }

+

+  const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);

+  unsigned FieldNo = 0;

+  for (ObjCIvarDecl *Field = ID->all_declared_ivar_begin(); Field;

+       Field = Field->getNextIvar(), ++FieldNo) {

+    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);

+    if (!FieldTy.isValid())

+      return llvm::DIType();

+    

+    StringRef FieldName = Field->getName();

+

+    // Ignore unnamed fields.

+    if (FieldName.empty())

+      continue;

+

+    // Get the location for the field.

+    llvm::DIFile FieldDefUnit = getOrCreateFile(Field->getLocation());

+    unsigned FieldLine = getLineNumber(Field->getLocation());

+    QualType FType = Field->getType();

+    uint64_t FieldSize = 0;

+    unsigned FieldAlign = 0;

+

+    if (!FType->isIncompleteArrayType()) {

+

+      // Bit size, align and offset of the type.

+      FieldSize = Field->isBitField()

+        ? Field->getBitWidthValue(CGM.getContext())

+        : CGM.getContext().getTypeSize(FType);

+      FieldAlign = CGM.getContext().getTypeAlign(FType);

+    }

+

+    uint64_t FieldOffset;

+    if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {

+      // We don't know the runtime offset of an ivar if we're using the

+      // non-fragile ABI.  For bitfields, use the bit offset into the first

+      // byte of storage of the bitfield.  For other fields, use zero.

+      if (Field->isBitField()) {

+        FieldOffset = CGM.getObjCRuntime().ComputeBitfieldBitOffset(

+            CGM, ID, Field);

+        FieldOffset %= CGM.getContext().getCharWidth();

+      } else {

+        FieldOffset = 0;

+      }

+    } else {

+      FieldOffset = RL.getFieldOffset(FieldNo);

+    }

+

+    unsigned Flags = 0;

+    if (Field->getAccessControl() == ObjCIvarDecl::Protected)

+      Flags = llvm::DIDescriptor::FlagProtected;

+    else if (Field->getAccessControl() == ObjCIvarDecl::Private)

+      Flags = llvm::DIDescriptor::FlagPrivate;

+

+    llvm::MDNode *PropertyNode = NULL;

+    if (ObjCImplementationDecl *ImpD = ID->getImplementation()) {

+      if (ObjCPropertyImplDecl *PImpD = 

+          ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {

+        if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {

+	  SourceLocation Loc = PD->getLocation();

+	  llvm::DIFile PUnit = getOrCreateFile(Loc);

+	  unsigned PLine = getLineNumber(Loc);

+          ObjCMethodDecl *Getter = PD->getGetterMethodDecl();

+          ObjCMethodDecl *Setter = PD->getSetterMethodDecl();

+          PropertyNode =

+            DBuilder.createObjCProperty(PD->getName(),

+                                        PUnit, PLine,

+                                        (Getter && Getter->isImplicit()) ? "" :

+                                        getSelectorName(PD->getGetterName()),

+                                        (Setter && Setter->isImplicit()) ? "" :

+                                        getSelectorName(PD->getSetterName()),

+                                        PD->getPropertyAttributes(),

+                                        getOrCreateType(PD->getType(), PUnit));

+        }

+      }

+    }

+    FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit,

+                                      FieldLine, FieldSize, FieldAlign,

+                                      FieldOffset, Flags, FieldTy,

+                                      PropertyNode);

+    EltTys.push_back(FieldTy);

+  }

+

+  llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);

+  FwdDeclNode->replaceOperandWith(10, Elements);

+  

+  LexicalBlockStack.pop_back();

+  return llvm::DIType(FwdDeclNode);

+}

+

+llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) {

+  llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);

+  int64_t Count = Ty->getNumElements();

+  if (Count == 0)

+    // If number of elements are not known then this is an unbounded array.

+    // Use Count == -1 to express such arrays.

+    Count = -1;

+

+  llvm::Value *Subscript = DBuilder.getOrCreateSubrange(0, Count);

+  llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);

+

+  uint64_t Size = CGM.getContext().getTypeSize(Ty);

+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);

+

+  return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);

+}

+

+llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,

+                                     llvm::DIFile Unit) {

+  uint64_t Size;

+  uint64_t Align;

+

+  // FIXME: make getTypeAlign() aware of VLAs and incomplete array types

+  if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) {

+    Size = 0;

+    Align =

+      CGM.getContext().getTypeAlign(CGM.getContext().getBaseElementType(VAT));

+  } else if (Ty->isIncompleteArrayType()) {

+    Size = 0;

+    if (Ty->getElementType()->isIncompleteType())

+      Align = 0;

+    else

+      Align = CGM.getContext().getTypeAlign(Ty->getElementType());

+  } else if (Ty->isDependentSizedArrayType() || Ty->isIncompleteType()) {

+    Size = 0;

+    Align = 0;

+  } else {

+    // Size and align of the whole array, not the element type.

+    Size = CGM.getContext().getTypeSize(Ty);

+    Align = CGM.getContext().getTypeAlign(Ty);

+  }

+

+  // Add the dimensions of the array.  FIXME: This loses CV qualifiers from

+  // interior arrays, do we care?  Why aren't nested arrays represented the

+  // obvious/recursive way?

+  SmallVector<llvm::Value *, 8> Subscripts;

+  QualType EltTy(Ty, 0);

+  while ((Ty = dyn_cast<ArrayType>(EltTy))) {

+    // If the number of elements is known, then count is that number. Otherwise,

+    // it's -1. This allows us to represent a subrange with an array of 0

+    // elements, like this:

+    //

+    //   struct foo {

+    //     int x[0];

+    //   };

+    int64_t Count = -1;         // Count == -1 is an unbounded array.

+    if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))

+      Count = CAT->getSize().getZExtValue();

+    

+    // FIXME: Verify this is right for VLAs.

+    Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));

+    EltTy = Ty->getElementType();

+  }

+

+  llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts);

+

+  llvm::DIType DbgTy = 

+    DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),

+                             SubscriptArray);

+  return DbgTy;

+}

+

+llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty, 

+                                     llvm::DIFile Unit) {

+  return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, 

+                               Ty, Ty->getPointeeType(), Unit);

+}

+

+llvm::DIType CGDebugInfo::CreateType(const RValueReferenceType *Ty, 

+                                     llvm::DIFile Unit) {

+  return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type, 

+                               Ty, Ty->getPointeeType(), Unit);

+}

+

+llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, 

+                                     llvm::DIFile U) {

+  QualType PointerDiffTy = CGM.getContext().getPointerDiffType();

+  llvm::DIType PointerDiffDITy = getOrCreateType(PointerDiffTy, U);

+  

+  if (!Ty->getPointeeType()->isFunctionType()) {

+    // We have a data member pointer type.

+    return PointerDiffDITy;

+  }

+  

+  // We have a member function pointer type. Treat it as a struct with two

+  // ptrdiff_t members.

+  std::pair<uint64_t, unsigned> Info = CGM.getContext().getTypeInfo(Ty);

+

+  uint64_t FieldOffset = 0;

+  llvm::Value *ElementTypes[2];

+  

+  // FIXME: This should be a DW_TAG_pointer_to_member type.

+  ElementTypes[0] =

+    DBuilder.createMemberType(U, "ptr", U, 0,

+                              Info.first, Info.second, FieldOffset, 0,

+                              PointerDiffDITy);

+  FieldOffset += Info.first;

+  

+  ElementTypes[1] =

+    DBuilder.createMemberType(U, "ptr", U, 0,

+                              Info.first, Info.second, FieldOffset, 0,

+                              PointerDiffDITy);

+  

+  llvm::DIArray Elements = DBuilder.getOrCreateArray(ElementTypes);

+

+  return DBuilder.createStructType(U, StringRef("test"), 

+                                   U, 0, FieldOffset, 

+                                   0, 0, Elements);

+}

+

+llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty, 

+                                     llvm::DIFile U) {

+  // Ignore the atomic wrapping

+  // FIXME: What is the correct representation?

+  return getOrCreateType(Ty->getValueType(), U);

+}

+

+/// CreateEnumType - get enumeration type.

+llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {

+  uint64_t Size = 0;

+  uint64_t Align = 0;

+  if (!ED->getTypeForDecl()->isIncompleteType()) {

+    Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());

+    Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());

+  }

+

+  // If this is just a forward declaration, construct an appropriately

+  // marked node and just return it.

+  if (!ED->getDefinition()) {

+    llvm::DIDescriptor EDContext;

+    EDContext = getContextDescriptor(cast<Decl>(ED->getDeclContext()));

+    llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());

+    unsigned Line = getLineNumber(ED->getLocation());

+    StringRef EDName = ED->getName();

+    return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type,

+                                      EDName, EDContext, DefUnit, Line, 0,

+                                      Size, Align);

+  }

+

+  // Create DIEnumerator elements for each enumerator.

+  SmallVector<llvm::Value *, 16> Enumerators;

+  ED = ED->getDefinition();

+  for (EnumDecl::enumerator_iterator

+         Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end();

+       Enum != EnumEnd; ++Enum) {

+    Enumerators.push_back(

+      DBuilder.createEnumerator(Enum->getName(),

+                                Enum->getInitVal().getZExtValue()));

+  }

+

+  // Return a CompositeType for the enum itself.

+  llvm::DIArray EltArray = DBuilder.getOrCreateArray(Enumerators);

+

+  llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());

+  unsigned Line = getLineNumber(ED->getLocation());

+  llvm::DIDescriptor EnumContext = 

+    getContextDescriptor(cast<Decl>(ED->getDeclContext()));

+  llvm::DIType ClassTy = ED->isScopedUsingClassTag() ?

+    getOrCreateType(ED->getIntegerType(), DefUnit) : llvm::DIType();

+  llvm::DIType DbgTy = 

+    DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, Line,

+                                   Size, Align, EltArray,

+                                   ClassTy);

+  return DbgTy;

+}

+

+static QualType UnwrapTypeForDebugInfo(QualType T) {

+  do {

+    QualType LastT = T;

+    switch (T->getTypeClass()) {

+    default:

+      return T;

+    case Type::TemplateSpecialization:

+      T = cast<TemplateSpecializationType>(T)->desugar();

+      break;

+    case Type::TypeOfExpr:

+      T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();

+      break;

+    case Type::TypeOf:

+      T = cast<TypeOfType>(T)->getUnderlyingType();

+      break;

+    case Type::Decltype:

+      T = cast<DecltypeType>(T)->getUnderlyingType();

+      break;

+    case Type::UnaryTransform:

+      T = cast<UnaryTransformType>(T)->getUnderlyingType();

+      break;

+    case Type::Attributed:

+      T = cast<AttributedType>(T)->getEquivalentType();

+      break;

+    case Type::Elaborated:

+      T = cast<ElaboratedType>(T)->getNamedType();

+      break;

+    case Type::Paren:

+      T = cast<ParenType>(T)->getInnerType();

+      break;

+    case Type::SubstTemplateTypeParm: {

+      // We need to keep the qualifiers handy since getReplacementType()

+      // will strip them away.

+      unsigned Quals = T.getLocalFastQualifiers();

+      T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();

+      T.addFastQualifiers(Quals);

+    }

+      break;

+    case Type::Auto:

+      T = cast<AutoType>(T)->getDeducedType();

+      break;

+    }

+    

+    assert(T != LastT && "Type unwrapping failed to unwrap!");

+    if (T == LastT)

+      return T;

+  } while (true);

+}

+

+/// getType - Get the type from the cache or return null type if it doesn't exist.

+llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {

+

+  // Unwrap the type as needed for debug information.

+  Ty = UnwrapTypeForDebugInfo(Ty);

+  

+  // Check for existing entry.

+  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =

+    TypeCache.find(Ty.getAsOpaquePtr());

+  if (it != TypeCache.end()) {

+    // Verify that the debug info still exists.

+    if (llvm::Value *V = it->second)

+      return llvm::DIType(cast<llvm::MDNode>(V));

+  }

+

+  return llvm::DIType();

+}

+

+/// getCompletedTypeOrNull - Get the type from the cache or return null if it

+/// doesn't exist.

+llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {

+

+  // Unwrap the type as needed for debug information.

+  Ty = UnwrapTypeForDebugInfo(Ty);

+

+  // Check for existing entry.

+  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =

+    CompletedTypeCache.find(Ty.getAsOpaquePtr());

+  if (it != CompletedTypeCache.end()) {

+    // Verify that the debug info still exists.

+    if (llvm::Value *V = it->second)

+      return llvm::DIType(cast<llvm::MDNode>(V));

+  }

+

+  return llvm::DIType();

+}

+

+

+/// getOrCreateType - Get the type from the cache or create a new

+/// one if necessary.

+llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {

+  if (Ty.isNull())

+    return llvm::DIType();

+

+  // Unwrap the type as needed for debug information.

+  Ty = UnwrapTypeForDebugInfo(Ty);

+

+  llvm::DIType T = getCompletedTypeOrNull(Ty);

+

+  if (T.Verify())

+    return T;

+

+  // Otherwise create the type.

+  llvm::DIType Res = CreateTypeNode(Ty, Unit);

+

+  llvm::DIType TC = getTypeOrNull(Ty);

+  if (TC.Verify() && TC.isForwardDecl())

+    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(),

+                                        static_cast<llvm::Value*>(TC)));

+  

+  // And update the type cache.

+  TypeCache[Ty.getAsOpaquePtr()] = Res;

+

+  if (!Res.isForwardDecl())

+    CompletedTypeCache[Ty.getAsOpaquePtr()] = Res;

+

+  return Res;

+}

+

+/// CreateTypeNode - Create a new debug type node.

+llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {

+  // Handle qualifiers, which recursively handles what they refer to.

+  if (Ty.hasLocalQualifiers())

+    return CreateQualifiedType(Ty, Unit);

+

+  const char *Diag = 0;

+  

+  // Work out details of type.

+  switch (Ty->getTypeClass()) {

+#define TYPE(Class, Base)

+#define ABSTRACT_TYPE(Class, Base)

+#define NON_CANONICAL_TYPE(Class, Base)

+#define DEPENDENT_TYPE(Class, Base) case Type::Class:

+#include "clang/AST/TypeNodes.def"

+    llvm_unreachable("Dependent types cannot show up in debug information");

+

+  case Type::ExtVector:

+  case Type::Vector:

+    return CreateType(cast<VectorType>(Ty), Unit);

+  case Type::ObjCObjectPointer:

+    return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);

+  case Type::ObjCObject:

+    return CreateType(cast<ObjCObjectType>(Ty), Unit);

+  case Type::ObjCInterface:

+    return CreateType(cast<ObjCInterfaceType>(Ty), Unit);

+  case Type::Builtin:

+    return CreateType(cast<BuiltinType>(Ty));

+  case Type::Complex:

+    return CreateType(cast<ComplexType>(Ty));

+  case Type::Pointer:

+    return CreateType(cast<PointerType>(Ty), Unit);

+  case Type::BlockPointer:

+    return CreateType(cast<BlockPointerType>(Ty), Unit);

+  case Type::Typedef:

+    return CreateType(cast<TypedefType>(Ty), Unit);

+  case Type::Record:

+    return CreateType(cast<RecordType>(Ty));

+  case Type::Enum:

+    return CreateEnumType(cast<EnumType>(Ty)->getDecl());

+  case Type::FunctionProto:

+  case Type::FunctionNoProto:

+    return CreateType(cast<FunctionType>(Ty), Unit);

+  case Type::ConstantArray:

+  case Type::VariableArray:

+  case Type::IncompleteArray:

+    return CreateType(cast<ArrayType>(Ty), Unit);

+

+  case Type::LValueReference:

+    return CreateType(cast<LValueReferenceType>(Ty), Unit);

+  case Type::RValueReference:

+    return CreateType(cast<RValueReferenceType>(Ty), Unit);

+

+  case Type::MemberPointer:

+    return CreateType(cast<MemberPointerType>(Ty), Unit);

+

+  case Type::Atomic:

+    return CreateType(cast<AtomicType>(Ty), Unit);

+

+  case Type::Attributed:

+  case Type::TemplateSpecialization:

+  case Type::Elaborated:

+  case Type::Paren:

+  case Type::SubstTemplateTypeParm:

+  case Type::TypeOfExpr:

+  case Type::TypeOf:

+  case Type::Decltype:

+  case Type::UnaryTransform:

+  case Type::Auto:

+    llvm_unreachable("type should have been unwrapped!");

+  }

+  

+  assert(Diag && "Fall through without a diagnostic?");

+  unsigned DiagID = CGM.getDiags().getCustomDiagID(DiagnosticsEngine::Error,

+                               "debug information for %0 is not yet supported");

+  CGM.getDiags().Report(DiagID)

+    << Diag;

+  return llvm::DIType();

+}

+

+/// getOrCreateLimitedType - Get the type from the cache or create a new

+/// limited type if necessary.

+llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty,

+						 llvm::DIFile Unit) {

+  if (Ty.isNull())

+    return llvm::DIType();

+

+  // Unwrap the type as needed for debug information.

+  Ty = UnwrapTypeForDebugInfo(Ty);

+

+  llvm::DIType T = getTypeOrNull(Ty);

+

+  // We may have cached a forward decl when we could have created

+  // a non-forward decl. Go ahead and create a non-forward decl

+  // now.

+  if (T.Verify() && !T.isForwardDecl()) return T;

+

+  // Otherwise create the type.

+  llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);

+

+  if (T.Verify() && T.isForwardDecl())

+    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(),

+                                        static_cast<llvm::Value*>(T)));

+

+  // And update the type cache.

+  TypeCache[Ty.getAsOpaquePtr()] = Res;

+  return Res;

+}

+

+// TODO: Currently used for context chains when limiting debug info.

+llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {

+  RecordDecl *RD = Ty->getDecl();

+  

+  // Get overall information about the record type for the debug info.

+  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());

+  unsigned Line = getLineNumber(RD->getLocation());

+  StringRef RDName = getClassName(RD);

+

+  llvm::DIDescriptor RDContext;

+  if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo)

+    RDContext = createContextChain(cast<Decl>(RD->getDeclContext()));

+  else

+    RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));

+

+  // If this is just a forward declaration, construct an appropriately

+  // marked node and just return it.

+  if (!RD->getDefinition())

+    return createRecordFwdDecl(RD, RDContext);

+

+  uint64_t Size = CGM.getContext().getTypeSize(Ty);

+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);

+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);

+  llvm::TrackingVH<llvm::MDNode> RealDecl;

+  

+  if (RD->isUnion())

+    RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line,

+					Size, Align, 0, llvm::DIArray());

+  else if (RD->isClass()) {

+    // FIXME: This could be a struct type giving a default visibility different

+    // than C++ class type, but needs llvm metadata changes first.

+    RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,

+					Size, Align, 0, 0, llvm::DIType(),

+					llvm::DIArray(), llvm::DIType(),

+					llvm::DIArray());

+  } else

+    RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,

+					 Size, Align, 0, llvm::DIArray());

+

+  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);

+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = llvm::DIType(RealDecl);

+

+  if (CXXDecl) {

+    // A class's primary base or the class itself contains the vtable.

+    llvm::MDNode *ContainingType = NULL;

+    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);

+    if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {

+      // Seek non virtual primary base root.

+      while (1) {

+	const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);

+	const CXXRecordDecl *PBT = BRL.getPrimaryBase();

+	if (PBT && !BRL.isPrimaryBaseVirtual())

+	  PBase = PBT;

+	else

+	  break;

+      }

+      ContainingType =

+	getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit);

+    }

+    else if (CXXDecl->isDynamicClass())

+      ContainingType = RealDecl;

+

+    RealDecl->replaceOperandWith(12, ContainingType);

+  }

+  return llvm::DIType(RealDecl);

+}

+

+/// CreateLimitedTypeNode - Create a new debug type node, but only forward

+/// declare composite types that haven't been processed yet.

+llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) {

+

+  // Work out details of type.

+  switch (Ty->getTypeClass()) {

+#define TYPE(Class, Base)

+#define ABSTRACT_TYPE(Class, Base)

+#define NON_CANONICAL_TYPE(Class, Base)

+#define DEPENDENT_TYPE(Class, Base) case Type::Class:

+        #include "clang/AST/TypeNodes.def"

+    llvm_unreachable("Dependent types cannot show up in debug information");

+

+  case Type::Record:

+    return CreateLimitedType(cast<RecordType>(Ty));

+  default:

+    return CreateTypeNode(Ty, Unit);

+  }

+}

+

+/// CreateMemberType - Create new member and increase Offset by FType's size.

+llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,

+                                           StringRef Name,

+                                           uint64_t *Offset) {

+  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);

+  uint64_t FieldSize = CGM.getContext().getTypeSize(FType);

+  unsigned FieldAlign = CGM.getContext().getTypeAlign(FType);

+  llvm::DIType Ty = DBuilder.createMemberType(Unit, Name, Unit, 0,

+                                              FieldSize, FieldAlign,

+                                              *Offset, 0, FieldTy);

+  *Offset += FieldSize;

+  return Ty;

+}

+

+/// getFunctionDeclaration - Return debug info descriptor to describe method

+/// declaration for the given method definition.

+llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {

+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);

+  if (!FD) return llvm::DISubprogram();

+

+  // Setup context.

+  getContextDescriptor(cast<Decl>(D->getDeclContext()));

+

+  llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator

+    MI = SPCache.find(FD->getCanonicalDecl());

+  if (MI != SPCache.end()) {

+    llvm::Value *V = MI->second;

+    llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V));

+    if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition())

+      return SP;

+  }

+

+  for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),

+         E = FD->redecls_end(); I != E; ++I) {

+    const FunctionDecl *NextFD = *I;

+    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator

+      MI = SPCache.find(NextFD->getCanonicalDecl());

+    if (MI != SPCache.end()) {

+      llvm::Value *V = MI->second;

+      llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V));

+      if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition())

+        return SP;

+    }

+  }

+  return llvm::DISubprogram();

+}

+

+// getOrCreateFunctionType - Construct DIType. If it is a c++ method, include

+// implicit parameter "this".

+llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl *D,

+                                                  QualType FnType,

+                                                  llvm::DIFile F) {

+

+  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))

+    return getOrCreateMethodType(Method, F);

+  if (const ObjCMethodDecl *OMethod = dyn_cast<ObjCMethodDecl>(D)) {

+    // Add "self" and "_cmd"

+    SmallVector<llvm::Value *, 16> Elts;

+

+    // First element is always return type. For 'void' functions it is NULL.

+    Elts.push_back(getOrCreateType(OMethod->getResultType(), F));

+    // "self" pointer is always first argument.

+    llvm::DIType SelfTy = getOrCreateType(OMethod->getSelfDecl()->getType(), F);

+    Elts.push_back(DBuilder.createObjectPointerType(SelfTy));

+    // "_cmd" pointer is always second argument.

+    llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F);

+    Elts.push_back(DBuilder.createArtificialType(CmdTy));

+    // Get rest of the arguments.

+    for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(), 

+           PE = OMethod->param_end(); PI != PE; ++PI)

+      Elts.push_back(getOrCreateType((*PI)->getType(), F));

+

+    llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);

+    return DBuilder.createSubroutineType(F, EltTypeArray);

+  }

+  return getOrCreateType(FnType, F);

+}

+

+/// EmitFunctionStart - Constructs the debug code for entering a function.

+void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,

+                                    llvm::Function *Fn,

+                                    CGBuilderTy &Builder) {

+

+  StringRef Name;

+  StringRef LinkageName;

+

+  FnBeginRegionCount.push_back(LexicalBlockStack.size());

+

+  const Decl *D = GD.getDecl();

+  // Function may lack declaration in source code if it is created by Clang

+  // CodeGen (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).

+  bool HasDecl = (D != 0);

+  // Use the location of the declaration.

+  SourceLocation Loc;

+  if (HasDecl)

+    Loc = D->getLocation();

+

+  unsigned Flags = 0;

+  llvm::DIFile Unit = getOrCreateFile(Loc);

+  llvm::DIDescriptor FDContext(Unit);

+  llvm::DIArray TParamsArray;

+  if (!HasDecl) {

+    // Use llvm function name.

+    Name = Fn->getName();

+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {

+    // If there is a DISubprogram for this function available then use it.

+    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator

+      FI = SPCache.find(FD->getCanonicalDecl());

+    if (FI != SPCache.end()) {

+      llvm::Value *V = FI->second;

+      llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(V));

+      if (SP.isSubprogram() && llvm::DISubprogram(SP).isDefinition()) {

+        llvm::MDNode *SPN = SP;

+        LexicalBlockStack.push_back(SPN);

+        RegionMap[D] = llvm::WeakVH(SP);

+        return;

+      }

+    }

+    Name = getFunctionName(FD);

+    // Use mangled name as linkage name for c/c++ functions.

+    if (FD->hasPrototype()) {

+      LinkageName = CGM.getMangledName(GD);

+      Flags |= llvm::DIDescriptor::FlagPrototyped;

+    }

+    if (LinkageName == Name ||

+        CGM.getCodeGenOpts().getDebugInfo() <= CodeGenOptions::DebugLineTablesOnly)

+      LinkageName = StringRef();

+

+    if (CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) {

+      if (const NamespaceDecl *NSDecl =

+          dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))

+        FDContext = getOrCreateNameSpace(NSDecl);

+      else if (const RecordDecl *RDecl =

+               dyn_cast_or_null<RecordDecl>(FD->getDeclContext()))

+        FDContext = getContextDescriptor(cast<Decl>(RDecl->getDeclContext()));

+

+      // Collect template parameters.

+      TParamsArray = CollectFunctionTemplateParams(FD, Unit);

+    }

+  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {

+    Name = getObjCMethodName(OMD);

+    Flags |= llvm::DIDescriptor::FlagPrototyped;

+  } else {

+    // Use llvm function name.

+    Name = Fn->getName();

+    Flags |= llvm::DIDescriptor::FlagPrototyped;

+  }

+  if (!Name.empty() && Name[0] == '\01')

+    Name = Name.substr(1);

+

+  unsigned LineNo = getLineNumber(Loc);

+  if (!HasDecl || D->isImplicit())

+    Flags |= llvm::DIDescriptor::FlagArtificial;

+

+  llvm::DIType DIFnType;

+  llvm::DISubprogram SPDecl;

+  if (HasDecl &&

+      CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) {

+    DIFnType = getOrCreateFunctionType(D, FnType, Unit);

+    SPDecl = getFunctionDeclaration(D);

+  } else {

+    // Create fake but valid subroutine type. Otherwise

+    // llvm::DISubprogram::Verify() would return false, and

+    // subprogram DIE will miss DW_AT_decl_file and

+    // DW_AT_decl_line fields.

+    SmallVector<llvm::Value*, 16> Elts;

+    llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);

+    DIFnType = DBuilder.createSubroutineType(Unit, EltTypeArray);

+  }

+  llvm::DISubprogram SP;

+  SP = DBuilder.createFunction(FDContext, Name, LinkageName, Unit,

+                               LineNo, DIFnType,

+                               Fn->hasInternalLinkage(), true/*definition*/,

+                               getLineNumber(CurLoc), Flags,

+                               CGM.getLangOpts().Optimize,

+                               Fn, TParamsArray, SPDecl);

+

+  // Push function on region stack.

+  llvm::MDNode *SPN = SP;

+  LexicalBlockStack.push_back(SPN);

+  if (HasDecl)

+    RegionMap[D] = llvm::WeakVH(SP);

+}

+

+/// EmitLocation - Emit metadata to indicate a change in line/column

+/// information in the source file.

+void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {

+  

+  // Update our current location

+  setLocation(Loc);

+

+  if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;

+

+  // Don't bother if things are the same as last time.

+  SourceManager &SM = CGM.getContext().getSourceManager();

+  if (CurLoc == PrevLoc ||

+      SM.getExpansionLoc(CurLoc) == SM.getExpansionLoc(PrevLoc))

+    // New Builder may not be in sync with CGDebugInfo.

+    if (!Builder.getCurrentDebugLocation().isUnknown())

+      return;

+  

+  // Update last state.

+  PrevLoc = CurLoc;

+

+  llvm::MDNode *Scope = LexicalBlockStack.back();

+  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(CurLoc),

+                                                      getColumnNumber(CurLoc),

+                                                      Scope));

+}

+

+/// CreateLexicalBlock - Creates a new lexical block node and pushes it on

+/// the stack.

+void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {

+  llvm::DIDescriptor D =

+    DBuilder.createLexicalBlock(LexicalBlockStack.empty() ?

+                                llvm::DIDescriptor() :

+                                llvm::DIDescriptor(LexicalBlockStack.back()),

+                                getOrCreateFile(CurLoc),

+                                getLineNumber(CurLoc),

+                                getColumnNumber(CurLoc));

+  llvm::MDNode *DN = D;

+  LexicalBlockStack.push_back(DN);

+}

+

+/// EmitLexicalBlockStart - Constructs the debug code for entering a declarative

+/// region - beginning of a DW_TAG_lexical_block.

+void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc) {

+  // Set our current location.

+  setLocation(Loc);

+

+  // Create a new lexical block and push it on the stack.

+  CreateLexicalBlock(Loc);

+

+  // Emit a line table change for the current location inside the new scope.

+  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(Loc),

+                                  getColumnNumber(Loc),

+                                  LexicalBlockStack.back()));

+}

+

+/// EmitLexicalBlockEnd - Constructs the debug code for exiting a declarative

+/// region - end of a DW_TAG_lexical_block.

+void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc) {

+  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

+

+  // Provide an entry in the line table for the end of the block.

+  EmitLocation(Builder, Loc);

+

+  LexicalBlockStack.pop_back();

+}

+

+/// EmitFunctionEnd - Constructs the debug code for exiting a function.

+void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {

+  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

+  unsigned RCount = FnBeginRegionCount.back();

+  assert(RCount <= LexicalBlockStack.size() && "Region stack mismatch");

+

+  // Pop all regions for this function.

+  while (LexicalBlockStack.size() != RCount)

+    EmitLexicalBlockEnd(Builder, CurLoc);

+  FnBeginRegionCount.pop_back();

+}

+

+// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  

+// See BuildByRefType.

+llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,

+                                                       uint64_t *XOffset) {

+

+  SmallVector<llvm::Value *, 5> EltTys;

+  QualType FType;

+  uint64_t FieldSize, FieldOffset;

+  unsigned FieldAlign;

+  

+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());

+  QualType Type = VD->getType();  

+

+  FieldOffset = 0;

+  FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);

+  EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset));

+  EltTys.push_back(CreateMemberType(Unit, FType, "__forwarding", &FieldOffset));

+  FType = CGM.getContext().IntTy;

+  EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset));

+  EltTys.push_back(CreateMemberType(Unit, FType, "__size", &FieldOffset));

+

+  bool HasCopyAndDispose = CGM.getContext().BlockRequiresCopying(Type, VD);

+  if (HasCopyAndDispose) {

+    FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);

+    EltTys.push_back(CreateMemberType(Unit, FType, "__copy_helper",

+                                      &FieldOffset));

+    EltTys.push_back(CreateMemberType(Unit, FType, "__destroy_helper",

+                                      &FieldOffset));

+  }

+  bool HasByrefExtendedLayout;

+  Qualifiers::ObjCLifetime Lifetime;

+  if (CGM.getContext().getByrefLifetime(Type,

+                                        Lifetime, HasByrefExtendedLayout)

+      && HasByrefExtendedLayout)

+    EltTys.push_back(CreateMemberType(Unit, FType,

+                                      "__byref_variable_layout",

+                                      &FieldOffset));

+  

+  CharUnits Align = CGM.getContext().getDeclAlign(VD);

+  if (Align > CGM.getContext().toCharUnitsFromBits(

+        CGM.getContext().getTargetInfo().getPointerAlign(0))) {

+    CharUnits FieldOffsetInBytes 

+      = CGM.getContext().toCharUnitsFromBits(FieldOffset);

+    CharUnits AlignedOffsetInBytes

+      = FieldOffsetInBytes.RoundUpToAlignment(Align);

+    CharUnits NumPaddingBytes

+      = AlignedOffsetInBytes - FieldOffsetInBytes;

+    

+    if (NumPaddingBytes.isPositive()) {

+      llvm::APInt pad(32, NumPaddingBytes.getQuantity());

+      FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,

+                                                    pad, ArrayType::Normal, 0);

+      EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset));

+    }

+  }

+  

+  FType = Type;

+  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);

+  FieldSize = CGM.getContext().getTypeSize(FType);

+  FieldAlign = CGM.getContext().toBits(Align);

+

+  *XOffset = FieldOffset;  

+  FieldTy = DBuilder.createMemberType(Unit, VD->getName(), Unit,

+                                      0, FieldSize, FieldAlign,

+                                      FieldOffset, 0, FieldTy);

+  EltTys.push_back(FieldTy);

+  FieldOffset += FieldSize;

+  

+  llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);

+  

+  unsigned Flags = llvm::DIDescriptor::FlagBlockByrefStruct;

+  

+  return DBuilder.createStructType(Unit, "", Unit, 0, FieldOffset, 0, Flags,

+                                   Elements);

+}

+

+/// EmitDeclare - Emit local variable declaration debug info.

+void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,

+                              llvm::Value *Storage, 

+                              unsigned ArgNo, CGBuilderTy &Builder) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

+

+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());

+  llvm::DIType Ty;

+  uint64_t XOffset = 0;

+  if (VD->hasAttr<BlocksAttr>())

+    Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);

+  else 

+    Ty = getOrCreateType(VD->getType(), Unit);

+

+  // If there is no debug info for this type then do not emit debug info

+  // for this variable.

+  if (!Ty)

+    return;

+

+  if (llvm::Argument *Arg = dyn_cast<llvm::Argument>(Storage)) {

+    // If Storage is an aggregate returned as 'sret' then let debugger know

+    // about this.

+    if (Arg->hasStructRetAttr())

+      Ty = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, Ty);

+    else if (CXXRecordDecl *Record = VD->getType()->getAsCXXRecordDecl()) {

+      // If an aggregate variable has non trivial destructor or non trivial copy

+      // constructor than it is pass indirectly. Let debug info know about this

+      // by using reference of the aggregate type as a argument type.

+      if (Record->hasNonTrivialCopyConstructor() ||

+          !Record->hasTrivialDestructor())

+        Ty = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, Ty);

+    }

+  }

+      

+  // Get location information.

+  unsigned Line = getLineNumber(VD->getLocation());

+  unsigned Column = getColumnNumber(VD->getLocation());

+  unsigned Flags = 0;

+  if (VD->isImplicit())

+    Flags |= llvm::DIDescriptor::FlagArtificial;

+  // If this is the first argument and it is implicit then

+  // give it an object pointer flag.

+  // FIXME: There has to be a better way to do this, but for static

+  // functions there won't be an implicit param at arg1 and

+  // otherwise it is 'self' or 'this'.

+  if (isa<ImplicitParamDecl>(VD) && ArgNo == 1)

+    Flags |= llvm::DIDescriptor::FlagObjectPointer;

+

+  llvm::MDNode *Scope = LexicalBlockStack.back();

+

+  StringRef Name = VD->getName();

+  if (!Name.empty()) {

+    if (VD->hasAttr<BlocksAttr>()) {

+      CharUnits offset = CharUnits::fromQuantity(32);

+      SmallVector<llvm::Value *, 9> addr;

+      llvm::Type *Int64Ty = CGM.Int64Ty;

+      addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));

+      // offset of __forwarding field

+      offset = CGM.getContext().toCharUnitsFromBits(

+        CGM.getContext().getTargetInfo().getPointerWidth(0));

+      addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));

+      addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));

+      addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));

+      // offset of x field

+      offset = CGM.getContext().toCharUnitsFromBits(XOffset);

+      addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));

+

+      // Create the descriptor for the variable.

+      llvm::DIVariable D =

+        DBuilder.createComplexVariable(Tag, 

+                                       llvm::DIDescriptor(Scope),

+                                       VD->getName(), Unit, Line, Ty,

+                                       addr, ArgNo);

+      

+      // Insert an llvm.dbg.declare into the current block.

+      llvm::Instruction *Call =

+        DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());

+      Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));

+      return;

+    } else if (isa<VariableArrayType>(VD->getType())) {

+      // These are "complex" variables in that they need an op_deref.

+      // Create the descriptor for the variable.

+      llvm::Value *Addr = llvm::ConstantInt::get(CGM.Int64Ty,

+                                                 llvm::DIBuilder::OpDeref);

+      llvm::DIVariable D =

+        DBuilder.createComplexVariable(Tag,

+                                       llvm::DIDescriptor(Scope),

+                                       Name, Unit, Line, Ty,

+                                       Addr, ArgNo);

+

+      // Insert an llvm.dbg.declare into the current block.

+      llvm::Instruction *Call =

+        DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());

+      Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));

+      return;

+    }

+    

+    // Create the descriptor for the variable.

+    llvm::DIVariable D =

+      DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope), 

+                                   Name, Unit, Line, Ty, 

+                                   CGM.getLangOpts().Optimize, Flags, ArgNo);

+    

+    // Insert an llvm.dbg.declare into the current block.

+    llvm::Instruction *Call =

+      DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());

+    Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));

+    return;

+  }

+  

+  // If VD is an anonymous union then Storage represents value for

+  // all union fields.

+  if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) {

+    const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());

+    if (RD->isUnion()) {

+      for (RecordDecl::field_iterator I = RD->field_begin(),

+             E = RD->field_end();

+           I != E; ++I) {

+        FieldDecl *Field = *I;

+        llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);

+        StringRef FieldName = Field->getName();

+          

+        // Ignore unnamed fields. Do not ignore unnamed records.

+        if (FieldName.empty() && !isa<RecordType>(Field->getType()))

+          continue;

+          

+        // Use VarDecl's Tag, Scope and Line number.

+        llvm::DIVariable D =

+          DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),

+                                       FieldName, Unit, Line, FieldTy, 

+                                       CGM.getLangOpts().Optimize, Flags,

+                                       ArgNo);

+          

+        // Insert an llvm.dbg.declare into the current block.

+        llvm::Instruction *Call =

+          DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());

+        Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));

+      }

+    }

+  }

+}

+

+void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,

+                                            llvm::Value *Storage,

+                                            CGBuilderTy &Builder) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, 0, Builder);

+}

+

+void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD,

+                                                    llvm::Value *Storage,

+                                                    CGBuilderTy &Builder,

+                                                 const CGBlockInfo &blockInfo) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

+  

+  if (Builder.GetInsertBlock() == 0)

+    return;

+  

+  bool isByRef = VD->hasAttr<BlocksAttr>();

+  

+  uint64_t XOffset = 0;

+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());

+  llvm::DIType Ty;

+  if (isByRef)

+    Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);

+  else 

+    Ty = getOrCreateType(VD->getType(), Unit);

+

+  // Self is passed along as an implicit non-arg variable in a

+  // block. Mark it as the object pointer.

+  if (isa<ImplicitParamDecl>(VD) && VD->getName() == "self")

+    Ty = DBuilder.createObjectPointerType(Ty);

+

+  // Get location information.

+  unsigned Line = getLineNumber(VD->getLocation());

+  unsigned Column = getColumnNumber(VD->getLocation());

+

+  const llvm::DataLayout &target = CGM.getDataLayout();

+

+  CharUnits offset = CharUnits::fromQuantity(

+    target.getStructLayout(blockInfo.StructureType)

+          ->getElementOffset(blockInfo.getCapture(VD).getIndex()));

+

+  SmallVector<llvm::Value *, 9> addr;

+  llvm::Type *Int64Ty = CGM.Int64Ty;

+  addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));

+  addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));

+  if (isByRef) {

+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));

+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));

+    // offset of __forwarding field

+    offset = CGM.getContext()

+                .toCharUnitsFromBits(target.getPointerSizeInBits(0));

+    addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));

+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));

+    addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));

+    // offset of x field

+    offset = CGM.getContext().toCharUnitsFromBits(XOffset);

+    addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));

+  }

+

+  // Create the descriptor for the variable.

+  llvm::DIVariable D =

+    DBuilder.createComplexVariable(llvm::dwarf::DW_TAG_auto_variable, 

+                                   llvm::DIDescriptor(LexicalBlockStack.back()),

+                                   VD->getName(), Unit, Line, Ty, addr);

+  // Insert an llvm.dbg.declare into the current block.

+  llvm::Instruction *Call =

+    DBuilder.insertDeclare(Storage, D, Builder.GetInsertPoint());

+  Call->setDebugLoc(llvm::DebugLoc::get(Line, Column,

+                                        LexicalBlockStack.back()));

+}

+

+/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument

+/// variable declaration.

+void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,

+                                           unsigned ArgNo,

+                                           CGBuilderTy &Builder) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, ArgNo, Builder);

+}

+

+namespace {

+  struct BlockLayoutChunk {

+    uint64_t OffsetInBits;

+    const BlockDecl::Capture *Capture;

+  };

+  bool operator<(const BlockLayoutChunk &l, const BlockLayoutChunk &r) {

+    return l.OffsetInBits < r.OffsetInBits;

+  }

+}

+

+void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,

+                                                       llvm::Value *addr,

+                                                       CGBuilderTy &Builder) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  ASTContext &C = CGM.getContext();

+  const BlockDecl *blockDecl = block.getBlockDecl();

+

+  // Collect some general information about the block's location.

+  SourceLocation loc = blockDecl->getCaretLocation();

+  llvm::DIFile tunit = getOrCreateFile(loc);

+  unsigned line = getLineNumber(loc);

+  unsigned column = getColumnNumber(loc);

+  

+  // Build the debug-info type for the block literal.

+  getContextDescriptor(cast<Decl>(blockDecl->getDeclContext()));

+

+  const llvm::StructLayout *blockLayout =

+    CGM.getDataLayout().getStructLayout(block.StructureType);

+

+  SmallVector<llvm::Value*, 16> fields;

+  fields.push_back(createFieldType("__isa", C.VoidPtrTy, 0, loc, AS_public,

+                                   blockLayout->getElementOffsetInBits(0),

+                                   tunit, tunit));

+  fields.push_back(createFieldType("__flags", C.IntTy, 0, loc, AS_public,

+                                   blockLayout->getElementOffsetInBits(1),

+                                   tunit, tunit));

+  fields.push_back(createFieldType("__reserved", C.IntTy, 0, loc, AS_public,

+                                   blockLayout->getElementOffsetInBits(2),

+                                   tunit, tunit));

+  fields.push_back(createFieldType("__FuncPtr", C.VoidPtrTy, 0, loc, AS_public,

+                                   blockLayout->getElementOffsetInBits(3),

+                                   tunit, tunit));

+  fields.push_back(createFieldType("__descriptor",

+                                   C.getPointerType(block.NeedsCopyDispose ?

+                                        C.getBlockDescriptorExtendedType() :

+                                        C.getBlockDescriptorType()),

+                                   0, loc, AS_public,

+                                   blockLayout->getElementOffsetInBits(4),

+                                   tunit, tunit));

+

+  // We want to sort the captures by offset, not because DWARF

+  // requires this, but because we're paranoid about debuggers.

+  SmallVector<BlockLayoutChunk, 8> chunks;

+

+  // 'this' capture.

+  if (blockDecl->capturesCXXThis()) {

+    BlockLayoutChunk chunk;

+    chunk.OffsetInBits =

+      blockLayout->getElementOffsetInBits(block.CXXThisIndex);

+    chunk.Capture = 0;

+    chunks.push_back(chunk);

+  }

+

+  // Variable captures.

+  for (BlockDecl::capture_const_iterator

+         i = blockDecl->capture_begin(), e = blockDecl->capture_end();

+       i != e; ++i) {

+    const BlockDecl::Capture &capture = *i;

+    const VarDecl *variable = capture.getVariable();

+    const CGBlockInfo::Capture &captureInfo = block.getCapture(variable);

+

+    // Ignore constant captures.

+    if (captureInfo.isConstant())

+      continue;

+

+    BlockLayoutChunk chunk;

+    chunk.OffsetInBits =

+      blockLayout->getElementOffsetInBits(captureInfo.getIndex());

+    chunk.Capture = &capture;

+    chunks.push_back(chunk);

+  }

+

+  // Sort by offset.

+  llvm::array_pod_sort(chunks.begin(), chunks.end());

+

+  for (SmallVectorImpl<BlockLayoutChunk>::iterator

+         i = chunks.begin(), e = chunks.end(); i != e; ++i) {

+    uint64_t offsetInBits = i->OffsetInBits;

+    const BlockDecl::Capture *capture = i->Capture;

+

+    // If we have a null capture, this must be the C++ 'this' capture.

+    if (!capture) {

+      const CXXMethodDecl *method =

+        cast<CXXMethodDecl>(blockDecl->getNonClosureContext());

+      QualType type = method->getThisType(C);

+

+      fields.push_back(createFieldType("this", type, 0, loc, AS_public,

+                                       offsetInBits, tunit, tunit));

+      continue;

+    }

+

+    const VarDecl *variable = capture->getVariable();

+    StringRef name = variable->getName();

+

+    llvm::DIType fieldType;

+    if (capture->isByRef()) {

+      std::pair<uint64_t,unsigned> ptrInfo = C.getTypeInfo(C.VoidPtrTy);

+

+      // FIXME: this creates a second copy of this type!

+      uint64_t xoffset;

+      fieldType = EmitTypeForVarWithBlocksAttr(variable, &xoffset);

+      fieldType = DBuilder.createPointerType(fieldType, ptrInfo.first);

+      fieldType = DBuilder.createMemberType(tunit, name, tunit, line,

+                                            ptrInfo.first, ptrInfo.second,

+                                            offsetInBits, 0, fieldType);

+    } else {

+      fieldType = createFieldType(name, variable->getType(), 0,

+                                  loc, AS_public, offsetInBits, tunit, tunit);

+    }

+    fields.push_back(fieldType);

+  }

+

+  SmallString<36> typeName;

+  llvm::raw_svector_ostream(typeName)

+    << "__block_literal_" << CGM.getUniqueBlockCount();

+

+  llvm::DIArray fieldsArray = DBuilder.getOrCreateArray(fields);

+

+  llvm::DIType type =

+    DBuilder.createStructType(tunit, typeName.str(), tunit, line,

+                              CGM.getContext().toBits(block.BlockSize),

+                              CGM.getContext().toBits(block.BlockAlign),

+                              0, fieldsArray);

+  type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);

+

+  // Get overall information about the block.

+  unsigned flags = llvm::DIDescriptor::FlagArtificial;

+  llvm::MDNode *scope = LexicalBlockStack.back();

+  StringRef name = ".block_descriptor";

+

+  // Create the descriptor for the parameter.

+  llvm::DIVariable debugVar =

+    DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_arg_variable,

+                                 llvm::DIDescriptor(scope), 

+                                 name, tunit, line, type, 

+                                 CGM.getLangOpts().Optimize, flags,

+                                 cast<llvm::Argument>(addr)->getArgNo() + 1);

+    

+  // Insert an llvm.dbg.value into the current block.

+  llvm::Instruction *declare =

+    DBuilder.insertDbgValueIntrinsic(addr, 0, debugVar,

+                                     Builder.GetInsertBlock());

+  declare->setDebugLoc(llvm::DebugLoc::get(line, column, scope));

+}

+

+/// EmitGlobalVariable - Emit information about a global variable.

+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,

+                                     const VarDecl *D) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  // Create global variable debug descriptor.

+  llvm::DIFile Unit = getOrCreateFile(D->getLocation());

+  unsigned LineNo = getLineNumber(D->getLocation());

+

+  setLocation(D->getLocation());

+

+  QualType T = D->getType();

+  if (T->isIncompleteArrayType()) {

+

+    // CodeGen turns int[] into int[1] so we'll do the same here.

+    llvm::APInt ConstVal(32, 1);

+    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();

+

+    T = CGM.getContext().getConstantArrayType(ET, ConstVal,

+                                              ArrayType::Normal, 0);

+  }

+  StringRef DeclName = D->getName();

+  StringRef LinkageName;

+  if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext())

+      && !isa<ObjCMethodDecl>(D->getDeclContext()))

+    LinkageName = Var->getName();

+  if (LinkageName == DeclName)

+    LinkageName = StringRef();

+  llvm::DIDescriptor DContext = 

+    getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()));

+  DBuilder.createStaticVariable(DContext, DeclName, LinkageName,

+                                Unit, LineNo, getOrCreateType(T, Unit),

+                                Var->hasInternalLinkage(), Var);

+}

+

+/// EmitGlobalVariable - Emit information about an objective-c interface.

+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,

+                                     ObjCInterfaceDecl *ID) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  // Create global variable debug descriptor.

+  llvm::DIFile Unit = getOrCreateFile(ID->getLocation());

+  unsigned LineNo = getLineNumber(ID->getLocation());

+

+  StringRef Name = ID->getName();

+

+  QualType T = CGM.getContext().getObjCInterfaceType(ID);

+  if (T->isIncompleteArrayType()) {

+

+    // CodeGen turns int[] into int[1] so we'll do the same here.

+    llvm::APInt ConstVal(32, 1);

+    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();

+

+    T = CGM.getContext().getConstantArrayType(ET, ConstVal,

+                                           ArrayType::Normal, 0);

+  }

+

+  DBuilder.createGlobalVariable(Name, Unit, LineNo,

+                                getOrCreateType(T, Unit),

+                                Var->hasInternalLinkage(), Var);

+}

+

+/// EmitGlobalVariable - Emit global variable's debug info.

+void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, 

+                                     llvm::Constant *Init) {

+  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo);

+  // Create the descriptor for the variable.

+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());

+  StringRef Name = VD->getName();

+  llvm::DIType Ty = getOrCreateType(VD->getType(), Unit);

+  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(VD)) {

+    const EnumDecl *ED = cast<EnumDecl>(ECD->getDeclContext());

+    assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?");

+    Ty = getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit);

+  }

+  // Do not use DIGlobalVariable for enums.

+  if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type)

+    return;

+  DBuilder.createStaticVariable(Unit, Name, Name, Unit,

+                                getLineNumber(VD->getLocation()),

+                                Ty, true, Init);

+}

+

+/// getOrCreateNamesSpace - Return namespace descriptor for the given

+/// namespace decl.

+llvm::DINameSpace 

+CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {

+  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH>::iterator I = 

+    NameSpaceCache.find(NSDecl);

+  if (I != NameSpaceCache.end())

+    return llvm::DINameSpace(cast<llvm::MDNode>(I->second));

+  

+  unsigned LineNo = getLineNumber(NSDecl->getLocation());

+  llvm::DIFile FileD = getOrCreateFile(NSDecl->getLocation());

+  llvm::DIDescriptor Context = 

+    getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()));

+  llvm::DINameSpace NS =

+    DBuilder.createNameSpace(Context, NSDecl->getName(), FileD, LineNo);

+  NameSpaceCache[NSDecl] = llvm::WeakVH(NS);

+  return NS;

+}

+

+void CGDebugInfo::finalize() {

+  for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI

+         = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {

+    llvm::DIType Ty, RepTy;

+    // Verify that the debug info still exists.

+    if (llvm::Value *V = VI->second)

+      Ty = llvm::DIType(cast<llvm::MDNode>(V));

+    

+    llvm::DenseMap<void *, llvm::WeakVH>::iterator it =

+      TypeCache.find(VI->first);

+    if (it != TypeCache.end()) {

+      // Verify that the debug info still exists.

+      if (llvm::Value *V = it->second)

+        RepTy = llvm::DIType(cast<llvm::MDNode>(V));

+    }

+    

+    if (Ty.Verify() && Ty.isForwardDecl() && RepTy.Verify()) {

+      Ty.replaceAllUsesWith(RepTy);

+    }

+  }

+  DBuilder.finalize();

+}

diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index cb9ce8b..5a3b122 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -1,325 +1,330 @@
-//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the source level debug info generator for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CGDEBUGINFO_H
-#define CLANG_CODEGEN_CGDEBUGINFO_H
-
-#include "CGBuilder.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/DIBuilder.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ValueHandle.h"
-
-namespace llvm {
-  class MDNode;
-}
-
-namespace clang {
-  class CXXMethodDecl;
-  class VarDecl;
-  class ObjCInterfaceDecl;
-  class ClassTemplateSpecializationDecl;
-  class GlobalDecl;
-
-namespace CodeGen {
-  class CodeGenModule;
-  class CodeGenFunction;
-  class CGBlockInfo;
-
-/// CGDebugInfo - This class gathers all debug information during compilation
-/// and is responsible for emitting to llvm globals or pass directly to
-/// the backend.
-class CGDebugInfo {
-  CodeGenModule &CGM;
-  llvm::DIBuilder DBuilder;
-  llvm::DICompileUnit TheCU;
-  SourceLocation CurLoc, PrevLoc;
-  llvm::DIType VTablePtrType;
-  llvm::DIType ClassTy;
-  llvm::DIType ObjTy;
-  llvm::DIType SelTy;
-  
-  /// TypeCache - Cache of previously constructed Types.
-  llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
-
-  /// CompleteTypeCache - Cache of previously constructed complete RecordTypes.
-  llvm::DenseMap<void *, llvm::WeakVH> CompletedTypeCache;
-
-  /// ReplaceMap - Cache of forward declared types to RAUW at the end of
-  /// compilation.
-  std::vector<std::pair<void *, llvm::WeakVH> >ReplaceMap;
-
-  bool BlockLiteralGenericSet;
-  llvm::DIType BlockLiteralGeneric;
-
-  // LexicalBlockStack - Keep track of our current nested lexical block.
-  std::vector<llvm::TrackingVH<llvm::MDNode> > LexicalBlockStack;
-  llvm::DenseMap<const Decl *, llvm::WeakVH> RegionMap;
-  // FnBeginRegionCount - Keep track of LexicalBlockStack counter at the
-  // beginning of a function. This is used to pop unbalanced regions at
-  // the end of a function.
-  std::vector<unsigned> FnBeginRegionCount;
-
-  /// DebugInfoNames - This is a storage for names that are
-  /// constructed on demand. For example, C++ destructors, C++ operators etc..
-  llvm::BumpPtrAllocator DebugInfoNames;
-  StringRef CWDName;
-
-  llvm::DenseMap<const char *, llvm::WeakVH> DIFileCache;
-  llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache;
-  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache;
-
-  /// Helper functions for getOrCreateType.
-  llvm::DIType CreateType(const BuiltinType *Ty);
-  llvm::DIType CreateType(const ComplexType *Ty);
-  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
-                          llvm::DIFile F);
-  llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const RecordType *Ty);
-  llvm::DIType CreateLimitedType(const RecordType *Ty);
-  llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const RValueReferenceType *Ty, llvm::DIFile Unit);
-  llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
-  llvm::DIType CreateEnumType(const EnumDecl *ED);
-  llvm::DIType getTypeOrNull(const QualType);
-  llvm::DIType getCompletedTypeOrNull(const QualType);
-  llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
-                                     llvm::DIFile F);
-  llvm::DIType getOrCreateFunctionType(const Decl *D, QualType FnType,
-                                       llvm::DIFile F);
-  llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
-  llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N);
-  llvm::DIType CreatePointeeType(QualType PointeeTy, llvm::DIFile F);
-  llvm::DIType CreatePointerLikeType(unsigned Tag,
-                                     const Type *Ty, QualType PointeeTy,
-                                     llvm::DIFile F);
-  
-  llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,
-                                             llvm::DIFile F,
-                                             llvm::DIType RecordTy);
-  
-  void CollectCXXMemberFunctions(const CXXRecordDecl *Decl,
-                                 llvm::DIFile F,
-                                 SmallVectorImpl<llvm::Value *> &E,
-                                 llvm::DIType T);
-
-  void CollectCXXFriends(const CXXRecordDecl *Decl,
-                       llvm::DIFile F,
-                       SmallVectorImpl<llvm::Value *> &EltTys,
-                       llvm::DIType RecordTy);
-
-  void CollectCXXBases(const CXXRecordDecl *Decl,
-                       llvm::DIFile F,
-                       SmallVectorImpl<llvm::Value *> &EltTys,
-                       llvm::DIType RecordTy);
-  
-  llvm::DIArray
-  CollectTemplateParams(const TemplateParameterList *TPList,
-                        const TemplateArgumentList &TAList,
-                        llvm::DIFile Unit);
-  llvm::DIArray
-  CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit);
-  llvm::DIArray 
-  CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,
-                           llvm::DIFile F);
-
-  llvm::DIType createFieldType(StringRef name, QualType type,
-                               uint64_t sizeInBitsOverride, SourceLocation loc,
-                               AccessSpecifier AS, uint64_t offsetInBits,
-                               llvm::DIFile tunit,
-                               llvm::DIDescriptor scope);
-  void CollectRecordStaticVars(const RecordDecl *, llvm::DIType);
-  void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
-                           SmallVectorImpl<llvm::Value *> &E,
-                           llvm::DIType RecordTy);
-
-  void CollectVTableInfo(const CXXRecordDecl *Decl,
-                         llvm::DIFile F,
-                         SmallVectorImpl<llvm::Value *> &EltTys);
-
-  // CreateLexicalBlock - Create a new lexical block node and push it on
-  // the stack.
-  void CreateLexicalBlock(SourceLocation Loc);
-  
-public:
-  CGDebugInfo(CodeGenModule &CGM);
-  ~CGDebugInfo();
-
-  void finalize();
-
-  /// setLocation - Update the current source location. If \arg loc is
-  /// invalid it is ignored.
-  void setLocation(SourceLocation Loc);
-
-  /// EmitLocation - Emit metadata to indicate a change in line/column
-  /// information in the source file.
-  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
-
-  /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate
-  /// start of a new function.
-  void EmitFunctionStart(GlobalDecl GD, QualType FnType,
-                         llvm::Function *Fn, CGBuilderTy &Builder);
-
-  /// EmitFunctionEnd - Constructs the debug code for exiting a function.
-  void EmitFunctionEnd(CGBuilderTy &Builder);
-
-  /// EmitLexicalBlockStart - Emit metadata to indicate the beginning of a
-  /// new lexical block and push the block onto the stack.
-  void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc);
-
-  /// EmitLexicalBlockEnd - Emit metadata to indicate the end of a new lexical
-  /// block and pop the current block.
-  void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc);
-
-  /// EmitDeclareOfAutoVariable - Emit call to llvm.dbg.declare for an automatic
-  /// variable declaration.
-  void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
-                                 CGBuilderTy &Builder);
-
-  /// EmitDeclareOfBlockDeclRefVariable - Emit call to llvm.dbg.declare for an
-  /// imported variable declaration in a block.
-  void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable,
-                                         llvm::Value *storage,
-                                         CGBuilderTy &Builder,
-                                         const CGBlockInfo &blockInfo);
-
-  /// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
-  /// variable declaration.
-  void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
-                                unsigned ArgNo, CGBuilderTy &Builder);
-
-  /// EmitDeclareOfBlockLiteralArgVariable - Emit call to
-  /// llvm.dbg.declare for the block-literal argument to a block
-  /// invocation function.
-  void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
-                                            llvm::Value *addr,
-                                            CGBuilderTy &Builder);
-
-  /// EmitGlobalVariable - Emit information about a global variable.
-  void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
-
-  /// EmitGlobalVariable - Emit information about an objective-c interface.
-  void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);
-
-  /// EmitGlobalVariable - Emit global variable's debug info.
-  void EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init);
-
-  /// getOrCreateRecordType - Emit record type's standalone debug info. 
-  llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L);
-
-  /// getOrCreateInterfaceType - Emit an objective c interface type standalone
-  /// debug info.
-  llvm::DIType getOrCreateInterfaceType(QualType Ty,
-					SourceLocation Loc);
-
-private:
-  /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
-  void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
-                   unsigned ArgNo, CGBuilderTy &Builder);
-
-  // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  
-  // See BuildByRefType.
-  llvm::DIType EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
-                                            uint64_t *OffSet);
-
-  /// getContextDescriptor - Get context info for the decl.
-  llvm::DIDescriptor getContextDescriptor(const Decl *Decl);
-
-  /// createRecordFwdDecl - Create a forward decl for a RecordType in a given
-  /// context.
-  llvm::DIType createRecordFwdDecl(const RecordDecl *, llvm::DIDescriptor);
-  
-  /// createContextChain - Create a set of decls for the context chain.
-  llvm::DIDescriptor createContextChain(const Decl *Decl);
-
-  /// getCurrentDirname - Return current directory name.
-  StringRef getCurrentDirname();
-
-  /// CreateCompileUnit - Create new compile unit.
-  void CreateCompileUnit();
-
-  /// getOrCreateFile - Get the file debug info descriptor for the input 
-  /// location.
-  llvm::DIFile getOrCreateFile(SourceLocation Loc);
-
-  /// getOrCreateMainFile - Get the file info for main compile unit.
-  llvm::DIFile getOrCreateMainFile();
-
-  /// getOrCreateType - Get the type from the cache or create a new type if
-  /// necessary.
-  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);
-
-  /// getOrCreateLimitedType - Get the type from the cache or create a new
-  /// partial type if necessary.
-  llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F);
-
-  /// CreateTypeNode - Create type metadata for a source language type.
-  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
-
-  /// CreateLimitedTypeNode - Create type metadata for a source language
-  /// type, but only partial types for records.
-  llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F);
-
-  /// CreateMemberType - Create new member and increase Offset by FType's size.
-  llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,
-                                StringRef Name, uint64_t *Offset);
-
-  /// getFunctionDeclaration - Return debug info descriptor to describe method
-  /// declaration for the given method definition.
-  llvm::DISubprogram getFunctionDeclaration(const Decl *D);
-
-  /// getFunctionName - Get function name for the given FunctionDecl. If the
-  /// name is constructred on demand (e.g. C++ destructor) then the name
-  /// is stored on the side.
-  StringRef getFunctionName(const FunctionDecl *FD);
-
-  /// getObjCMethodName - Returns the unmangled name of an Objective-C method.
-  /// This is the display name for the debugging info.  
-  StringRef getObjCMethodName(const ObjCMethodDecl *FD);
-
-  /// getSelectorName - Return selector name. This is used for debugging
-  /// info.
-  StringRef getSelectorName(Selector S);
-
-  /// getClassName - Get class name including template argument list.
-  StringRef getClassName(const RecordDecl *RD);
-
-  /// getVTableName - Get vtable name for the given Class.
-  StringRef getVTableName(const CXXRecordDecl *Decl);
-
-  /// getLineNumber - Get line number for the location. If location is invalid
-  /// then use current location.
-  unsigned getLineNumber(SourceLocation Loc);
-
-  /// getColumnNumber - Get column number for the location. If location is 
-  /// invalid then use current location.
-  unsigned getColumnNumber(SourceLocation Loc);
-};
-} // namespace CodeGen
-} // namespace clang
-
-
-#endif
+//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -------------*- C++ -*-===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This is the source level debug info generator for llvm translation.

+//

+//===----------------------------------------------------------------------===//

+

+#ifndef CLANG_CODEGEN_CGDEBUGINFO_H

+#define CLANG_CODEGEN_CGDEBUGINFO_H

+

+#include "CGBuilder.h"

+#include "clang/AST/Expr.h"

+#include "clang/AST/Type.h"

+#include "clang/Basic/SourceLocation.h"

+#include "llvm/ADT/DenseMap.h"

+#include "llvm/DIBuilder.h"

+#include "llvm/DebugInfo.h"

+#include "llvm/Support/Allocator.h"

+#include "llvm/Support/ValueHandle.h"

+

+namespace llvm {

+  class MDNode;

+}

+

+namespace clang {

+  class CXXMethodDecl;

+  class VarDecl;

+  class ObjCInterfaceDecl;

+  class ClassTemplateSpecializationDecl;

+  class GlobalDecl;

+

+namespace CodeGen {

+  class CodeGenModule;

+  class CodeGenFunction;

+  class CGBlockInfo;

+

+/// CGDebugInfo - This class gathers all debug information during compilation

+/// and is responsible for emitting to llvm globals or pass directly to

+/// the backend.

+class CGDebugInfo {

+  CodeGenModule &CGM;

+  llvm::DIBuilder DBuilder;

+  llvm::DICompileUnit TheCU;

+  SourceLocation CurLoc, PrevLoc;

+  llvm::DIType VTablePtrType;

+  llvm::DIType ClassTy;

+  llvm::DIType ObjTy;

+  llvm::DIType SelTy;

+  llvm::DIType OCLImage1dDITy, OCLImage1dArrayDITy, OCLImage1dBufferDITy;

+  llvm::DIType OCLImage2dDITy, OCLImage2dArrayDITy;

+  llvm::DIType OCLImage3dDITy;

+  

+  /// TypeCache - Cache of previously constructed Types.

+  llvm::DenseMap<void *, llvm::WeakVH> TypeCache;

+

+  /// CompleteTypeCache - Cache of previously constructed complete RecordTypes.

+  llvm::DenseMap<void *, llvm::WeakVH> CompletedTypeCache;

+

+  /// ReplaceMap - Cache of forward declared types to RAUW at the end of

+  /// compilation.

+  std::vector<std::pair<void *, llvm::WeakVH> >ReplaceMap;

+

+  bool BlockLiteralGenericSet;

+  llvm::DIType BlockLiteralGeneric;

+

+  // LexicalBlockStack - Keep track of our current nested lexical block.

+  std::vector<llvm::TrackingVH<llvm::MDNode> > LexicalBlockStack;

+  llvm::DenseMap<const Decl *, llvm::WeakVH> RegionMap;

+  // FnBeginRegionCount - Keep track of LexicalBlockStack counter at the

+  // beginning of a function. This is used to pop unbalanced regions at

+  // the end of a function.

+  std::vector<unsigned> FnBeginRegionCount;

+

+  /// DebugInfoNames - This is a storage for names that are

+  /// constructed on demand. For example, C++ destructors, C++ operators etc..

+  llvm::BumpPtrAllocator DebugInfoNames;

+  StringRef CWDName;

+

+  llvm::DenseMap<const char *, llvm::WeakVH> DIFileCache;

+  llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache;

+  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache;

+

+  /// Helper functions for getOrCreateType.

+  llvm::DIType CreateType(const BuiltinType *Ty);

+  llvm::DIType CreateType(const ComplexType *Ty);

+  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const ObjCObjectPointerType *Ty,

+                          llvm::DIFile F);

+  llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const RecordType *Ty);

+  llvm::DIType CreateLimitedType(const RecordType *Ty);

+  llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const RValueReferenceType *Ty, llvm::DIFile Unit);

+  llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);

+  llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);

+  llvm::DIType CreateEnumType(const EnumDecl *ED);

+  llvm::DIType getTypeOrNull(const QualType);

+  llvm::DIType getCompletedTypeOrNull(const QualType);

+  llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,

+                                     llvm::DIFile F);

+  llvm::DIType getOrCreateFunctionType(const Decl *D, QualType FnType,

+                                       llvm::DIFile F);

+  llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);

+  llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N);

+  llvm::DIType CreatePointeeType(QualType PointeeTy, llvm::DIFile F);

+  llvm::DIType CreatePointerLikeType(unsigned Tag,

+                                     const Type *Ty, QualType PointeeTy,

+                                     llvm::DIFile F);

+

+  llvm::DIType getOrCreateStructPtrType(StringRef Name, llvm::DIType &Cache);

+

+  llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,

+                                             llvm::DIFile F,

+                                             llvm::DIType RecordTy);

+  

+  void CollectCXXMemberFunctions(const CXXRecordDecl *Decl,

+                                 llvm::DIFile F,

+                                 SmallVectorImpl<llvm::Value *> &E,

+                                 llvm::DIType T);

+

+  void CollectCXXFriends(const CXXRecordDecl *Decl,

+                       llvm::DIFile F,

+                       SmallVectorImpl<llvm::Value *> &EltTys,

+                       llvm::DIType RecordTy);

+

+  void CollectCXXBases(const CXXRecordDecl *Decl,

+                       llvm::DIFile F,

+                       SmallVectorImpl<llvm::Value *> &EltTys,

+                       llvm::DIType RecordTy);

+  

+  llvm::DIArray

+  CollectTemplateParams(const TemplateParameterList *TPList,

+                        const TemplateArgumentList &TAList,

+                        llvm::DIFile Unit);

+  llvm::DIArray

+  CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit);

+  llvm::DIArray 

+  CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,

+                           llvm::DIFile F);

+

+  llvm::DIType createFieldType(StringRef name, QualType type,

+                               uint64_t sizeInBitsOverride, SourceLocation loc,

+                               AccessSpecifier AS, uint64_t offsetInBits,

+                               llvm::DIFile tunit,

+                               llvm::DIDescriptor scope);

+  void CollectRecordStaticVars(const RecordDecl *, llvm::DIType);

+  void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,

+                           SmallVectorImpl<llvm::Value *> &E,

+                           llvm::DIType RecordTy);

+

+  void CollectVTableInfo(const CXXRecordDecl *Decl,

+                         llvm::DIFile F,

+                         SmallVectorImpl<llvm::Value *> &EltTys);

+

+  // CreateLexicalBlock - Create a new lexical block node and push it on

+  // the stack.

+  void CreateLexicalBlock(SourceLocation Loc);

+  

+public:

+  CGDebugInfo(CodeGenModule &CGM);

+  ~CGDebugInfo();

+

+  void finalize();

+

+  /// setLocation - Update the current source location. If \arg loc is

+  /// invalid it is ignored.

+  void setLocation(SourceLocation Loc);

+

+  /// EmitLocation - Emit metadata to indicate a change in line/column

+  /// information in the source file.

+  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);

+

+  /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate

+  /// start of a new function.

+  void EmitFunctionStart(GlobalDecl GD, QualType FnType,

+                         llvm::Function *Fn, CGBuilderTy &Builder);

+

+  /// EmitFunctionEnd - Constructs the debug code for exiting a function.

+  void EmitFunctionEnd(CGBuilderTy &Builder);

+

+  /// EmitLexicalBlockStart - Emit metadata to indicate the beginning of a

+  /// new lexical block and push the block onto the stack.

+  void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc);

+

+  /// EmitLexicalBlockEnd - Emit metadata to indicate the end of a new lexical

+  /// block and pop the current block.

+  void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc);

+

+  /// EmitDeclareOfAutoVariable - Emit call to llvm.dbg.declare for an automatic

+  /// variable declaration.

+  void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,

+                                 CGBuilderTy &Builder);

+

+  /// EmitDeclareOfBlockDeclRefVariable - Emit call to llvm.dbg.declare for an

+  /// imported variable declaration in a block.

+  void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable,

+                                         llvm::Value *storage,

+                                         CGBuilderTy &Builder,

+                                         const CGBlockInfo &blockInfo);

+

+  /// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument

+  /// variable declaration.

+  void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,

+                                unsigned ArgNo, CGBuilderTy &Builder);

+

+  /// EmitDeclareOfBlockLiteralArgVariable - Emit call to

+  /// llvm.dbg.declare for the block-literal argument to a block

+  /// invocation function.

+  void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,

+                                            llvm::Value *addr,

+                                            CGBuilderTy &Builder);

+

+  /// EmitGlobalVariable - Emit information about a global variable.

+  void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);

+

+  /// EmitGlobalVariable - Emit information about an objective-c interface.

+  void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);

+

+  /// EmitGlobalVariable - Emit global variable's debug info.

+  void EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init);

+

+  /// getOrCreateRecordType - Emit record type's standalone debug info. 

+  llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L);

+

+  /// getOrCreateInterfaceType - Emit an objective c interface type standalone

+  /// debug info.

+  llvm::DIType getOrCreateInterfaceType(QualType Ty,

+					SourceLocation Loc);

+

+private:

+  /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.

+  void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,

+                   unsigned ArgNo, CGBuilderTy &Builder);

+

+  // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  

+  // See BuildByRefType.

+  llvm::DIType EmitTypeForVarWithBlocksAttr(const VarDecl *VD,

+                                            uint64_t *OffSet);

+

+  /// getContextDescriptor - Get context info for the decl.

+  llvm::DIDescriptor getContextDescriptor(const Decl *Decl);

+

+  /// createRecordFwdDecl - Create a forward decl for a RecordType in a given

+  /// context.

+  llvm::DIType createRecordFwdDecl(const RecordDecl *, llvm::DIDescriptor);

+  

+  /// createContextChain - Create a set of decls for the context chain.

+  llvm::DIDescriptor createContextChain(const Decl *Decl);

+

+  /// getCurrentDirname - Return current directory name.

+  StringRef getCurrentDirname();

+

+  /// CreateCompileUnit - Create new compile unit.

+  void CreateCompileUnit();

+

+  /// getOrCreateFile - Get the file debug info descriptor for the input 

+  /// location.

+  llvm::DIFile getOrCreateFile(SourceLocation Loc);

+

+  /// getOrCreateMainFile - Get the file info for main compile unit.

+  llvm::DIFile getOrCreateMainFile();

+

+  /// getOrCreateType - Get the type from the cache or create a new type if

+  /// necessary.

+  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);

+

+  /// getOrCreateLimitedType - Get the type from the cache or create a new

+  /// partial type if necessary.

+  llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F);

+

+  /// CreateTypeNode - Create type metadata for a source language type.

+  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);

+

+  /// CreateLimitedTypeNode - Create type metadata for a source language

+  /// type, but only partial types for records.

+  llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F);

+

+  /// CreateMemberType - Create new member and increase Offset by FType's size.

+  llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,

+                                StringRef Name, uint64_t *Offset);

+

+  /// getFunctionDeclaration - Return debug info descriptor to describe method

+  /// declaration for the given method definition.

+  llvm::DISubprogram getFunctionDeclaration(const Decl *D);

+

+  /// getFunctionName - Get function name for the given FunctionDecl. If the

+  /// name is constructred on demand (e.g. C++ destructor) then the name

+  /// is stored on the side.

+  StringRef getFunctionName(const FunctionDecl *FD);

+

+  /// getObjCMethodName - Returns the unmangled name of an Objective-C method.

+  /// This is the display name for the debugging info.  

+  StringRef getObjCMethodName(const ObjCMethodDecl *FD);

+

+  /// getSelectorName - Return selector name. This is used for debugging

+  /// info.

+  StringRef getSelectorName(Selector S);

+

+  /// getClassName - Get class name including template argument list.

+  StringRef getClassName(const RecordDecl *RD);

+

+  /// getVTableName - Get vtable name for the given Class.

+  StringRef getVTableName(const CXXRecordDecl *Decl);

+

+  /// getLineNumber - Get line number for the location. If location is invalid

+  /// then use current location.

+  unsigned getLineNumber(SourceLocation Loc);

+

+  /// getColumnNumber - Get column number for the location. If location is 

+  /// invalid then use current location.

+  unsigned getColumnNumber(SourceLocation Loc);

+};

+} // namespace CodeGen

+} // namespace clang

+

+

+#endif

diff --git a/lib/CodeGen/CGOpenCLRuntime.cpp b/lib/CodeGen/CGOpenCLRuntime.cpp
index 3a0e116..61d6286 100644
--- a/lib/CodeGen/CGOpenCLRuntime.cpp
+++ b/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -1,28 +1,59 @@
-//===----- CGOpenCLRuntime.cpp - Interface to OpenCL Runtimes -------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides an abstract class for OpenCL code generation.  Concrete
-// subclasses of this implement code generation for specific OpenCL
-// runtime libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGOpenCLRuntime.h"
-#include "CodeGenFunction.h"
-#include "llvm/GlobalValue.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-CGOpenCLRuntime::~CGOpenCLRuntime() {}
-
-void CGOpenCLRuntime::EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF,
-                                                const VarDecl &D) {
-  return CGF.EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
-}
+//===----- CGOpenCLRuntime.cpp - Interface to OpenCL Runtimes -------------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This provides an abstract class for OpenCL code generation.  Concrete

+// subclasses of this implement code generation for specific OpenCL

+// runtime libraries.

+//

+//===----------------------------------------------------------------------===//

+

+#include "CGOpenCLRuntime.h"

+#include "CodeGenFunction.h"

+#include "llvm/GlobalValue.h"

+#include "llvm/DerivedTypes.h"

+#include <assert.h>

+

+using namespace clang;

+using namespace CodeGen;

+

+CGOpenCLRuntime::~CGOpenCLRuntime() {}

+

+void CGOpenCLRuntime::EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF,

+                                                const VarDecl &D) {

+  return CGF.EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);

+}

+

+llvm::Type *CGOpenCLRuntime::convertOpenCLSpecificType(const Type *T) {

+  assert(T->isOpenCLSpecificType() &&

+         "Not an OpenCL specific type!");

+

+  switch (cast<BuiltinType>(T)->getKind()) {

+  default: 

+    llvm_unreachable("Unexpected opencl builtin type!");

+    return 0;

+  case BuiltinType::OCLImage1d:

+    return llvm::PointerType::get(llvm::StructType::create(

+                           CGM.getLLVMContext(), "opencl.image1d_t"), 0);

+  case BuiltinType::OCLImage1dArray:

+    return llvm::PointerType::get(llvm::StructType::create(

+                           CGM.getLLVMContext(), "opencl.image1d_array_t"), 0);

+  case BuiltinType::OCLImage1dBuffer:

+    return llvm::PointerType::get(llvm::StructType::create(

+                           CGM.getLLVMContext(), "opencl.image1d_buffer_t"), 0);

+  case BuiltinType::OCLImage2d:

+    return llvm::PointerType::get(llvm::StructType::create(

+                           CGM.getLLVMContext(), "opencl.image2d_t"), 0);

+  case BuiltinType::OCLImage2dArray:

+    return llvm::PointerType::get(llvm::StructType::create(

+                           CGM.getLLVMContext(), "opencl.image2d_array_t"), 0);

+  case BuiltinType::OCLImage3d:

+    return llvm::PointerType::get(llvm::StructType::create(

+                           CGM.getLLVMContext(), "opencl.image3d_t"), 0);

+  }

+}

diff --git a/lib/CodeGen/CGOpenCLRuntime.h b/lib/CodeGen/CGOpenCLRuntime.h
index 9a8430f..7b33951 100644
--- a/lib/CodeGen/CGOpenCLRuntime.h
+++ b/lib/CodeGen/CGOpenCLRuntime.h
@@ -1,46 +1,52 @@
-//===----- CGOpenCLRuntime.h - Interface to OpenCL Runtimes -----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides an abstract class for OpenCL code generation.  Concrete
-// subclasses of this implement code generation for specific OpenCL
-// runtime libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_OPENCLRUNTIME_H
-#define CLANG_CODEGEN_OPENCLRUNTIME_H
-
-namespace clang {
-
-class VarDecl;
-
-namespace CodeGen {
-
-class CodeGenFunction;
-class CodeGenModule;
-
-class CGOpenCLRuntime {
-protected:
-  CodeGenModule &CGM;
-
-public:
-  CGOpenCLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
-  virtual ~CGOpenCLRuntime();
-
-  /// Emit the IR required for a work-group-local variable declaration, and add
-  /// an entry to CGF's LocalDeclMap for D.  The base class does this using
-  /// CodeGenFunction::EmitStaticVarDecl to emit an internal global for D.
-  virtual void EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF,
-                                         const VarDecl &D);
-};
-
-}
-}
-
-#endif
+//===----- CGOpenCLRuntime.h - Interface to OpenCL Runtimes -----*- C++ -*-===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This provides an abstract class for OpenCL code generation.  Concrete

+// subclasses of this implement code generation for specific OpenCL

+// runtime libraries.

+//

+//===----------------------------------------------------------------------===//

+

+#ifndef CLANG_CODEGEN_OPENCLRUNTIME_H

+#define CLANG_CODEGEN_OPENCLRUNTIME_H

+

+#include "clang/AST/Type.h"

+#include "llvm/Type.h"

+#include "llvm/Value.h"

+

+namespace clang {

+

+class VarDecl;

+

+namespace CodeGen {

+

+class CodeGenFunction;

+class CodeGenModule;

+

+class CGOpenCLRuntime {

+protected:

+  CodeGenModule &CGM;

+

+public:

+  CGOpenCLRuntime(CodeGenModule &CGM) : CGM(CGM) {}

+  virtual ~CGOpenCLRuntime();

+

+  /// Emit the IR required for a work-group-local variable declaration, and add

+  /// an entry to CGF's LocalDeclMap for D.  The base class does this using

+  /// CodeGenFunction::EmitStaticVarDecl to emit an internal global for D.

+  virtual void EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF,

+                                         const VarDecl &D);

+

+  virtual llvm::Type *convertOpenCLSpecificType(const Type *T);

+};

+

+}

+}

+

+#endif

diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index 53716a0..0a1fb4b 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -1,1011 +1,1017 @@
-//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of RTTI descriptors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CodeGenOptions.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-class RTTIBuilder {
-  CodeGenModule &CGM;  // Per-module state.
-  llvm::LLVMContext &VMContext;
-  
-  /// Fields - The fields of the RTTI descriptor currently being built.
-  SmallVector<llvm::Constant *, 16> Fields;
-
-  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
-  llvm::GlobalVariable *
-  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
-
-  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
-  /// descriptor of the given type.
-  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
-  
-  /// BuildVTablePointer - Build the vtable pointer for the given type.
-  void BuildVTablePointer(const Type *Ty);
-  
-  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
-  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-  /// classes with bases that do not satisfy the abi::__si_class_type_info 
-  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
-  /// for pointer types.
-  void BuildPointerTypeInfo(QualType PointeeTy);
-
-  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
-  /// type_info for an object type.
-  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
-  
-  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-  /// struct, used for member pointer types.
-  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
-  
-public:
-  RTTIBuilder(CodeGenModule &CGM) : CGM(CGM), 
-    VMContext(CGM.getModule().getContext()) { }
-
-  // Pointer type info flags.
-  enum {
-    /// PTI_Const - Type has const qualifier.
-    PTI_Const = 0x1,
-    
-    /// PTI_Volatile - Type has volatile qualifier.
-    PTI_Volatile = 0x2,
-    
-    /// PTI_Restrict - Type has restrict qualifier.
-    PTI_Restrict = 0x4,
-    
-    /// PTI_Incomplete - Type is incomplete.
-    PTI_Incomplete = 0x8,
-    
-    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
-    /// (in pointer to member).
-    PTI_ContainingClassIncomplete = 0x10
-  };
-  
-  // VMI type info flags.
-  enum {
-    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
-    VMI_NonDiamondRepeat = 0x1,
-    
-    /// VMI_DiamondShaped - Class is diamond shaped.
-    VMI_DiamondShaped = 0x2
-  };
-  
-  // Base class type info flags.
-  enum {
-    /// BCTI_Virtual - Base class is virtual.
-    BCTI_Virtual = 0x1,
-    
-    /// BCTI_Public - Base class is public.
-    BCTI_Public = 0x2
-  };
-  
-  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
-  ///
-  /// \param Force - true to force the creation of this RTTI value
-  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
-};
-}
-
-llvm::GlobalVariable *
-RTTIBuilder::GetAddrOfTypeName(QualType Ty, 
-                               llvm::GlobalVariable::LinkageTypes Linkage) {
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // We know that the mangled name of the type starts at index 4 of the
-  // mangled name of the typename, so we can just index into it in order to
-  // get the mangled name of the type.
-  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
-                                                            Name.substr(4));
-
-  llvm::GlobalVariable *GV = 
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
-
-  GV->setInitializer(Init);
-
-  return GV;
-}
-
-llvm::Constant *RTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
-  // Mangle the RTTI name.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // Look for an existing global.
-  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
-  
-  if (!GV) {
-    // Create a new global variable.
-    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
-                                  /*Constant=*/true,
-                                  llvm::GlobalValue::ExternalLinkage, 0, Name);
-  }
-  
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
-/// info for that type is defined in the standard library.
-static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
-  // Itanium C++ ABI 2.9.2:
-  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
-  //   the run-time support library. Specifically, the run-time support
-  //   library should contain type_info objects for the types X, X* and 
-  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
-  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
-  //   long, unsigned long, long long, unsigned long long, float, double,
-  //   long double, char16_t, char32_t, and the IEEE 754r decimal and 
-  //   half-precision floating point types.
-  switch (Ty->getKind()) {
-    case BuiltinType::Void:
-    case BuiltinType::NullPtr:
-    case BuiltinType::Bool:
-    case BuiltinType::WChar_S:
-    case BuiltinType::WChar_U:
-    case BuiltinType::Char_U:
-    case BuiltinType::Char_S:
-    case BuiltinType::UChar:
-    case BuiltinType::SChar:
-    case BuiltinType::Short:
-    case BuiltinType::UShort:
-    case BuiltinType::Int:
-    case BuiltinType::UInt:
-    case BuiltinType::Long:
-    case BuiltinType::ULong:
-    case BuiltinType::LongLong:
-    case BuiltinType::ULongLong:
-    case BuiltinType::Half:
-    case BuiltinType::Float:
-    case BuiltinType::Double:
-    case BuiltinType::LongDouble:
-    case BuiltinType::Char16:
-    case BuiltinType::Char32:
-    case BuiltinType::Int128:
-    case BuiltinType::UInt128:
-      return true;
-      
-    case BuiltinType::Dependent:
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-    case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-      llvm_unreachable("asking for RRTI for a placeholder type!");
-      
-    case BuiltinType::ObjCId:
-    case BuiltinType::ObjCClass:
-    case BuiltinType::ObjCSel:
-      llvm_unreachable("FIXME: Objective-C types are unsupported!");
-  }
-
-  llvm_unreachable("Invalid BuiltinType Kind!");
-}
-
-static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
-  QualType PointeeTy = PointerTy->getPointeeType();
-  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
-  if (!BuiltinTy)
-    return false;
-    
-  // Check the qualifiers.
-  Qualifiers Quals = PointeeTy.getQualifiers();
-  Quals.removeConst();
-    
-  if (!Quals.empty())
-    return false;
-    
-  return TypeInfoIsInStandardLibrary(BuiltinTy);
-}
-
-/// IsStandardLibraryRTTIDescriptor - Returns whether the type
-/// information for the given type exists in the standard library.
-static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
-  // Type info for builtin types is defined in the standard library.
-  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
-    return TypeInfoIsInStandardLibrary(BuiltinTy);
-  
-  // Type info for some pointer types to builtin types is defined in the
-  // standard library.
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return TypeInfoIsInStandardLibrary(PointerTy);
-
-  return false;
-}
-
-/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
-/// the given type exists somewhere else, and that we should not emit the type
-/// information in this translation unit.  Assumes that it is not a
-/// standard-library type.
-static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) {
-  ASTContext &Context = CGM.getContext();
-
-  // If RTTI is disabled, don't consider key functions.
-  if (!Context.getLangOpts().RTTI) return false;
-
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
-    if (!RD->hasDefinition())
-      return false;
-
-    if (!RD->isDynamicClass())
-      return false;
-
-    return !CGM.getVTables().ShouldEmitVTableInThisTU(RD);
-  }
-  
-  return false;
-}
-
-/// IsIncompleteClassType - Returns whether the given record type is incomplete.
-static bool IsIncompleteClassType(const RecordType *RecordTy) {
-  return !RecordTy->getDecl()->isCompleteDefinition();
-}  
-
-/// ContainsIncompleteClassType - Returns whether the given type contains an
-/// incomplete class type. This is true if
-///
-///   * The given type is an incomplete class type.
-///   * The given type is a pointer type whose pointee type contains an 
-///     incomplete class type.
-///   * The given type is a member pointer type whose class is an incomplete
-///     class type.
-///   * The given type is a member pointer type whoise pointee type contains an
-///     incomplete class type.
-/// is an indirect or direct pointer to an incomplete class type.
-static bool ContainsIncompleteClassType(QualType Ty) {
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    if (IsIncompleteClassType(RecordTy))
-      return true;
-  }
-  
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return ContainsIncompleteClassType(PointerTy->getPointeeType());
-  
-  if (const MemberPointerType *MemberPointerTy = 
-      dyn_cast<MemberPointerType>(Ty)) {
-    // Check if the class type is incomplete.
-    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
-    if (IsIncompleteClassType(ClassType))
-      return true;
-    
-    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
-  }
-  
-  return false;
-}
-
-/// getTypeInfoLinkage - Return the linkage that the type info and type info
-/// name constants should have for the given type.
-static llvm::GlobalVariable::LinkageTypes 
-getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) {
-  // Itanium C++ ABI 2.9.5p7:
-  //   In addition, it and all of the intermediate abi::__pointer_type_info 
-  //   structs in the chain down to the abi::__class_type_info for the
-  //   incomplete class type must be prevented from resolving to the 
-  //   corresponding type_info structs for the complete class type, possibly
-  //   by making them local static objects. Finally, a dummy class RTTI is
-  //   generated for the incomplete type that will not resolve to the final 
-  //   complete class RTTI (because the latter need not exist), possibly by 
-  //   making it a local static object.
-  if (ContainsIncompleteClassType(Ty))
-    return llvm::GlobalValue::InternalLinkage;
-  
-  switch (Ty->getLinkage()) {
-  case NoLinkage:
-  case InternalLinkage:
-  case UniqueExternalLinkage:
-    return llvm::GlobalValue::InternalLinkage;
-
-  case ExternalLinkage:
-    if (!CGM.getLangOpts().RTTI) {
-      // RTTI is not enabled, which means that this type info struct is going
-      // to be used for exception handling. Give it linkonce_odr linkage.
-      return llvm::GlobalValue::LinkOnceODRLinkage;
-    }
-
-    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
-      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
-      if (RD->hasAttr<WeakAttr>())
-        return llvm::GlobalValue::WeakODRLinkage;
-      if (RD->isDynamicClass())
-        return CGM.getVTableLinkage(RD);
-    }
-
-    return llvm::GlobalValue::LinkOnceODRLinkage;
-  }
-
-  llvm_unreachable("Invalid linkage!");
-}
-
-// CanUseSingleInheritance - Return whether the given record decl has a "single, 
-// public, non-virtual base at offset zero (i.e. the derived class is dynamic 
-// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
-static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
-  // Check the number of bases.
-  if (RD->getNumBases() != 1)
-    return false;
-  
-  // Get the base.
-  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
-  
-  // Check that the base is not virtual.
-  if (Base->isVirtual())
-    return false;
-  
-  // Check that the base is public.
-  if (Base->getAccessSpecifier() != AS_public)
-    return false;
-  
-  // Check that the class is dynamic iff the base is.
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  if (!BaseDecl->isEmpty() && 
-      BaseDecl->isDynamicClass() != RD->isDynamicClass())
-    return false;
-  
-  return true;
-}
-
-void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
-  // abi::__class_type_info.
-  static const char * const ClassTypeInfo =
-    "_ZTVN10__cxxabiv117__class_type_infoE";
-  // abi::__si_class_type_info.
-  static const char * const SIClassTypeInfo =
-    "_ZTVN10__cxxabiv120__si_class_type_infoE";
-  // abi::__vmi_class_type_info.
-  static const char * const VMIClassTypeInfo =
-    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
-
-  const char *VTableName = 0;
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Builtin:
-  // GCC treats vector and complex types as fundamental types.
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::Atomic:
-  // FIXME: GCC treats block pointers as fundamental types?!
-  case Type::BlockPointer:
-    // abi::__fundamental_type_info.
-    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
-    break;
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // abi::__array_type_info.
-    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // abi::__function_type_info.
-    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
-    break;
-
-  case Type::Enum:
-    // abi::__enum_type_info.
-    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      VTableName = ClassTypeInfo;
-    } else if (CanUseSingleInheritance(RD)) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = VMIClassTypeInfo;
-    }
-    
-    break;
-  }
-
-  case Type::ObjCObject:
-    // Ignore protocol qualifiers.
-    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
-
-    // Handle id and Class.
-    if (isa<BuiltinType>(Ty)) {
-      VTableName = ClassTypeInfo;
-      break;
-    }
-
-    assert(isa<ObjCInterfaceType>(Ty));
-    // Fall through.
-
-  case Type::ObjCInterface:
-    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = ClassTypeInfo;
-    }
-    break;
-
-  case Type::ObjCObjectPointer:
-  case Type::Pointer:
-    // abi::__pointer_type_info.
-    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
-    break;
-
-  case Type::MemberPointer:
-    // abi::__pointer_to_member_type_info.
-    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
-    break;
-  }
-
-  llvm::Constant *VTable = 
-    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
-    
-  llvm::Type *PtrDiffTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
-
-  // The vtable address point is 2.
-  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
-  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
-  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
-
-  Fields.push_back(VTable);
-}
-
-// maybeUpdateRTTILinkage - Will update the linkage of the RTTI data structures
-// from available_externally to the correct linkage if necessary. An example of
-// this is:
-//
-//   struct A {
-//     virtual void f();
-//   };
-//
-//   const std::type_info &g() {
-//     return typeid(A);
-//   }
-//
-//   void A::f() { }
-//
-// When we're generating the typeid(A) expression, we do not yet know that
-// A's key function is defined in this translation unit, so we will give the
-// typeinfo and typename structures available_externally linkage. When A::f
-// forces the vtable to be generated, we need to change the linkage of the
-// typeinfo and typename structs, otherwise we'll end up with undefined
-// externals when linking.
-static void 
-maybeUpdateRTTILinkage(CodeGenModule &CGM, llvm::GlobalVariable *GV,
-                       QualType Ty) {
-  // We're only interested in globals with available_externally linkage.
-  if (!GV->hasAvailableExternallyLinkage())
-    return;
-
-  // Get the real linkage for the type.
-  llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty);
-
-  // If variable is supposed to have available_externally linkage, we don't
-  // need to do anything.
-  if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
-    return;
-
-  // Update the typeinfo linkage.
-  GV->setLinkage(Linkage);
-
-  // Get the typename global.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  llvm::GlobalVariable *TypeNameGV = CGM.getModule().getNamedGlobal(Name);
-
-  assert(TypeNameGV->hasAvailableExternallyLinkage() &&
-         "Type name has different linkage from type info!");
-
-  // And update its linkage.
-  TypeNameGV->setLinkage(Linkage);
-}
-
-llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
-  // We want to operate on the canonical type.
-  Ty = CGM.getContext().getCanonicalType(Ty);
-
-  // Check if we've already emitted an RTTI descriptor for this type.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
-  if (OldGV && !OldGV->isDeclaration()) {
-    maybeUpdateRTTILinkage(CGM, OldGV, Ty);
-
-    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
-  }
-
-  // Check if there is already an external RTTI descriptor for this type.
-  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
-  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
-    return GetAddrOfExternalRTTIDescriptor(Ty);
-
-  // Emit the standard library with external linkage.
-  llvm::GlobalVariable::LinkageTypes Linkage;
-  if (IsStdLib)
-    Linkage = llvm::GlobalValue::ExternalLinkage;
-  else
-    Linkage = getTypeInfoLinkage(CGM, Ty);
-
-  // Add the vtable pointer.
-  BuildVTablePointer(cast<Type>(Ty));
-  
-  // And the name.
-  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
-
-  Fields.push_back(llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy));
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  // GCC treats vector types as fundamental types.
-  case Type::Builtin:
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::BlockPointer:
-    // Itanium C++ ABI 2.9.5p4:
-    // abi::__fundamental_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__array_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__function_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Enum:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__enum_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      // We don't need to emit any fields.
-      break;
-    }
-    
-    if (CanUseSingleInheritance(RD))
-      BuildSIClassTypeInfo(RD);
-    else 
-      BuildVMIClassTypeInfo(RD);
-
-    break;
-  }
-
-  case Type::ObjCObject:
-  case Type::ObjCInterface:
-    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
-    break;
-
-  case Type::ObjCObjectPointer:
-    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
-    break; 
-      
-  case Type::Pointer:
-    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
-    break;
-
-  case Type::MemberPointer:
-    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
-    break;
-
-  case Type::Atomic:
-    // No fields, at least for the moment.
-    break;
-  }
-
-  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
-
-  llvm::GlobalVariable *GV = 
-    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
-                             /*Constant=*/true, Linkage, Init, Name);
-  
-  // If there's already an old global variable, replace it with the new one.
-  if (OldGV) {
-    GV->takeName(OldGV);
-    llvm::Constant *NewPtr = 
-      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
-    OldGV->replaceAllUsesWith(NewPtr);
-    OldGV->eraseFromParent();
-  }
-
-  // GCC only relies on the uniqueness of the type names, not the
-  // type_infos themselves, so we can emit these as hidden symbols.
-  // But don't do this if we're worried about strict visibility
-  // compatibility.
-  if (const RecordType *RT = dyn_cast<RecordType>(Ty)) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-
-    CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForRTTI);
-    CGM.setTypeVisibility(TypeName, RD, CodeGenModule::TVK_ForRTTIName);
-  } else {
-    Visibility TypeInfoVisibility = DefaultVisibility;
-    if (CGM.getCodeGenOpts().HiddenWeakVTables &&
-        Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
-      TypeInfoVisibility = HiddenVisibility;
-
-    // The type name should have the same visibility as the type itself.
-    Visibility ExplicitVisibility = Ty->getVisibility();
-    TypeName->setVisibility(CodeGenModule::
-                            GetLLVMVisibility(ExplicitVisibility));
-  
-    TypeInfoVisibility = minVisibility(TypeInfoVisibility, Ty->getVisibility());
-    GV->setVisibility(CodeGenModule::GetLLVMVisibility(TypeInfoVisibility));
-  }
-
-  GV->setUnnamedAddr(true);
-
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// ComputeQualifierFlags - Compute the pointer type info flags from the
-/// given qualifier.
-static unsigned ComputeQualifierFlags(Qualifiers Quals) {
-  unsigned Flags = 0;
-
-  if (Quals.hasConst())
-    Flags |= RTTIBuilder::PTI_Const;
-  if (Quals.hasVolatile())
-    Flags |= RTTIBuilder::PTI_Volatile;
-  if (Quals.hasRestrict())
-    Flags |= RTTIBuilder::PTI_Restrict;
-
-  return Flags;
-}
-
-/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
-/// for the given Objective-C object type.
-void RTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
-  // Drop qualifiers.
-  const Type *T = OT->getBaseType().getTypePtr();
-  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
-
-  // The builtin types are abi::__class_type_infos and don't require
-  // extra fields.
-  if (isa<BuiltinType>(T)) return;
-
-  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
-  ObjCInterfaceDecl *Super = Class->getSuperClass();
-
-  // Root classes are also __class_type_info.
-  if (!Super) return;
-
-  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
-
-  // Everything else is single inheritance.
-  llvm::Constant *BaseTypeInfo = RTTIBuilder(CGM).BuildTypeInfo(SuperTy);
-  Fields.push_back(BaseTypeInfo);
-}
-
-/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
-void RTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
-  // Itanium C++ ABI 2.9.5p6b:
-  // It adds to abi::__class_type_info a single member pointing to the 
-  // type_info structure for the base type,
-  llvm::Constant *BaseTypeInfo = 
-    RTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
-  Fields.push_back(BaseTypeInfo);
-}
-
-namespace {
-  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
-  /// a class hierarchy.
-  struct SeenBases {
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
-  };
-}
-
-/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
-/// abi::__vmi_class_type_info.
-///
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
-                                             SeenBases &Bases) {
-  
-  unsigned Flags = 0;
-  
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  
-  if (Base->isVirtual()) {
-    // Mark the virtual base as seen.
-    if (!Bases.VirtualBases.insert(BaseDecl)) {
-      // If this virtual base has been seen before, then the class is diamond
-      // shaped.
-      Flags |= RTTIBuilder::VMI_DiamondShaped;
-    } else {
-      if (Bases.NonVirtualBases.count(BaseDecl))
-        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  } else {
-    // Mark the non-virtual base as seen.
-    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
-      // If this non-virtual base has been seen before, then the class has non-
-      // diamond shaped repeated inheritance.
-      Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
-    } else {
-      if (Bases.VirtualBases.count(BaseDecl))
-        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  }
-
-  // Walk all bases.
-  for (CXXRecordDecl::base_class_const_iterator I = BaseDecl->bases_begin(),
-       E = BaseDecl->bases_end(); I != E; ++I) 
-    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
-  
-  return Flags;
-}
-
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
-  unsigned Flags = 0;
-  SeenBases Bases;
-  
-  // Walk all bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) 
-    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
-  
-  return Flags;
-}
-
-/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-/// classes with bases that do not satisfy the abi::__si_class_type_info 
-/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __flags is a word with flags describing details about the class 
-  //   structure, which may be referenced by using the __flags_masks 
-  //   enumeration. These flags refer to both direct and indirect bases. 
-  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_count is a word with the number of direct proper base class 
-  //   descriptions that follow.
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
-  
-  if (!RD->getNumBases())
-    return;
-  
-  llvm::Type *LongLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
-
-  // Now add the base class descriptions.
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_info[] is an array of base class descriptions -- one for every 
-  //   direct proper base. Each description is of the type:
-  //
-  //   struct abi::__base_class_type_info {
-  //   public:
-  //     const __class_type_info *__base_type;
-  //     long __offset_flags;
-  //
-  //     enum __offset_flags_masks {
-  //       __virtual_mask = 0x1,
-  //       __public_mask = 0x2,
-  //       __offset_shift = 8
-  //     };
-  //   };
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXBaseSpecifier *Base = I;
-
-    // The __base_type member points to the RTTI for the base type.
-    Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(Base->getType()));
-
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-
-    int64_t OffsetFlags = 0;
-    
-    // All but the lower 8 bits of __offset_flags are a signed offset. 
-    // For a non-virtual base, this is the offset in the object of the base
-    // subobject. For a virtual base, this is the offset in the virtual table of
-    // the virtual base offset for the virtual base referenced (negative).
-    CharUnits Offset;
-    if (Base->isVirtual())
-      Offset = 
-        CGM.getVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
-    else {
-      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-      Offset = Layout.getBaseClassOffset(BaseDecl);
-    };
-    
-    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
-    
-    // The low-order byte of __offset_flags contains flags, as given by the 
-    // masks from the enumeration __offset_flags_masks.
-    if (Base->isVirtual())
-      OffsetFlags |= BCTI_Virtual;
-    if (Base->getAccessSpecifier() == AS_public)
-      OffsetFlags |= BCTI_Public;
-
-    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
-  }
-}
-
-/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
-/// used for pointer types.
-void RTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {  
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //  __pointee is a pointer to the std::type_info derivation for the 
-  //  unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-}
-
-/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-/// struct, used for member pointer types.
-void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
-  QualType PointeeTy = Ty->getPointeeType();
-  
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to.
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  if (IsIncompleteClassType(ClassType))
-    Flags |= PTI_ContainingClassIncomplete;
-  
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __pointee is a pointer to the std::type_info derivation for the 
-  //   unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-
-  // Itanium C++ ABI 2.9.5p9:
-  //   __context is a pointer to an abi::__class_type_info corresponding to the
-  //   class type containing the member pointed to 
-  //   (e.g., the "A" in "int A::*").
-  Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
-                                                       bool ForEH) {
-  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
-  // FIXME: should we even be calling this method if RTTI is disabled
-  // and it's not for EH?
-  if (!ForEH && !getLangOpts().RTTI)
-    return llvm::Constant::getNullValue(Int8PtrTy);
-  
-  if (ForEH && Ty->isObjCObjectPointerType() &&
-      LangOpts.ObjCRuntime.isGNUFamily())
-    return ObjCRuntime->GetEHType(Ty);
-
-  return RTTIBuilder(*this).BuildTypeInfo(Ty);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
-  QualType PointerType = Context.getPointerType(Type);
-  QualType PointerTypeConst = Context.getPointerType(Type.withConst());
-  RTTIBuilder(*this).BuildTypeInfo(Type, true);
-  RTTIBuilder(*this).BuildTypeInfo(PointerType, true);
-  RTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptors() {
-  QualType FundamentalTypes[] = { Context.VoidTy, Context.NullPtrTy,
-                                  Context.BoolTy, Context.WCharTy,
-                                  Context.CharTy, Context.UnsignedCharTy,
-                                  Context.SignedCharTy, Context.ShortTy, 
-                                  Context.UnsignedShortTy, Context.IntTy,
-                                  Context.UnsignedIntTy, Context.LongTy, 
-                                  Context.UnsignedLongTy, Context.LongLongTy, 
-                                  Context.UnsignedLongLongTy, Context.FloatTy,
-                                  Context.DoubleTy, Context.LongDoubleTy,
-                                  Context.Char16Ty, Context.Char32Ty };
-  for (unsigned i = 0; i < sizeof(FundamentalTypes)/sizeof(QualType); ++i)
-    EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);
-}
+//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This contains code dealing with C++ code generation of RTTI descriptors.

+//

+//===----------------------------------------------------------------------===//

+

+#include "CodeGenModule.h"

+#include "CGCXXABI.h"

+#include "CGObjCRuntime.h"

+#include "clang/AST/RecordLayout.h"

+#include "clang/AST/Type.h"

+#include "clang/Frontend/CodeGenOptions.h"

+

+using namespace clang;

+using namespace CodeGen;

+

+namespace {

+class RTTIBuilder {

+  CodeGenModule &CGM;  // Per-module state.

+  llvm::LLVMContext &VMContext;

+  

+  /// Fields - The fields of the RTTI descriptor currently being built.

+  SmallVector<llvm::Constant *, 16> Fields;

+

+  /// GetAddrOfTypeName - Returns the mangled type name of the given type.

+  llvm::GlobalVariable *

+  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);

+

+  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 

+  /// descriptor of the given type.

+  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);

+  

+  /// BuildVTablePointer - Build the vtable pointer for the given type.

+  void BuildVTablePointer(const Type *Ty);

+  

+  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single

+  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.

+  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);

+  

+  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for

+  /// classes with bases that do not satisfy the abi::__si_class_type_info 

+  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.

+  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);

+  

+  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used

+  /// for pointer types.

+  void BuildPointerTypeInfo(QualType PointeeTy);

+

+  /// BuildObjCObjectTypeInfo - Build the appropriate kind of

+  /// type_info for an object type.

+  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);

+  

+  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 

+  /// struct, used for member pointer types.

+  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);

+  

+public:

+  RTTIBuilder(CodeGenModule &CGM) : CGM(CGM), 

+    VMContext(CGM.getModule().getContext()) { }

+

+  // Pointer type info flags.

+  enum {

+    /// PTI_Const - Type has const qualifier.

+    PTI_Const = 0x1,

+    

+    /// PTI_Volatile - Type has volatile qualifier.

+    PTI_Volatile = 0x2,

+    

+    /// PTI_Restrict - Type has restrict qualifier.

+    PTI_Restrict = 0x4,

+    

+    /// PTI_Incomplete - Type is incomplete.

+    PTI_Incomplete = 0x8,

+    

+    /// PTI_ContainingClassIncomplete - Containing class is incomplete.

+    /// (in pointer to member).

+    PTI_ContainingClassIncomplete = 0x10

+  };

+  

+  // VMI type info flags.

+  enum {

+    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.

+    VMI_NonDiamondRepeat = 0x1,

+    

+    /// VMI_DiamondShaped - Class is diamond shaped.

+    VMI_DiamondShaped = 0x2

+  };

+  

+  // Base class type info flags.

+  enum {

+    /// BCTI_Virtual - Base class is virtual.

+    BCTI_Virtual = 0x1,

+    

+    /// BCTI_Public - Base class is public.

+    BCTI_Public = 0x2

+  };

+  

+  /// BuildTypeInfo - Build the RTTI type info struct for the given type.

+  ///

+  /// \param Force - true to force the creation of this RTTI value

+  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);

+};

+}

+

+llvm::GlobalVariable *

+RTTIBuilder::GetAddrOfTypeName(QualType Ty, 

+                               llvm::GlobalVariable::LinkageTypes Linkage) {

+  SmallString<256> OutName;

+  llvm::raw_svector_ostream Out(OutName);

+  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);

+  Out.flush();

+  StringRef Name = OutName.str();

+

+  // We know that the mangled name of the type starts at index 4 of the

+  // mangled name of the typename, so we can just index into it in order to

+  // get the mangled name of the type.

+  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,

+                                                            Name.substr(4));

+

+  llvm::GlobalVariable *GV = 

+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);

+

+  GV->setInitializer(Init);

+

+  return GV;

+}

+

+llvm::Constant *RTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {

+  // Mangle the RTTI name.

+  SmallString<256> OutName;

+  llvm::raw_svector_ostream Out(OutName);

+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);

+  Out.flush();

+  StringRef Name = OutName.str();

+

+  // Look for an existing global.

+  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);

+  

+  if (!GV) {

+    // Create a new global variable.

+    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,

+                                  /*Constant=*/true,

+                                  llvm::GlobalValue::ExternalLinkage, 0, Name);

+  }

+  

+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);

+}

+

+/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type

+/// info for that type is defined in the standard library.

+static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {

+  // Itanium C++ ABI 2.9.2:

+  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in

+  //   the run-time support library. Specifically, the run-time support

+  //   library should contain type_info objects for the types X, X* and 

+  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,

+  //   unsigned char, signed char, short, unsigned short, int, unsigned int,

+  //   long, unsigned long, long long, unsigned long long, float, double,

+  //   long double, char16_t, char32_t, and the IEEE 754r decimal and 

+  //   half-precision floating point types.

+  switch (Ty->getKind()) {

+    case BuiltinType::Void:

+    case BuiltinType::NullPtr:

+    case BuiltinType::Bool:

+    case BuiltinType::WChar_S:

+    case BuiltinType::WChar_U:

+    case BuiltinType::Char_U:

+    case BuiltinType::Char_S:

+    case BuiltinType::UChar:

+    case BuiltinType::SChar:

+    case BuiltinType::Short:

+    case BuiltinType::UShort:

+    case BuiltinType::Int:

+    case BuiltinType::UInt:

+    case BuiltinType::Long:

+    case BuiltinType::ULong:

+    case BuiltinType::LongLong:

+    case BuiltinType::ULongLong:

+    case BuiltinType::Half:

+    case BuiltinType::Float:

+    case BuiltinType::Double:

+    case BuiltinType::LongDouble:

+    case BuiltinType::Char16:

+    case BuiltinType::Char32:

+    case BuiltinType::Int128:

+    case BuiltinType::UInt128:

+    case BuiltinType::OCLImage1d:

+    case BuiltinType::OCLImage1dArray:

+    case BuiltinType::OCLImage1dBuffer:

+    case BuiltinType::OCLImage2d:

+    case BuiltinType::OCLImage2dArray:

+    case BuiltinType::OCLImage3d:

+      return true;

+      

+    case BuiltinType::Dependent:

+#define BUILTIN_TYPE(Id, SingletonId)

+#define PLACEHOLDER_TYPE(Id, SingletonId) \

+    case BuiltinType::Id:

+#include "clang/AST/BuiltinTypes.def"

+      llvm_unreachable("asking for RRTI for a placeholder type!");

+      

+    case BuiltinType::ObjCId:

+    case BuiltinType::ObjCClass:

+    case BuiltinType::ObjCSel:

+      llvm_unreachable("FIXME: Objective-C types are unsupported!");

+  }

+

+  llvm_unreachable("Invalid BuiltinType Kind!");

+}

+

+static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {

+  QualType PointeeTy = PointerTy->getPointeeType();

+  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);

+  if (!BuiltinTy)

+    return false;

+    

+  // Check the qualifiers.

+  Qualifiers Quals = PointeeTy.getQualifiers();

+  Quals.removeConst();

+    

+  if (!Quals.empty())

+    return false;

+    

+  return TypeInfoIsInStandardLibrary(BuiltinTy);

+}

+

+/// IsStandardLibraryRTTIDescriptor - Returns whether the type

+/// information for the given type exists in the standard library.

+static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {

+  // Type info for builtin types is defined in the standard library.

+  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))

+    return TypeInfoIsInStandardLibrary(BuiltinTy);

+  

+  // Type info for some pointer types to builtin types is defined in the

+  // standard library.

+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))

+    return TypeInfoIsInStandardLibrary(PointerTy);

+

+  return false;

+}

+

+/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for

+/// the given type exists somewhere else, and that we should not emit the type

+/// information in this translation unit.  Assumes that it is not a

+/// standard-library type.

+static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) {

+  ASTContext &Context = CGM.getContext();

+

+  // If RTTI is disabled, don't consider key functions.

+  if (!Context.getLangOpts().RTTI) return false;

+

+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {

+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());

+    if (!RD->hasDefinition())

+      return false;

+

+    if (!RD->isDynamicClass())

+      return false;

+

+    return !CGM.getVTables().ShouldEmitVTableInThisTU(RD);

+  }

+  

+  return false;

+}

+

+/// IsIncompleteClassType - Returns whether the given record type is incomplete.

+static bool IsIncompleteClassType(const RecordType *RecordTy) {

+  return !RecordTy->getDecl()->isCompleteDefinition();

+}  

+

+/// ContainsIncompleteClassType - Returns whether the given type contains an

+/// incomplete class type. This is true if

+///

+///   * The given type is an incomplete class type.

+///   * The given type is a pointer type whose pointee type contains an 

+///     incomplete class type.

+///   * The given type is a member pointer type whose class is an incomplete

+///     class type.

+///   * The given type is a member pointer type whoise pointee type contains an

+///     incomplete class type.

+/// is an indirect or direct pointer to an incomplete class type.

+static bool ContainsIncompleteClassType(QualType Ty) {

+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {

+    if (IsIncompleteClassType(RecordTy))

+      return true;

+  }

+  

+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))

+    return ContainsIncompleteClassType(PointerTy->getPointeeType());

+  

+  if (const MemberPointerType *MemberPointerTy = 

+      dyn_cast<MemberPointerType>(Ty)) {

+    // Check if the class type is incomplete.

+    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());

+    if (IsIncompleteClassType(ClassType))

+      return true;

+    

+    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());

+  }

+  

+  return false;

+}

+

+/// getTypeInfoLinkage - Return the linkage that the type info and type info

+/// name constants should have for the given type.

+static llvm::GlobalVariable::LinkageTypes 

+getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) {

+  // Itanium C++ ABI 2.9.5p7:

+  //   In addition, it and all of the intermediate abi::__pointer_type_info 

+  //   structs in the chain down to the abi::__class_type_info for the

+  //   incomplete class type must be prevented from resolving to the 

+  //   corresponding type_info structs for the complete class type, possibly

+  //   by making them local static objects. Finally, a dummy class RTTI is

+  //   generated for the incomplete type that will not resolve to the final 

+  //   complete class RTTI (because the latter need not exist), possibly by 

+  //   making it a local static object.

+  if (ContainsIncompleteClassType(Ty))

+    return llvm::GlobalValue::InternalLinkage;

+  

+  switch (Ty->getLinkage()) {

+  case NoLinkage:

+  case InternalLinkage:

+  case UniqueExternalLinkage:

+    return llvm::GlobalValue::InternalLinkage;

+

+  case ExternalLinkage:

+    if (!CGM.getLangOpts().RTTI) {

+      // RTTI is not enabled, which means that this type info struct is going

+      // to be used for exception handling. Give it linkonce_odr linkage.

+      return llvm::GlobalValue::LinkOnceODRLinkage;

+    }

+

+    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {

+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());

+      if (RD->hasAttr<WeakAttr>())

+        return llvm::GlobalValue::WeakODRLinkage;

+      if (RD->isDynamicClass())

+        return CGM.getVTableLinkage(RD);

+    }

+

+    return llvm::GlobalValue::LinkOnceODRLinkage;

+  }

+

+  llvm_unreachable("Invalid linkage!");

+}

+

+// CanUseSingleInheritance - Return whether the given record decl has a "single, 

+// public, non-virtual base at offset zero (i.e. the derived class is dynamic 

+// iff the base is)", according to Itanium C++ ABI, 2.95p6b.

+static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {

+  // Check the number of bases.

+  if (RD->getNumBases() != 1)

+    return false;

+  

+  // Get the base.

+  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();

+  

+  // Check that the base is not virtual.

+  if (Base->isVirtual())

+    return false;

+  

+  // Check that the base is public.

+  if (Base->getAccessSpecifier() != AS_public)

+    return false;

+  

+  // Check that the class is dynamic iff the base is.

+  const CXXRecordDecl *BaseDecl = 

+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());

+  if (!BaseDecl->isEmpty() && 

+      BaseDecl->isDynamicClass() != RD->isDynamicClass())

+    return false;

+  

+  return true;

+}

+

+void RTTIBuilder::BuildVTablePointer(const Type *Ty) {

+  // abi::__class_type_info.

+  static const char * const ClassTypeInfo =

+    "_ZTVN10__cxxabiv117__class_type_infoE";

+  // abi::__si_class_type_info.

+  static const char * const SIClassTypeInfo =

+    "_ZTVN10__cxxabiv120__si_class_type_infoE";

+  // abi::__vmi_class_type_info.

+  static const char * const VMIClassTypeInfo =

+    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";

+

+  const char *VTableName = 0;

+

+  switch (Ty->getTypeClass()) {

+#define TYPE(Class, Base)

+#define ABSTRACT_TYPE(Class, Base)

+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:

+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:

+#define DEPENDENT_TYPE(Class, Base) case Type::Class:

+#include "clang/AST/TypeNodes.def"

+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");

+

+  case Type::LValueReference:

+  case Type::RValueReference:

+    llvm_unreachable("References shouldn't get here");

+

+  case Type::Builtin:

+  // GCC treats vector and complex types as fundamental types.

+  case Type::Vector:

+  case Type::ExtVector:

+  case Type::Complex:

+  case Type::Atomic:

+  // FIXME: GCC treats block pointers as fundamental types?!

+  case Type::BlockPointer:

+    // abi::__fundamental_type_info.

+    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";

+    break;

+

+  case Type::ConstantArray:

+  case Type::IncompleteArray:

+  case Type::VariableArray:

+    // abi::__array_type_info.

+    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";

+    break;

+

+  case Type::FunctionNoProto:

+  case Type::FunctionProto:

+    // abi::__function_type_info.

+    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";

+    break;

+

+  case Type::Enum:

+    // abi::__enum_type_info.

+    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";

+    break;

+

+  case Type::Record: {

+    const CXXRecordDecl *RD = 

+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());

+    

+    if (!RD->hasDefinition() || !RD->getNumBases()) {

+      VTableName = ClassTypeInfo;

+    } else if (CanUseSingleInheritance(RD)) {

+      VTableName = SIClassTypeInfo;

+    } else {

+      VTableName = VMIClassTypeInfo;

+    }

+    

+    break;

+  }

+

+  case Type::ObjCObject:

+    // Ignore protocol qualifiers.

+    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();

+

+    // Handle id and Class.

+    if (isa<BuiltinType>(Ty)) {

+      VTableName = ClassTypeInfo;

+      break;

+    }

+

+    assert(isa<ObjCInterfaceType>(Ty));

+    // Fall through.

+

+  case Type::ObjCInterface:

+    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {

+      VTableName = SIClassTypeInfo;

+    } else {

+      VTableName = ClassTypeInfo;

+    }

+    break;

+

+  case Type::ObjCObjectPointer:

+  case Type::Pointer:

+    // abi::__pointer_type_info.

+    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";

+    break;

+

+  case Type::MemberPointer:

+    // abi::__pointer_to_member_type_info.

+    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";

+    break;

+  }

+

+  llvm::Constant *VTable = 

+    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);

+    

+  llvm::Type *PtrDiffTy = 

+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());

+

+  // The vtable address point is 2.

+  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);

+  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);

+  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);

+

+  Fields.push_back(VTable);

+}

+

+// maybeUpdateRTTILinkage - Will update the linkage of the RTTI data structures

+// from available_externally to the correct linkage if necessary. An example of

+// this is:

+//

+//   struct A {

+//     virtual void f();

+//   };

+//

+//   const std::type_info &g() {

+//     return typeid(A);

+//   }

+//

+//   void A::f() { }

+//

+// When we're generating the typeid(A) expression, we do not yet know that

+// A's key function is defined in this translation unit, so we will give the

+// typeinfo and typename structures available_externally linkage. When A::f

+// forces the vtable to be generated, we need to change the linkage of the

+// typeinfo and typename structs, otherwise we'll end up with undefined

+// externals when linking.

+static void 

+maybeUpdateRTTILinkage(CodeGenModule &CGM, llvm::GlobalVariable *GV,

+                       QualType Ty) {

+  // We're only interested in globals with available_externally linkage.

+  if (!GV->hasAvailableExternallyLinkage())

+    return;

+

+  // Get the real linkage for the type.

+  llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty);

+

+  // If variable is supposed to have available_externally linkage, we don't

+  // need to do anything.

+  if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)

+    return;

+

+  // Update the typeinfo linkage.

+  GV->setLinkage(Linkage);

+

+  // Get the typename global.

+  SmallString<256> OutName;

+  llvm::raw_svector_ostream Out(OutName);

+  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);

+  Out.flush();

+  StringRef Name = OutName.str();

+

+  llvm::GlobalVariable *TypeNameGV = CGM.getModule().getNamedGlobal(Name);

+

+  assert(TypeNameGV->hasAvailableExternallyLinkage() &&

+         "Type name has different linkage from type info!");

+

+  // And update its linkage.

+  TypeNameGV->setLinkage(Linkage);

+}

+

+llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {

+  // We want to operate on the canonical type.

+  Ty = CGM.getContext().getCanonicalType(Ty);

+

+  // Check if we've already emitted an RTTI descriptor for this type.

+  SmallString<256> OutName;

+  llvm::raw_svector_ostream Out(OutName);

+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);

+  Out.flush();

+  StringRef Name = OutName.str();

+

+  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);

+  if (OldGV && !OldGV->isDeclaration()) {

+    maybeUpdateRTTILinkage(CGM, OldGV, Ty);

+

+    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);

+  }

+

+  // Check if there is already an external RTTI descriptor for this type.

+  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);

+  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))

+    return GetAddrOfExternalRTTIDescriptor(Ty);

+

+  // Emit the standard library with external linkage.

+  llvm::GlobalVariable::LinkageTypes Linkage;

+  if (IsStdLib)

+    Linkage = llvm::GlobalValue::ExternalLinkage;

+  else

+    Linkage = getTypeInfoLinkage(CGM, Ty);

+

+  // Add the vtable pointer.

+  BuildVTablePointer(cast<Type>(Ty));

+  

+  // And the name.

+  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);

+

+  Fields.push_back(llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy));

+

+  switch (Ty->getTypeClass()) {

+#define TYPE(Class, Base)

+#define ABSTRACT_TYPE(Class, Base)

+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:

+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:

+#define DEPENDENT_TYPE(Class, Base) case Type::Class:

+#include "clang/AST/TypeNodes.def"

+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");

+

+  // GCC treats vector types as fundamental types.

+  case Type::Builtin:

+  case Type::Vector:

+  case Type::ExtVector:

+  case Type::Complex:

+  case Type::BlockPointer:

+    // Itanium C++ ABI 2.9.5p4:

+    // abi::__fundamental_type_info adds no data members to std::type_info.

+    break;

+

+  case Type::LValueReference:

+  case Type::RValueReference:

+    llvm_unreachable("References shouldn't get here");

+

+  case Type::ConstantArray:

+  case Type::IncompleteArray:

+  case Type::VariableArray:

+    // Itanium C++ ABI 2.9.5p5:

+    // abi::__array_type_info adds no data members to std::type_info.

+    break;

+

+  case Type::FunctionNoProto:

+  case Type::FunctionProto:

+    // Itanium C++ ABI 2.9.5p5:

+    // abi::__function_type_info adds no data members to std::type_info.

+    break;

+

+  case Type::Enum:

+    // Itanium C++ ABI 2.9.5p5:

+    // abi::__enum_type_info adds no data members to std::type_info.

+    break;

+

+  case Type::Record: {

+    const CXXRecordDecl *RD = 

+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());

+    if (!RD->hasDefinition() || !RD->getNumBases()) {

+      // We don't need to emit any fields.

+      break;

+    }

+    

+    if (CanUseSingleInheritance(RD))

+      BuildSIClassTypeInfo(RD);

+    else 

+      BuildVMIClassTypeInfo(RD);

+

+    break;

+  }

+

+  case Type::ObjCObject:

+  case Type::ObjCInterface:

+    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));

+    break;

+

+  case Type::ObjCObjectPointer:

+    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());

+    break; 

+      

+  case Type::Pointer:

+    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());

+    break;

+

+  case Type::MemberPointer:

+    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));

+    break;

+

+  case Type::Atomic:

+    // No fields, at least for the moment.

+    break;

+  }

+

+  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);

+

+  llvm::GlobalVariable *GV = 

+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 

+                             /*Constant=*/true, Linkage, Init, Name);

+  

+  // If there's already an old global variable, replace it with the new one.

+  if (OldGV) {

+    GV->takeName(OldGV);

+    llvm::Constant *NewPtr = 

+      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());

+    OldGV->replaceAllUsesWith(NewPtr);

+    OldGV->eraseFromParent();

+  }

+

+  // GCC only relies on the uniqueness of the type names, not the

+  // type_infos themselves, so we can emit these as hidden symbols.

+  // But don't do this if we're worried about strict visibility

+  // compatibility.

+  if (const RecordType *RT = dyn_cast<RecordType>(Ty)) {

+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());

+

+    CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForRTTI);

+    CGM.setTypeVisibility(TypeName, RD, CodeGenModule::TVK_ForRTTIName);

+  } else {

+    Visibility TypeInfoVisibility = DefaultVisibility;

+    if (CGM.getCodeGenOpts().HiddenWeakVTables &&

+        Linkage == llvm::GlobalValue::LinkOnceODRLinkage)

+      TypeInfoVisibility = HiddenVisibility;

+

+    // The type name should have the same visibility as the type itself.

+    Visibility ExplicitVisibility = Ty->getVisibility();

+    TypeName->setVisibility(CodeGenModule::

+                            GetLLVMVisibility(ExplicitVisibility));

+  

+    TypeInfoVisibility = minVisibility(TypeInfoVisibility, Ty->getVisibility());

+    GV->setVisibility(CodeGenModule::GetLLVMVisibility(TypeInfoVisibility));

+  }

+

+  GV->setUnnamedAddr(true);

+

+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);

+}

+

+/// ComputeQualifierFlags - Compute the pointer type info flags from the

+/// given qualifier.

+static unsigned ComputeQualifierFlags(Qualifiers Quals) {

+  unsigned Flags = 0;

+

+  if (Quals.hasConst())

+    Flags |= RTTIBuilder::PTI_Const;

+  if (Quals.hasVolatile())

+    Flags |= RTTIBuilder::PTI_Volatile;

+  if (Quals.hasRestrict())

+    Flags |= RTTIBuilder::PTI_Restrict;

+

+  return Flags;

+}

+

+/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info

+/// for the given Objective-C object type.

+void RTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {

+  // Drop qualifiers.

+  const Type *T = OT->getBaseType().getTypePtr();

+  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));

+

+  // The builtin types are abi::__class_type_infos and don't require

+  // extra fields.

+  if (isa<BuiltinType>(T)) return;

+

+  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();

+  ObjCInterfaceDecl *Super = Class->getSuperClass();

+

+  // Root classes are also __class_type_info.

+  if (!Super) return;

+

+  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);

+

+  // Everything else is single inheritance.

+  llvm::Constant *BaseTypeInfo = RTTIBuilder(CGM).BuildTypeInfo(SuperTy);

+  Fields.push_back(BaseTypeInfo);

+}

+

+/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single

+/// inheritance, according to the Itanium C++ ABI, 2.95p6b.

+void RTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {

+  // Itanium C++ ABI 2.9.5p6b:

+  // It adds to abi::__class_type_info a single member pointing to the 

+  // type_info structure for the base type,

+  llvm::Constant *BaseTypeInfo = 

+    RTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());

+  Fields.push_back(BaseTypeInfo);

+}

+

+namespace {

+  /// SeenBases - Contains virtual and non-virtual bases seen when traversing

+  /// a class hierarchy.

+  struct SeenBases {

+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;

+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;

+  };

+}

+

+/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in

+/// abi::__vmi_class_type_info.

+///

+static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 

+                                             SeenBases &Bases) {

+  

+  unsigned Flags = 0;

+  

+  const CXXRecordDecl *BaseDecl = 

+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());

+  

+  if (Base->isVirtual()) {

+    // Mark the virtual base as seen.

+    if (!Bases.VirtualBases.insert(BaseDecl)) {

+      // If this virtual base has been seen before, then the class is diamond

+      // shaped.

+      Flags |= RTTIBuilder::VMI_DiamondShaped;

+    } else {

+      if (Bases.NonVirtualBases.count(BaseDecl))

+        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;

+    }

+  } else {

+    // Mark the non-virtual base as seen.

+    if (!Bases.NonVirtualBases.insert(BaseDecl)) {

+      // If this non-virtual base has been seen before, then the class has non-

+      // diamond shaped repeated inheritance.

+      Flags |= RTTIBuilder::VMI_NonDiamondRepeat;

+    } else {

+      if (Bases.VirtualBases.count(BaseDecl))

+        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;

+    }

+  }

+

+  // Walk all bases.

+  for (CXXRecordDecl::base_class_const_iterator I = BaseDecl->bases_begin(),

+       E = BaseDecl->bases_end(); I != E; ++I) 

+    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);

+  

+  return Flags;

+}

+

+static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {

+  unsigned Flags = 0;

+  SeenBases Bases;

+  

+  // Walk all bases.

+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),

+       E = RD->bases_end(); I != E; ++I) 

+    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);

+  

+  return Flags;

+}

+

+/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for

+/// classes with bases that do not satisfy the abi::__si_class_type_info 

+/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.

+void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {

+  llvm::Type *UnsignedIntLTy = 

+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);

+  

+  // Itanium C++ ABI 2.9.5p6c:

+  //   __flags is a word with flags describing details about the class 

+  //   structure, which may be referenced by using the __flags_masks 

+  //   enumeration. These flags refer to both direct and indirect bases. 

+  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);

+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));

+

+  // Itanium C++ ABI 2.9.5p6c:

+  //   __base_count is a word with the number of direct proper base class 

+  //   descriptions that follow.

+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));

+  

+  if (!RD->getNumBases())

+    return;

+  

+  llvm::Type *LongLTy = 

+    CGM.getTypes().ConvertType(CGM.getContext().LongTy);

+

+  // Now add the base class descriptions.

+  

+  // Itanium C++ ABI 2.9.5p6c:

+  //   __base_info[] is an array of base class descriptions -- one for every 

+  //   direct proper base. Each description is of the type:

+  //

+  //   struct abi::__base_class_type_info {

+  //   public:

+  //     const __class_type_info *__base_type;

+  //     long __offset_flags;

+  //

+  //     enum __offset_flags_masks {

+  //       __virtual_mask = 0x1,

+  //       __public_mask = 0x2,

+  //       __offset_shift = 8

+  //     };

+  //   };

+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),

+       E = RD->bases_end(); I != E; ++I) {

+    const CXXBaseSpecifier *Base = I;

+

+    // The __base_type member points to the RTTI for the base type.

+    Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(Base->getType()));

+

+    const CXXRecordDecl *BaseDecl = 

+      cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());

+

+    int64_t OffsetFlags = 0;

+    

+    // All but the lower 8 bits of __offset_flags are a signed offset. 

+    // For a non-virtual base, this is the offset in the object of the base

+    // subobject. For a virtual base, this is the offset in the virtual table of

+    // the virtual base offset for the virtual base referenced (negative).

+    CharUnits Offset;

+    if (Base->isVirtual())

+      Offset = 

+        CGM.getVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);

+    else {

+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);

+      Offset = Layout.getBaseClassOffset(BaseDecl);

+    };

+    

+    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;

+    

+    // The low-order byte of __offset_flags contains flags, as given by the 

+    // masks from the enumeration __offset_flags_masks.

+    if (Base->isVirtual())

+      OffsetFlags |= BCTI_Virtual;

+    if (Base->getAccessSpecifier() == AS_public)

+      OffsetFlags |= BCTI_Public;

+

+    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));

+  }

+}

+

+/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,

+/// used for pointer types.

+void RTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {  

+  Qualifiers Quals;

+  QualType UnqualifiedPointeeTy = 

+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);

+  

+  // Itanium C++ ABI 2.9.5p7:

+  //   __flags is a flag word describing the cv-qualification and other 

+  //   attributes of the type pointed to

+  unsigned Flags = ComputeQualifierFlags(Quals);

+

+  // Itanium C++ ABI 2.9.5p7:

+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an

+  //   incomplete class type, the incomplete target type flag is set. 

+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))

+    Flags |= PTI_Incomplete;

+

+  llvm::Type *UnsignedIntLTy = 

+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);

+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));

+  

+  // Itanium C++ ABI 2.9.5p7:

+  //  __pointee is a pointer to the std::type_info derivation for the 

+  //  unqualified type being pointed to.

+  llvm::Constant *PointeeTypeInfo = 

+    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);

+  Fields.push_back(PointeeTypeInfo);

+}

+

+/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 

+/// struct, used for member pointer types.

+void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {

+  QualType PointeeTy = Ty->getPointeeType();

+  

+  Qualifiers Quals;

+  QualType UnqualifiedPointeeTy = 

+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);

+  

+  // Itanium C++ ABI 2.9.5p7:

+  //   __flags is a flag word describing the cv-qualification and other 

+  //   attributes of the type pointed to.

+  unsigned Flags = ComputeQualifierFlags(Quals);

+

+  const RecordType *ClassType = cast<RecordType>(Ty->getClass());

+

+  // Itanium C++ ABI 2.9.5p7:

+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an

+  //   incomplete class type, the incomplete target type flag is set. 

+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))

+    Flags |= PTI_Incomplete;

+

+  if (IsIncompleteClassType(ClassType))

+    Flags |= PTI_ContainingClassIncomplete;

+  

+  llvm::Type *UnsignedIntLTy = 

+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);

+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));

+  

+  // Itanium C++ ABI 2.9.5p7:

+  //   __pointee is a pointer to the std::type_info derivation for the 

+  //   unqualified type being pointed to.

+  llvm::Constant *PointeeTypeInfo = 

+    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);

+  Fields.push_back(PointeeTypeInfo);

+

+  // Itanium C++ ABI 2.9.5p9:

+  //   __context is a pointer to an abi::__class_type_info corresponding to the

+  //   class type containing the member pointed to 

+  //   (e.g., the "A" in "int A::*").

+  Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));

+}

+

+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,

+                                                       bool ForEH) {

+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.

+  // FIXME: should we even be calling this method if RTTI is disabled

+  // and it's not for EH?

+  if (!ForEH && !getLangOpts().RTTI)

+    return llvm::Constant::getNullValue(Int8PtrTy);

+  

+  if (ForEH && Ty->isObjCObjectPointerType() &&

+      LangOpts.ObjCRuntime.isGNUFamily())

+    return ObjCRuntime->GetEHType(Ty);

+

+  return RTTIBuilder(*this).BuildTypeInfo(Ty);

+}

+

+void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {

+  QualType PointerType = Context.getPointerType(Type);

+  QualType PointerTypeConst = Context.getPointerType(Type.withConst());

+  RTTIBuilder(*this).BuildTypeInfo(Type, true);

+  RTTIBuilder(*this).BuildTypeInfo(PointerType, true);

+  RTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);

+}

+

+void CodeGenModule::EmitFundamentalRTTIDescriptors() {

+  QualType FundamentalTypes[] = { Context.VoidTy, Context.NullPtrTy,

+                                  Context.BoolTy, Context.WCharTy,

+                                  Context.CharTy, Context.UnsignedCharTy,

+                                  Context.SignedCharTy, Context.ShortTy, 

+                                  Context.UnsignedShortTy, Context.IntTy,

+                                  Context.UnsignedIntTy, Context.LongTy, 

+                                  Context.UnsignedLongTy, Context.LongLongTy, 

+                                  Context.UnsignedLongLongTy, Context.FloatTy,

+                                  Context.DoubleTy, Context.LongDoubleTy,

+                                  Context.Char16Ty, Context.Char32Ty };

+  for (unsigned i = 0; i < sizeof(FundamentalTypes)/sizeof(QualType); ++i)

+    EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);

+}

diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index a0effa8..8cb6dd0 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -14,6 +14,7 @@
 #include "CodeGenTypes.h"
 #include "CGCXXABI.h"
 #include "CGCall.h"
+#include "CGOpenCLRuntime.h"
 #include "CGRecordLayout.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -366,6 +367,15 @@
     case BuiltinType::Int128:
       ResultType = llvm::IntegerType::get(getLLVMContext(), 128);
       break;
+
+    case BuiltinType::OCLImage1d:
+    case BuiltinType::OCLImage1dArray:
+    case BuiltinType::OCLImage1dBuffer:
+    case BuiltinType::OCLImage2d:
+    case BuiltinType::OCLImage2dArray:
+    case BuiltinType::OCLImage3d:
+      ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
+      break;
     
     case BuiltinType::Dependent:
 #define BUILTIN_TYPE(Id, SingletonId)
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 518c8a07..390fd34 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2753,6 +2753,30 @@
     case tok::kw___pixel:
       isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
       break;
+    case tok::kw_image1d_t:
+       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc,
+                                      PrevSpec, DiagID);
+      break;
+    case tok::kw_image1d_array_t:
+       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc,
+                                      PrevSpec, DiagID);
+      break;
+    case tok::kw_image1d_buffer_t:
+       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc,
+                                      PrevSpec, DiagID);
+      break;
+    case tok::kw_image2d_t:
+       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc,
+                                      PrevSpec, DiagID);
+      break;
+    case tok::kw_image2d_array_t:
+       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc,
+                                      PrevSpec, DiagID);
+      break;
+    case tok::kw_image3d_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
+                                     PrevSpec, DiagID);
+      break;
     case tok::kw___unknown_anytype:
       isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
                                      PrevSpec, DiagID);
@@ -3596,6 +3620,14 @@
   case tok::kw__Decimal128:
   case tok::kw___vector:
 
+    // OpenCL specific types:
+  case tok::kw_image1d_t:
+  case tok::kw_image1d_array_t:
+  case tok::kw_image1d_buffer_t:
+  case tok::kw_image2d_t:
+  case tok::kw_image2d_array_t:
+  case tok::kw_image3d_t:
+
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
   case tok::kw_struct:
@@ -3668,6 +3700,14 @@
   case tok::kw__Decimal128:
   case tok::kw___vector:
 
+    // OpenCL specific types:
+  case tok::kw_image1d_t:
+  case tok::kw_image1d_array_t:
+  case tok::kw_image1d_buffer_t:
+  case tok::kw_image2d_t:
+  case tok::kw_image2d_array_t:
+  case tok::kw_image3d_t:
+
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
   case tok::kw_struct:
@@ -3812,6 +3852,14 @@
   case tok::kw__Decimal128:
   case tok::kw___vector:
 
+    // OpenCL specific types:
+  case tok::kw_image1d_t:
+  case tok::kw_image1d_array_t:
+  case tok::kw_image1d_buffer_t:
+  case tok::kw_image2d_t:
+  case tok::kw_image2d_array_t:
+  case tok::kw_image3d_t:
+
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
   case tok::kw_struct:
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 14980ee..b7705f8 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1078,7 +1078,13 @@
   case tok::kw_void:
   case tok::kw_typename:
   case tok::kw_typeof:
-  case tok::kw___vector: {
+  case tok::kw___vector:
+  case tok::kw_image1d_t:
+  case tok::kw_image1d_array_t:
+  case tok::kw_image1d_buffer_t:
+  case tok::kw_image2d_t:
+  case tok::kw_image2d_array_t:
+  case tok::kw_image3d_t: {
     if (!getLangOpts().CPlusPlus) {
       Diag(Tok, diag::err_expected_expression);
       return ExprError();
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index b26181f..e411899 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -1,1574 +1,1580 @@
-//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file implements the tentative parsing portions of the Parser
-//  interfaces, for ambiguity resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Sema/ParsedTemplate.h"
-using namespace clang;
-
-/// isCXXDeclarationStatement - C++-specialized function that disambiguates
-/// between a declaration or an expression statement, when parsing function
-/// bodies. Returns true for declaration, false for expression.
-///
-///         declaration-statement:
-///           block-declaration
-///
-///         block-declaration:
-///           simple-declaration
-///           asm-definition
-///           namespace-alias-definition
-///           using-declaration
-///           using-directive
-/// [C++0x]   static_assert-declaration
-///
-///         asm-definition:
-///           'asm' '(' string-literal ')' ';'
-///
-///         namespace-alias-definition:
-///           'namespace' identifier = qualified-namespace-specifier ';'
-///
-///         using-declaration:
-///           'using' typename[opt] '::'[opt] nested-name-specifier
-///                 unqualified-id ';'
-///           'using' '::' unqualified-id ;
-///
-///         using-directive:
-///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]
-///                 namespace-name ';'
-///
-bool Parser::isCXXDeclarationStatement() {
-  switch (Tok.getKind()) {
-    // asm-definition
-  case tok::kw_asm:
-    // namespace-alias-definition
-  case tok::kw_namespace:
-    // using-declaration
-    // using-directive
-  case tok::kw_using:
-    // static_assert-declaration
-  case tok::kw_static_assert:
-  case tok::kw__Static_assert:
-    return true;
-    // simple-declaration
-  default:
-    return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
-  }
-}
-
-/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
-/// between a simple-declaration or an expression-statement.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-/// Returns false if the statement is disambiguated as expression.
-///
-/// simple-declaration:
-///   decl-specifier-seq init-declarator-list[opt] ';'
-///
-/// (if AllowForRangeDecl specified)
-/// for ( for-range-declaration : for-range-initializer ) statement
-/// for-range-declaration: 
-///    attribute-specifier-seqopt type-specifier-seq declarator
-bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
-  // C++ 6.8p1:
-  // There is an ambiguity in the grammar involving expression-statements and
-  // declarations: An expression-statement with a function-style explicit type
-  // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
-  // from a declaration where the first declarator starts with a '('. In those
-  // cases the statement is a declaration. [Note: To disambiguate, the whole
-  // statement might have to be examined to determine if it is an
-  // expression-statement or a declaration].
-
-  // C++ 6.8p3:
-  // The disambiguation is purely syntactic; that is, the meaning of the names
-  // occurring in such a statement, beyond whether they are type-names or not,
-  // is not generally used in or changed by the disambiguation. Class
-  // templates are instantiated as necessary to determine if a qualified name
-  // is a type-name. Disambiguation precedes parsing, and a statement
-  // disambiguated as a declaration may be an ill-formed declaration.
-
-  // We don't have to parse all of the decl-specifier-seq part. There's only
-  // an ambiguity if the first decl-specifier is
-  // simple-type-specifier/typename-specifier followed by a '(', which may
-  // indicate a function-style cast expression.
-  // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
-  // a case.
-
-  bool InvalidAsDeclaration = false;
-  TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),
-                                           &InvalidAsDeclaration);
-  if (TPR != TPResult::Ambiguous())
-    return TPR != TPResult::False(); // Returns true for TPResult::True() or
-                                     // TPResult::Error().
-
-  // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
-  // and so gets some cases wrong. We can't carry on if we've already seen
-  // something which makes this statement invalid as a declaration in this case,
-  // since it can cause us to misparse valid code. Revisit this once
-  // TryParseInitDeclaratorList is fixed.
-  if (InvalidAsDeclaration)
-    return false;
-
-  // FIXME: Add statistics about the number of ambiguous statements encountered
-  // and how they were resolved (number of declarations+number of expressions).
-
-  // Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
-  // or an identifier which doesn't resolve as anything. We need tentative
-  // parsing...
-
-  TentativeParsingAction PA(*this);
-  TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
-  PA.Revert();
-
-  // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
-    return true;
-
-  // Declarations take precedence over expressions.
-  if (TPR == TPResult::Ambiguous())
-    TPR = TPResult::True();
-
-  assert(TPR == TPResult::True() || TPR == TPResult::False());
-  return TPR == TPResult::True();
-}
-
-/// simple-declaration:
-///   decl-specifier-seq init-declarator-list[opt] ';'
-///
-/// (if AllowForRangeDecl specified)
-/// for ( for-range-declaration : for-range-initializer ) statement
-/// for-range-declaration: 
-///    attribute-specifier-seqopt type-specifier-seq declarator
-///
-Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
-  if (Tok.is(tok::kw_typeof))
-    TryParseTypeofSpecifier();
-  else {
-    if (Tok.is(tok::annot_cxxscope))
-      ConsumeToken();
-    ConsumeToken();
-
-    if (getLangOpts().ObjC1 && Tok.is(tok::less))
-      TryParseProtocolQualifiers();
-  }
-
-  // Two decl-specifiers in a row conclusively disambiguate this as being a
-  // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
-  // overwhelmingly common case that the next token is a '('.
-  if (Tok.isNot(tok::l_paren)) {
-    TPResult TPR = isCXXDeclarationSpecifier();
-    if (TPR == TPResult::Ambiguous())
-      return TPResult::True();
-    if (TPR == TPResult::True() || TPR == TPResult::Error())
-      return TPR;
-    assert(TPR == TPResult::False());
-  }
-
-  TPResult TPR = TryParseInitDeclaratorList();
-  if (TPR != TPResult::Ambiguous())
-    return TPR;
-
-  if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
-    return TPResult::False();
-
-  return TPResult::Ambiguous();
-}
-
-///       init-declarator-list:
-///         init-declarator
-///         init-declarator-list ',' init-declarator
-///
-///       init-declarator:
-///         declarator initializer[opt]
-/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
-///
-/// initializer:
-///   '=' initializer-clause
-///   '(' expression-list ')'
-///
-/// initializer-clause:
-///   assignment-expression
-///   '{' initializer-list ','[opt] '}'
-///   '{' '}'
-///
-Parser::TPResult Parser::TryParseInitDeclaratorList() {
-  while (1) {
-    // declarator
-    TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
-    if (TPR != TPResult::Ambiguous())
-      return TPR;
-
-    // [GNU] simple-asm-expr[opt] attributes[opt]
-    if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
-      return TPResult::True();
-
-    // initializer[opt]
-    if (Tok.is(tok::l_paren)) {
-      // Parse through the parens.
-      ConsumeParen();
-      if (!SkipUntil(tok::r_paren))
-        return TPResult::Error();
-    } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
-      // MSVC and g++ won't examine the rest of declarators if '=' is 
-      // encountered; they just conclude that we have a declaration.
-      // EDG parses the initializer completely, which is the proper behavior
-      // for this case.
-      //
-      // At present, Clang follows MSVC and g++, since the parser does not have
-      // the ability to parse an expression fully without recording the
-      // results of that parse.
-      // Also allow 'in' after on objective-c declaration as in: 
-      // for (int (^b)(void) in array). Ideally this should be done in the 
-      // context of parsing for-init-statement of a foreach statement only. But,
-      // in any other context 'in' is invalid after a declaration and parser
-      // issues the error regardless of outcome of this decision.
-      // FIXME. Change if above assumption does not hold.
-      return TPResult::True();
-    }
-
-    if (Tok.isNot(tok::comma))
-      break;
-    ConsumeToken(); // the comma.
-  }
-
-  return TPResult::Ambiguous();
-}
-
-/// isCXXConditionDeclaration - Disambiguates between a declaration or an
-/// expression for a condition of a if/switch/while/for statement.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-///       condition:
-///         expression
-///         type-specifier-seq declarator '=' assignment-expression
-/// [C++11] type-specifier-seq declarator '=' initializer-clause
-/// [C++11] type-specifier-seq declarator braced-init-list
-/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
-///             '=' assignment-expression
-///
-bool Parser::isCXXConditionDeclaration() {
-  TPResult TPR = isCXXDeclarationSpecifier();
-  if (TPR != TPResult::Ambiguous())
-    return TPR != TPResult::False(); // Returns true for TPResult::True() or
-                                     // TPResult::Error().
-
-  // FIXME: Add statistics about the number of ambiguous statements encountered
-  // and how they were resolved (number of declarations+number of expressions).
-
-  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
-  // We need tentative parsing...
-
-  TentativeParsingAction PA(*this);
-
-  // type-specifier-seq
-  if (Tok.is(tok::kw_typeof))
-    TryParseTypeofSpecifier();
-  else {
-    ConsumeToken();
-    
-    if (getLangOpts().ObjC1 && Tok.is(tok::less))
-      TryParseProtocolQualifiers();
-  }
-  assert(Tok.is(tok::l_paren) && "Expected '('");
-
-  // declarator
-  TPR = TryParseDeclarator(false/*mayBeAbstract*/);
-
-  // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
-    TPR = TPResult::True();
-
-  if (TPR == TPResult::Ambiguous()) {
-    // '='
-    // [GNU] simple-asm-expr[opt] attributes[opt]
-    if (Tok.is(tok::equal)  ||
-        Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
-      TPR = TPResult::True();
-    else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace))
-      TPR = TPResult::True();
-    else
-      TPR = TPResult::False();
-  }
-
-  PA.Revert();
-
-  assert(TPR == TPResult::True() || TPR == TPResult::False());
-  return TPR == TPResult::True();
-}
-
-  /// \brief Determine whether the next set of tokens contains a type-id.
-  ///
-  /// The context parameter states what context we're parsing right
-  /// now, which affects how this routine copes with the token
-  /// following the type-id. If the context is TypeIdInParens, we have
-  /// already parsed the '(' and we will cease lookahead when we hit
-  /// the corresponding ')'. If the context is
-  /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
-  /// before this template argument, and will cease lookahead when we
-  /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id
-  /// and false for an expression.  If during the disambiguation
-  /// process a parsing error is encountered, the function returns
-  /// true to let the declaration parsing code handle it.
-  ///
-  /// type-id:
-  ///   type-specifier-seq abstract-declarator[opt]
-  ///
-bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
-
-  isAmbiguous = false;
-
-  // C++ 8.2p2:
-  // The ambiguity arising from the similarity between a function-style cast and
-  // a type-id can occur in different contexts. The ambiguity appears as a
-  // choice between a function-style cast expression and a declaration of a
-  // type. The resolution is that any construct that could possibly be a type-id
-  // in its syntactic context shall be considered a type-id.
-
-  TPResult TPR = isCXXDeclarationSpecifier();
-  if (TPR != TPResult::Ambiguous())
-    return TPR != TPResult::False(); // Returns true for TPResult::True() or
-                                     // TPResult::Error().
-
-  // FIXME: Add statistics about the number of ambiguous statements encountered
-  // and how they were resolved (number of declarations+number of expressions).
-
-  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
-  // We need tentative parsing...
-
-  TentativeParsingAction PA(*this);
-
-  // type-specifier-seq
-  if (Tok.is(tok::kw_typeof))
-    TryParseTypeofSpecifier();
-  else {
-    ConsumeToken();
-    
-    if (getLangOpts().ObjC1 && Tok.is(tok::less))
-      TryParseProtocolQualifiers();
-  }
-  
-  assert(Tok.is(tok::l_paren) && "Expected '('");
-
-  // declarator
-  TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
-
-  // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
-    TPR = TPResult::True();
-
-  if (TPR == TPResult::Ambiguous()) {
-    // We are supposed to be inside parens, so if after the abstract declarator
-    // we encounter a ')' this is a type-id, otherwise it's an expression.
-    if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
-      TPR = TPResult::True();
-      isAmbiguous = true;
-
-    // We are supposed to be inside a template argument, so if after
-    // the abstract declarator we encounter a '>', '>>' (in C++0x), or
-    // ',', this is a type-id. Otherwise, it's an expression.
-    } else if (Context == TypeIdAsTemplateArgument &&
-               (Tok.is(tok::greater) || Tok.is(tok::comma) ||
-                (getLangOpts().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
-      TPR = TPResult::True();
-      isAmbiguous = true;
-
-    } else
-      TPR = TPResult::False();
-  }
-
-  PA.Revert();
-
-  assert(TPR == TPResult::True() || TPR == TPResult::False());
-  return TPR == TPResult::True();
-}
-
-/// \brief Returns true if this is a C++11 attribute-specifier. Per
-/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens
-/// always introduce an attribute. In Objective-C++11, this rule does not
-/// apply if either '[' begins a message-send.
-///
-/// If Disambiguate is true, we try harder to determine whether a '[[' starts
-/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not.
-///
-/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an
-/// Obj-C message send or the start of an attribute. Otherwise, we assume it
-/// is not an Obj-C message send.
-///
-/// C++11 [dcl.attr.grammar]:
-///
-///     attribute-specifier:
-///         '[' '[' attribute-list ']' ']'
-///         alignment-specifier
-///
-///     attribute-list:
-///         attribute[opt]
-///         attribute-list ',' attribute[opt]
-///         attribute '...'
-///         attribute-list ',' attribute '...'
-///
-///     attribute:
-///         attribute-token attribute-argument-clause[opt]
-///
-///     attribute-token:
-///         identifier
-///         identifier '::' identifier
-///
-///     attribute-argument-clause:
-///         '(' balanced-token-seq ')'
-Parser::CXX11AttributeKind
-Parser::isCXX11AttributeSpecifier(bool Disambiguate,
-                                  bool OuterMightBeMessageSend) {
-  if (Tok.is(tok::kw_alignas))
-    return CAK_AttributeSpecifier;
-
-  if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
-    return CAK_NotAttributeSpecifier;
-
-  // No tentative parsing if we don't need to look for ']]' or a lambda.
-  if (!Disambiguate && !getLangOpts().ObjC1)
-    return CAK_AttributeSpecifier;
-
-  TentativeParsingAction PA(*this);
-
-  // Opening brackets were checked for above.
-  ConsumeBracket();
-
-  // Outside Obj-C++11, treat anything with a matching ']]' as an attribute.
-  if (!getLangOpts().ObjC1) {
-    ConsumeBracket();
-
-    bool IsAttribute = SkipUntil(tok::r_square, false);
-    IsAttribute &= Tok.is(tok::r_square);
-
-    PA.Revert();
-
-    return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
-  }
-
-  // In Obj-C++11, we need to distinguish four situations:
-  //  1a) int x[[attr]];                     C++11 attribute.
-  //  1b) [[attr]];                          C++11 statement attribute.
-  //   2) int x[[obj](){ return 1; }()];     Lambda in array size/index.
-  //  3a) int x[[obj get]];                  Message send in array size/index.
-  //  3b) [[Class alloc] init];              Message send in message send.
-  //   4) [[obj]{ return self; }() doStuff]; Lambda in message send.
-  // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.
-
-  // If we have a lambda-introducer, then this is definitely not a message send.
-  // FIXME: If this disambiguation is too slow, fold the tentative lambda parse
-  // into the tentative attribute parse below.
-  LambdaIntroducer Intro;
-  if (!TryParseLambdaIntroducer(Intro)) {
-    // A lambda cannot end with ']]', and an attribute must.
-    bool IsAttribute = Tok.is(tok::r_square);
-
-    PA.Revert();
-
-    if (IsAttribute)
-      // Case 1: C++11 attribute.
-      return CAK_AttributeSpecifier;
-
-    if (OuterMightBeMessageSend)
-      // Case 4: Lambda in message send.
-      return CAK_NotAttributeSpecifier;
-
-    // Case 2: Lambda in array size / index.
-    return CAK_InvalidAttributeSpecifier;
-  }
-
-  ConsumeBracket();
-
-  // If we don't have a lambda-introducer, then we have an attribute or a
-  // message-send.
-  bool IsAttribute = true;
-  while (Tok.isNot(tok::r_square)) {
-    if (Tok.is(tok::comma)) {
-      // Case 1: Stray commas can only occur in attributes.
-      PA.Revert();
-      return CAK_AttributeSpecifier;
-    }
-
-    // Parse the attribute-token, if present.
-    // C++11 [dcl.attr.grammar]:
-    //   If a keyword or an alternative token that satisfies the syntactic
-    //   requirements of an identifier is contained in an attribute-token,
-    //   it is considered an identifier.
-    SourceLocation Loc;
-    if (!TryParseCXX11AttributeIdentifier(Loc)) {
-      IsAttribute = false;
-      break;
-    }
-    if (Tok.is(tok::coloncolon)) {
-      ConsumeToken();
-      if (!TryParseCXX11AttributeIdentifier(Loc)) {
-        IsAttribute = false;
-        break;
-      }
-    }
-
-    // Parse the attribute-argument-clause, if present.
-    if (Tok.is(tok::l_paren)) {
-      ConsumeParen();
-      if (!SkipUntil(tok::r_paren, false)) {
-        IsAttribute = false;
-        break;
-      }
-    }
-
-    if (Tok.is(tok::ellipsis))
-      ConsumeToken();
-
-    if (Tok.isNot(tok::comma))
-      break;
-
-    ConsumeToken();
-  }
-
-  // An attribute must end ']]'.
-  if (IsAttribute) {
-    if (Tok.is(tok::r_square)) {
-      ConsumeBracket();
-      IsAttribute = Tok.is(tok::r_square);
-    } else {
-      IsAttribute = false;
-    }
-  }
-
-  PA.Revert();
-
-  if (IsAttribute)
-    // Case 1: C++11 statement attribute.
-    return CAK_AttributeSpecifier;
-
-  // Case 3: Message send.
-  return CAK_NotAttributeSpecifier;
-}
-
-///         declarator:
-///           direct-declarator
-///           ptr-operator declarator
-///
-///         direct-declarator:
-///           declarator-id
-///           direct-declarator '(' parameter-declaration-clause ')'
-///                 cv-qualifier-seq[opt] exception-specification[opt]
-///           direct-declarator '[' constant-expression[opt] ']'
-///           '(' declarator ')'
-/// [GNU]     '(' attributes declarator ')'
-///
-///         abstract-declarator:
-///           ptr-operator abstract-declarator[opt]
-///           direct-abstract-declarator
-///           ...
-///
-///         direct-abstract-declarator:
-///           direct-abstract-declarator[opt]
-///           '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-///                 exception-specification[opt]
-///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
-///           '(' abstract-declarator ')'
-///
-///         ptr-operator:
-///           '*' cv-qualifier-seq[opt]
-///           '&'
-/// [C++0x]   '&&'                                                        [TODO]
-///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
-///
-///         cv-qualifier-seq:
-///           cv-qualifier cv-qualifier-seq[opt]
-///
-///         cv-qualifier:
-///           'const'
-///           'volatile'
-///
-///         declarator-id:
-///           '...'[opt] id-expression
-///
-///         id-expression:
-///           unqualified-id
-///           qualified-id                                                [TODO]
-///
-///         unqualified-id:
-///           identifier
-///           operator-function-id                                        [TODO]
-///           conversion-function-id                                      [TODO]
-///           '~' class-name                                              [TODO]
-///           template-id                                                 [TODO]
-///
-Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
-                                            bool mayHaveIdentifier) {
-  // declarator:
-  //   direct-declarator
-  //   ptr-operator declarator
-
-  while (1) {
-    if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
-      if (TryAnnotateCXXScopeToken(true))
-        return TPResult::Error();
-
-    if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
-        Tok.is(tok::ampamp) ||
-        (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
-      // ptr-operator
-      ConsumeToken();
-      while (Tok.is(tok::kw_const)    ||
-             Tok.is(tok::kw_volatile) ||
-             Tok.is(tok::kw_restrict))
-        ConsumeToken();
-    } else {
-      break;
-    }
-  }
-
-  // direct-declarator:
-  // direct-abstract-declarator:
-  if (Tok.is(tok::ellipsis))
-    ConsumeToken();
-  
-  if ((Tok.is(tok::identifier) ||
-       (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) &&
-      mayHaveIdentifier) {
-    // declarator-id
-    if (Tok.is(tok::annot_cxxscope))
-      ConsumeToken();
-    else
-      TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
-    ConsumeToken();
-  } else if (Tok.is(tok::l_paren)) {
-    ConsumeParen();
-    if (mayBeAbstract &&
-        (Tok.is(tok::r_paren) ||       // 'int()' is a function.
-         // 'int(...)' is a function.
-         (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||
-         isDeclarationSpecifier())) {   // 'int(int)' is a function.
-      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-      //        exception-specification[opt]
-      TPResult TPR = TryParseFunctionDeclarator();
-      if (TPR != TPResult::Ambiguous())
-        return TPR;
-    } else {
-      // '(' declarator ')'
-      // '(' attributes declarator ')'
-      // '(' abstract-declarator ')'
-      if (Tok.is(tok::kw___attribute) ||
-          Tok.is(tok::kw___declspec) ||
-          Tok.is(tok::kw___cdecl) ||
-          Tok.is(tok::kw___stdcall) ||
-          Tok.is(tok::kw___fastcall) ||
-          Tok.is(tok::kw___thiscall) ||
-          Tok.is(tok::kw___unaligned))
-        return TPResult::True(); // attributes indicate declaration
-      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
-      if (TPR != TPResult::Ambiguous())
-        return TPR;
-      if (Tok.isNot(tok::r_paren))
-        return TPResult::False();
-      ConsumeParen();
-    }
-  } else if (!mayBeAbstract) {
-    return TPResult::False();
-  }
-
-  while (1) {
-    TPResult TPR(TPResult::Ambiguous());
-
-    // abstract-declarator: ...
-    if (Tok.is(tok::ellipsis))
-      ConsumeToken();
-
-    if (Tok.is(tok::l_paren)) {
-      // Check whether we have a function declarator or a possible ctor-style
-      // initializer that follows the declarator. Note that ctor-style
-      // initializers are not possible in contexts where abstract declarators
-      // are allowed.
-      if (!mayBeAbstract && !isCXXFunctionDeclarator())
-        break;
-
-      // direct-declarator '(' parameter-declaration-clause ')'
-      //        cv-qualifier-seq[opt] exception-specification[opt]
-      ConsumeParen();
-      TPR = TryParseFunctionDeclarator();
-    } else if (Tok.is(tok::l_square)) {
-      // direct-declarator '[' constant-expression[opt] ']'
-      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
-      TPR = TryParseBracketDeclarator();
-    } else {
-      break;
-    }
-
-    if (TPR != TPResult::Ambiguous())
-      return TPR;
-  }
-
-  return TPResult::Ambiguous();
-}
-
-Parser::TPResult 
-Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
-  switch (Kind) {
-  // Obviously starts an expression.
-  case tok::numeric_constant:
-  case tok::char_constant:
-  case tok::wide_char_constant:
-  case tok::utf16_char_constant:
-  case tok::utf32_char_constant:
-  case tok::string_literal:
-  case tok::wide_string_literal:
-  case tok::utf8_string_literal:
-  case tok::utf16_string_literal:
-  case tok::utf32_string_literal:
-  case tok::l_square:
-  case tok::l_paren:
-  case tok::amp:
-  case tok::ampamp:
-  case tok::star:
-  case tok::plus:
-  case tok::plusplus:
-  case tok::minus:
-  case tok::minusminus:
-  case tok::tilde:
-  case tok::exclaim:
-  case tok::kw_sizeof:
-  case tok::kw___func__:
-  case tok::kw_const_cast:
-  case tok::kw_delete:
-  case tok::kw_dynamic_cast:
-  case tok::kw_false:
-  case tok::kw_new:
-  case tok::kw_operator:
-  case tok::kw_reinterpret_cast:
-  case tok::kw_static_cast:
-  case tok::kw_this:
-  case tok::kw_throw:
-  case tok::kw_true:
-  case tok::kw_typeid:
-  case tok::kw_alignof:
-  case tok::kw_noexcept:
-  case tok::kw_nullptr:
-  case tok::kw__Alignof:
-  case tok::kw___null:
-  case tok::kw___alignof:
-  case tok::kw___builtin_choose_expr:
-  case tok::kw___builtin_offsetof:
-  case tok::kw___builtin_types_compatible_p:
-  case tok::kw___builtin_va_arg:
-  case tok::kw___imag:
-  case tok::kw___real:
-  case tok::kw___FUNCTION__:
-  case tok::kw_L__FUNCTION__:
-  case tok::kw___PRETTY_FUNCTION__:
-  case tok::kw___has_nothrow_assign:
-  case tok::kw___has_nothrow_copy:
-  case tok::kw___has_nothrow_constructor:
-  case tok::kw___has_trivial_assign:
-  case tok::kw___has_trivial_copy:
-  case tok::kw___has_trivial_constructor:
-  case tok::kw___has_trivial_destructor:
-  case tok::kw___has_virtual_destructor:
-  case tok::kw___is_abstract:
-  case tok::kw___is_base_of:
-  case tok::kw___is_class:
-  case tok::kw___is_convertible_to:
-  case tok::kw___is_empty:
-  case tok::kw___is_enum:
-  case tok::kw___is_interface_class:
-  case tok::kw___is_final:
-  case tok::kw___is_literal:
-  case tok::kw___is_literal_type:
-  case tok::kw___is_pod:
-  case tok::kw___is_polymorphic:
-  case tok::kw___is_trivial:
-  case tok::kw___is_trivially_assignable:
-  case tok::kw___is_trivially_constructible:
-  case tok::kw___is_trivially_copyable:
-  case tok::kw___is_union:
-  case tok::kw___uuidof:
-    return TPResult::True();
-      
-  // Obviously starts a type-specifier-seq:
-  case tok::kw_char:
-  case tok::kw_const:
-  case tok::kw_double:
-  case tok::kw_enum:
-  case tok::kw_half:
-  case tok::kw_float:
-  case tok::kw_int:
-  case tok::kw_long:
-  case tok::kw___int64:
-  case tok::kw___int128:
-  case tok::kw_restrict:
-  case tok::kw_short:
-  case tok::kw_signed:
-  case tok::kw_struct:
-  case tok::kw_union:
-  case tok::kw_unsigned:
-  case tok::kw_void:
-  case tok::kw_volatile:
-  case tok::kw__Bool:
-  case tok::kw__Complex:
-  case tok::kw_class:
-  case tok::kw_typename:
-  case tok::kw_wchar_t:
-  case tok::kw_char16_t:
-  case tok::kw_char32_t:
-  case tok::kw___underlying_type:
-  case tok::kw_thread_local:
-  case tok::kw__Decimal32:
-  case tok::kw__Decimal64:
-  case tok::kw__Decimal128:
-  case tok::kw___thread:
-  case tok::kw_typeof:
-  case tok::kw___cdecl:
-  case tok::kw___stdcall:
-  case tok::kw___fastcall:
-  case tok::kw___thiscall:
-  case tok::kw___unaligned:
-  case tok::kw___vector:
-  case tok::kw___pixel:
-  case tok::kw__Atomic:
-  case tok::kw___unknown_anytype:
-    return TPResult::False();
-
-  default:
-    break;
-  }
-  
-  return TPResult::Ambiguous();
-}
-
-bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
-  return std::find(TentativelyDeclaredIdentifiers.begin(),
-                   TentativelyDeclaredIdentifiers.end(), II)
-      != TentativelyDeclaredIdentifiers.end();
-}
-
-/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
-/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
-/// be either a decl-specifier or a function-style cast, and TPResult::Error()
-/// if a parsing error was found and reported.
-///
-/// If HasMissingTypename is provided, a name with a dependent scope specifier
-/// will be treated as ambiguous if the 'typename' keyword is missing. If this
-/// happens, *HasMissingTypename will be set to 'true'. This will also be used
-/// as an indicator that undeclared identifiers (which will trigger a later
-/// parse error) should be treated as types. Returns TPResult::Ambiguous() in
-/// such cases.
-///
-///         decl-specifier:
-///           storage-class-specifier
-///           type-specifier
-///           function-specifier
-///           'friend'
-///           'typedef'
-/// [C++0x]   'constexpr'
-/// [GNU]     attributes declaration-specifiers[opt]
-///
-///         storage-class-specifier:
-///           'register'
-///           'static'
-///           'extern'
-///           'mutable'
-///           'auto'
-/// [GNU]     '__thread'
-///
-///         function-specifier:
-///           'inline'
-///           'virtual'
-///           'explicit'
-///
-///         typedef-name:
-///           identifier
-///
-///         type-specifier:
-///           simple-type-specifier
-///           class-specifier
-///           enum-specifier
-///           elaborated-type-specifier
-///           typename-specifier
-///           cv-qualifier
-///
-///         simple-type-specifier:
-///           '::'[opt] nested-name-specifier[opt] type-name
-///           '::'[opt] nested-name-specifier 'template'
-///                 simple-template-id                              [TODO]
-///           'char'
-///           'wchar_t'
-///           'bool'
-///           'short'
-///           'int'
-///           'long'
-///           'signed'
-///           'unsigned'
-///           'float'
-///           'double'
-///           'void'
-/// [GNU]     typeof-specifier
-/// [GNU]     '_Complex'
-/// [C++0x]   'auto'                                                [TODO]
-/// [C++0x]   'decltype' ( expression )
-///
-///         type-name:
-///           class-name
-///           enum-name
-///           typedef-name
-///
-///         elaborated-type-specifier:
-///           class-key '::'[opt] nested-name-specifier[opt] identifier
-///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
-///               simple-template-id
-///           'enum' '::'[opt] nested-name-specifier[opt] identifier
-///
-///         enum-name:
-///           identifier
-///
-///         enum-specifier:
-///           'enum' identifier[opt] '{' enumerator-list[opt] '}'
-///           'enum' identifier[opt] '{' enumerator-list ',' '}'
-///
-///         class-specifier:
-///           class-head '{' member-specification[opt] '}'
-///
-///         class-head:
-///           class-key identifier[opt] base-clause[opt]
-///           class-key nested-name-specifier identifier base-clause[opt]
-///           class-key nested-name-specifier[opt] simple-template-id
-///               base-clause[opt]
-///
-///         class-key:
-///           'class'
-///           'struct'
-///           'union'
-///
-///         cv-qualifier:
-///           'const'
-///           'volatile'
-/// [GNU]     restrict
-///
-Parser::TPResult
-Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
-                                  bool *HasMissingTypename) {
-  switch (Tok.getKind()) {
-  case tok::identifier: {
-    // Check for need to substitute AltiVec __vector keyword
-    // for "vector" identifier.
-    if (TryAltiVecVectorToken())
-      return TPResult::True();
-
-    const Token &Next = NextToken();
-    // In 'foo bar', 'foo' is always a type name outside of Objective-C.
-    if (!getLangOpts().ObjC1 && Next.is(tok::identifier))
-      return TPResult::True();
-
-    if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
-      // Determine whether this is a valid expression. If not, we will hit
-      // a parse error one way or another. In that case, tell the caller that
-      // this is ambiguous. Typo-correct to type and expression keywords and
-      // to types and identifiers, in order to try to recover from errors.
-      CorrectionCandidateCallback TypoCorrection;
-      TypoCorrection.WantRemainingKeywords = false;
-      switch (TryAnnotateName(false /* no nested name specifier */,
-                              &TypoCorrection)) {
-      case ANK_Error:
-        return TPResult::Error();
-      case ANK_TentativeDecl:
-        return TPResult::False();
-      case ANK_TemplateName:
-        // A bare type template-name which can't be a template template
-        // argument is an error, and was probably intended to be a type.
-        return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
-      case ANK_Unresolved:
-        return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False();
-      case ANK_Success:
-        break;
-      }
-      assert(Tok.isNot(tok::identifier) &&
-             "TryAnnotateName succeeded without producing an annotation");
-    } else {
-      // This might possibly be a type with a dependent scope specifier and
-      // a missing 'typename' keyword. Don't use TryAnnotateName in this case,
-      // since it will annotate as a primary expression, and we want to use the
-      // "missing 'typename'" logic.
-      if (TryAnnotateTypeOrScopeToken())
-        return TPResult::Error();
-      // If annotation failed, assume it's a non-type.
-      // FIXME: If this happens due to an undeclared identifier, treat it as
-      // ambiguous.
-      if (Tok.is(tok::identifier))
-        return TPResult::False();
-    }
-
-    // We annotated this token as something. Recurse to handle whatever we got.
-    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
-  }
-
-  case tok::kw_typename:  // typename T::type
-    // Annotate typenames and C++ scope specifiers.  If we get one, just
-    // recurse to handle whatever we get.
-    if (TryAnnotateTypeOrScopeToken())
-      return TPResult::Error();
-    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
-
-  case tok::coloncolon: {    // ::foo::bar
-    const Token &Next = NextToken();
-    if (Next.is(tok::kw_new) ||    // ::new
-        Next.is(tok::kw_delete))   // ::delete
-      return TPResult::False();
-  }
-    // Fall through.
-  case tok::kw_decltype:
-    // Annotate typenames and C++ scope specifiers.  If we get one, just
-    // recurse to handle whatever we get.
-    if (TryAnnotateTypeOrScopeToken())
-      return TPResult::Error();
-    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
-
-    // decl-specifier:
-    //   storage-class-specifier
-    //   type-specifier
-    //   function-specifier
-    //   'friend'
-    //   'typedef'
-    //   'constexpr'
-  case tok::kw_friend:
-  case tok::kw_typedef:
-  case tok::kw_constexpr:
-    // storage-class-specifier
-  case tok::kw_register:
-  case tok::kw_static:
-  case tok::kw_extern:
-  case tok::kw_mutable:
-  case tok::kw_auto:
-  case tok::kw___thread:
-    // function-specifier
-  case tok::kw_inline:
-  case tok::kw_virtual:
-  case tok::kw_explicit:
-
-    // Modules
-  case tok::kw___module_private__:
-
-    // Debugger support
-  case tok::kw___unknown_anytype:
-      
-    // type-specifier:
-    //   simple-type-specifier
-    //   class-specifier
-    //   enum-specifier
-    //   elaborated-type-specifier
-    //   typename-specifier
-    //   cv-qualifier
-
-    // class-specifier
-    // elaborated-type-specifier
-  case tok::kw_class:
-  case tok::kw_struct:
-  case tok::kw_union:
-    // enum-specifier
-  case tok::kw_enum:
-    // cv-qualifier
-  case tok::kw_const:
-  case tok::kw_volatile:
-
-    // GNU
-  case tok::kw_restrict:
-  case tok::kw__Complex:
-  case tok::kw___attribute:
-    return TPResult::True();
-
-    // Microsoft
-  case tok::kw___declspec:
-  case tok::kw___cdecl:
-  case tok::kw___stdcall:
-  case tok::kw___fastcall:
-  case tok::kw___thiscall:
-  case tok::kw___w64:
-  case tok::kw___ptr64:
-  case tok::kw___ptr32:
-  case tok::kw___forceinline:
-  case tok::kw___unaligned:
-    return TPResult::True();
-
-    // Borland
-  case tok::kw___pascal:
-    return TPResult::True();
-  
-    // AltiVec
-  case tok::kw___vector:
-    return TPResult::True();
-
-  case tok::annot_template_id: {
-    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
-    if (TemplateId->Kind != TNK_Type_template)
-      return TPResult::False();
-    CXXScopeSpec SS;
-    AnnotateTemplateIdTokenAsType();
-    assert(Tok.is(tok::annot_typename));
-    goto case_typename;
-  }
-
-  case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
-    // We've already annotated a scope; try to annotate a type.
-    if (TryAnnotateTypeOrScopeToken())
-      return TPResult::Error();
-    if (!Tok.is(tok::annot_typename)) {
-      // If the next token is an identifier or a type qualifier, then this
-      // can't possibly be a valid expression either.
-      if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {
-        CXXScopeSpec SS;
-        Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
-                                                     Tok.getAnnotationRange(),
-                                                     SS);
-        if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
-          TentativeParsingAction PA(*this);
-          ConsumeToken();
-          ConsumeToken();
-          bool isIdentifier = Tok.is(tok::identifier);
-          TPResult TPR = TPResult::False();
-          if (!isIdentifier)
-            TPR = isCXXDeclarationSpecifier(BracedCastResult,
-                                            HasMissingTypename);
-          PA.Revert();
-
-          if (isIdentifier ||
-              TPR == TPResult::True() || TPR == TPResult::Error())
-            return TPResult::Error();
-
-          if (HasMissingTypename) {
-            // We can't tell whether this is a missing 'typename' or a valid
-            // expression.
-            *HasMissingTypename = true;
-            return TPResult::Ambiguous();
-          }
-        } else {
-          // Try to resolve the name. If it doesn't exist, assume it was
-          // intended to name a type and keep disambiguating.
-          switch (TryAnnotateName(false /* SS is not dependent */)) {
-          case ANK_Error:
-            return TPResult::Error();
-          case ANK_TentativeDecl:
-            return TPResult::False();
-          case ANK_TemplateName:
-            // A bare type template-name which can't be a template template
-            // argument is an error, and was probably intended to be a type.
-            return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
-          case ANK_Unresolved:
-            return HasMissingTypename ? TPResult::Ambiguous()
-                                      : TPResult::False();
-          case ANK_Success:
-            // Annotated it, check again.
-            assert(Tok.isNot(tok::annot_cxxscope) ||
-                   NextToken().isNot(tok::identifier));
-            return isCXXDeclarationSpecifier(BracedCastResult,
-                                             HasMissingTypename);
-          }
-        }
-      }
-      return TPResult::False();
-    }
-    // If that succeeded, fallthrough into the generic simple-type-id case.
-
-    // The ambiguity resides in a simple-type-specifier/typename-specifier
-    // followed by a '('. The '(' could either be the start of:
-    //
-    //   direct-declarator:
-    //     '(' declarator ')'
-    //
-    //   direct-abstract-declarator:
-    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-    //              exception-specification[opt]
-    //     '(' abstract-declarator ')'
-    //
-    // or part of a function-style cast expression:
-    //
-    //     simple-type-specifier '(' expression-list[opt] ')'
-    //
-
-    // simple-type-specifier:
-
-  case tok::annot_typename:
-  case_typename:
-    // In Objective-C, we might have a protocol-qualified type.
-    if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {
-      // Tentatively parse the 
-      TentativeParsingAction PA(*this);
-      ConsumeToken(); // The type token
-      
-      TPResult TPR = TryParseProtocolQualifiers();
-      bool isFollowedByParen = Tok.is(tok::l_paren);
-      bool isFollowedByBrace = Tok.is(tok::l_brace);
-      
-      PA.Revert();
-      
-      if (TPR == TPResult::Error())
-        return TPResult::Error();
-      
-      if (isFollowedByParen)
-        return TPResult::Ambiguous();
-
-      if (getLangOpts().CPlusPlus0x && isFollowedByBrace)
-        return BracedCastResult;
-      
-      return TPResult::True();
-    }
-      
-  case tok::kw_char:
-  case tok::kw_wchar_t:
-  case tok::kw_char16_t:
-  case tok::kw_char32_t:
-  case tok::kw_bool:
-  case tok::kw_short:
-  case tok::kw_int:
-  case tok::kw_long:
-  case tok::kw___int64:
-  case tok::kw___int128:
-  case tok::kw_signed:
-  case tok::kw_unsigned:
-  case tok::kw_half:
-  case tok::kw_float:
-  case tok::kw_double:
-  case tok::kw_void:
-  case tok::annot_decltype:
-    if (NextToken().is(tok::l_paren))
-      return TPResult::Ambiguous();
-
-    // This is a function-style cast in all cases we disambiguate other than
-    // one:
-    //   struct S {
-    //     enum E : int { a = 4 }; // enum
-    //     enum E : int { 4 };     // bit-field
-    //   };
-    if (getLangOpts().CPlusPlus0x && NextToken().is(tok::l_brace))
-      return BracedCastResult;
-
-    if (isStartOfObjCClassMessageMissingOpenBracket())
-      return TPResult::False();
-      
-    return TPResult::True();
-
-  // GNU typeof support.
-  case tok::kw_typeof: {
-    if (NextToken().isNot(tok::l_paren))
-      return TPResult::True();
-
-    TentativeParsingAction PA(*this);
-
-    TPResult TPR = TryParseTypeofSpecifier();
-    bool isFollowedByParen = Tok.is(tok::l_paren);
-    bool isFollowedByBrace = Tok.is(tok::l_brace);
-
-    PA.Revert();
-
-    if (TPR == TPResult::Error())
-      return TPResult::Error();
-
-    if (isFollowedByParen)
-      return TPResult::Ambiguous();
-
-    if (getLangOpts().CPlusPlus0x && isFollowedByBrace)
-      return BracedCastResult;
-
-    return TPResult::True();
-  }
-
-  // C++0x type traits support
-  case tok::kw___underlying_type:
-    return TPResult::True();
-
-  // C11 _Atomic
-  case tok::kw__Atomic:
-    return TPResult::True();
-
-  default:
-    return TPResult::False();
-  }
-}
-
-/// [GNU] typeof-specifier:
-///         'typeof' '(' expressions ')'
-///         'typeof' '(' type-name ')'
-///
-Parser::TPResult Parser::TryParseTypeofSpecifier() {
-  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
-  ConsumeToken();
-
-  assert(Tok.is(tok::l_paren) && "Expected '('");
-  // Parse through the parens after 'typeof'.
-  ConsumeParen();
-  if (!SkipUntil(tok::r_paren))
-    return TPResult::Error();
-
-  return TPResult::Ambiguous();
-}
-
-/// [ObjC] protocol-qualifiers:
-////         '<' identifier-list '>'
-Parser::TPResult Parser::TryParseProtocolQualifiers() {
-  assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
-  ConsumeToken();
-  do {
-    if (Tok.isNot(tok::identifier))
-      return TPResult::Error();
-    ConsumeToken();
-    
-    if (Tok.is(tok::comma)) {
-      ConsumeToken();
-      continue;
-    }
-    
-    if (Tok.is(tok::greater)) {
-      ConsumeToken();
-      return TPResult::Ambiguous();
-    }
-  } while (false);
-  
-  return TPResult::Error();
-}
-
-Parser::TPResult
-Parser::TryParseDeclarationSpecifier(bool *HasMissingTypename) {
-  TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),
-                                           HasMissingTypename);
-  if (TPR != TPResult::Ambiguous())
-    return TPR;
-
-  if (Tok.is(tok::kw_typeof))
-    TryParseTypeofSpecifier();
-  else {
-    if (Tok.is(tok::annot_cxxscope))
-      ConsumeToken();
-    ConsumeToken();
-    
-    if (getLangOpts().ObjC1 && Tok.is(tok::less))
-      TryParseProtocolQualifiers();
-  }
-
-  return TPResult::Ambiguous();
-}
-
-/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
-/// a constructor-style initializer, when parsing declaration statements.
-/// Returns true for function declarator and false for constructor-style
-/// initializer.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-///         exception-specification[opt]
-///
-bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
-
-  // C++ 8.2p1:
-  // The ambiguity arising from the similarity between a function-style cast and
-  // a declaration mentioned in 6.8 can also occur in the context of a
-  // declaration. In that context, the choice is between a function declaration
-  // with a redundant set of parentheses around a parameter name and an object
-  // declaration with a function-style cast as the initializer. Just as for the
-  // ambiguities mentioned in 6.8, the resolution is to consider any construct
-  // that could possibly be a declaration a declaration.
-
-  TentativeParsingAction PA(*this);
-
-  ConsumeParen();
-  bool InvalidAsDeclaration = false;
-  TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
-  if (TPR == TPResult::Ambiguous()) {
-    if (Tok.isNot(tok::r_paren))
-      TPR = TPResult::False();
-    else {
-      const Token &Next = NextToken();
-      if (Next.is(tok::amp) || Next.is(tok::ampamp) ||
-          Next.is(tok::kw_const) || Next.is(tok::kw_volatile) ||
-          Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) ||
-          Next.is(tok::l_square) || isCXX0XVirtSpecifier(Next) ||
-          Next.is(tok::l_brace) || Next.is(tok::kw_try) ||
-          Next.is(tok::equal) || Next.is(tok::arrow))
-        // The next token cannot appear after a constructor-style initializer,
-        // and can appear next in a function definition. This must be a function
-        // declarator.
-        TPR = TPResult::True();
-      else if (InvalidAsDeclaration)
-        // Use the absence of 'typename' as a tie-breaker.
-        TPR = TPResult::False();
-    }
-  }
-
-  PA.Revert();
-
-  if (IsAmbiguous && TPR == TPResult::Ambiguous())
-    *IsAmbiguous = true;
-
-  // In case of an error, let the declaration parsing code handle it.
-  return TPR != TPResult::False();
-}
-
-/// parameter-declaration-clause:
-///   parameter-declaration-list[opt] '...'[opt]
-///   parameter-declaration-list ',' '...'
-///
-/// parameter-declaration-list:
-///   parameter-declaration
-///   parameter-declaration-list ',' parameter-declaration
-///
-/// parameter-declaration:
-///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
-///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
-///     '=' assignment-expression
-///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
-///     attributes[opt]
-///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
-///     attributes[opt] '=' assignment-expression
-///
-Parser::TPResult
-Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration) {
-
-  if (Tok.is(tok::r_paren))
-    return TPResult::Ambiguous();
-
-  //   parameter-declaration-list[opt] '...'[opt]
-  //   parameter-declaration-list ',' '...'
-  //
-  // parameter-declaration-list:
-  //   parameter-declaration
-  //   parameter-declaration-list ',' parameter-declaration
-  //
-  while (1) {
-    // '...'[opt]
-    if (Tok.is(tok::ellipsis)) {
-      ConsumeToken();
-      if (Tok.is(tok::r_paren))
-        return TPResult::True(); // '...)' is a sign of a function declarator.
-      else
-        return TPResult::False();
-    }
-
-    // An attribute-specifier-seq here is a sign of a function declarator.
-    if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
-                                  /*OuterMightBeMessageSend*/true))
-      return TPResult::True();
-
-    ParsedAttributes attrs(AttrFactory);
-    MaybeParseMicrosoftAttributes(attrs);
-
-    // decl-specifier-seq
-    // A parameter-declaration's initializer must be preceded by an '=', so
-    // decl-specifier-seq '{' is not a parameter in C++11.
-    TPResult TPR = TryParseDeclarationSpecifier(InvalidAsDeclaration);
-    if (TPR != TPResult::Ambiguous())
-      return TPR;
-
-    // declarator
-    // abstract-declarator[opt]
-    TPR = TryParseDeclarator(true/*mayBeAbstract*/);
-    if (TPR != TPResult::Ambiguous())
-      return TPR;
-
-    // [GNU] attributes[opt]
-    if (Tok.is(tok::kw___attribute))
-      return TPResult::True();
-
-    if (Tok.is(tok::equal)) {
-      // '=' assignment-expression
-      // Parse through assignment-expression.
-      if (!SkipUntil(tok::comma, tok::r_paren, true/*StopAtSemi*/,
-                     true/*DontConsume*/))
-        return TPResult::Error();
-    }
-
-    if (Tok.is(tok::ellipsis)) {
-      ConsumeToken();
-      if (Tok.is(tok::r_paren))
-        return TPResult::True(); // '...)' is a sign of a function declarator.
-      else
-        return TPResult::False();
-    }
-
-    if (Tok.isNot(tok::comma))
-      break;
-    ConsumeToken(); // the comma.
-  }
-
-  return TPResult::Ambiguous();
-}
-
-/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
-/// parsing as a function declarator.
-/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
-/// return TPResult::Ambiguous(), otherwise it will return either False() or
-/// Error().
-///
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-///         exception-specification[opt]
-///
-/// exception-specification:
-///   'throw' '(' type-id-list[opt] ')'
-///
-Parser::TPResult Parser::TryParseFunctionDeclarator() {
-
-  // The '(' is already parsed.
-
-  TPResult TPR = TryParseParameterDeclarationClause();
-  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
-    TPR = TPResult::False();
-
-  if (TPR == TPResult::False() || TPR == TPResult::Error())
-    return TPR;
-
-  // Parse through the parens.
-  if (!SkipUntil(tok::r_paren))
-    return TPResult::Error();
-
-  // cv-qualifier-seq
-  while (Tok.is(tok::kw_const)    ||
-         Tok.is(tok::kw_volatile) ||
-         Tok.is(tok::kw_restrict)   )
-    ConsumeToken();
-
-  // ref-qualifier[opt]
-  if (Tok.is(tok::amp) || Tok.is(tok::ampamp))
-    ConsumeToken();
-  
-  // exception-specification
-  if (Tok.is(tok::kw_throw)) {
-    ConsumeToken();
-    if (Tok.isNot(tok::l_paren))
-      return TPResult::Error();
-
-    // Parse through the parens after 'throw'.
-    ConsumeParen();
-    if (!SkipUntil(tok::r_paren))
-      return TPResult::Error();
-  }
-  if (Tok.is(tok::kw_noexcept)) {
-    ConsumeToken();
-    // Possibly an expression as well.
-    if (Tok.is(tok::l_paren)) {
-      // Find the matching rparen.
-      ConsumeParen();
-      if (!SkipUntil(tok::r_paren))
-        return TPResult::Error();
-    }
-  }
-
-  return TPResult::Ambiguous();
-}
-
-/// '[' constant-expression[opt] ']'
-///
-Parser::TPResult Parser::TryParseBracketDeclarator() {
-  ConsumeBracket();
-  if (!SkipUntil(tok::r_square))
-    return TPResult::Error();
-
-  return TPResult::Ambiguous();
-}
+//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+//  This file implements the tentative parsing portions of the Parser

+//  interfaces, for ambiguity resolution.

+//

+//===----------------------------------------------------------------------===//

+

+#include "clang/Parse/Parser.h"

+#include "clang/Parse/ParseDiagnostic.h"

+#include "clang/Sema/ParsedTemplate.h"

+using namespace clang;

+

+/// isCXXDeclarationStatement - C++-specialized function that disambiguates

+/// between a declaration or an expression statement, when parsing function

+/// bodies. Returns true for declaration, false for expression.

+///

+///         declaration-statement:

+///           block-declaration

+///

+///         block-declaration:

+///           simple-declaration

+///           asm-definition

+///           namespace-alias-definition

+///           using-declaration

+///           using-directive

+/// [C++0x]   static_assert-declaration

+///

+///         asm-definition:

+///           'asm' '(' string-literal ')' ';'

+///

+///         namespace-alias-definition:

+///           'namespace' identifier = qualified-namespace-specifier ';'

+///

+///         using-declaration:

+///           'using' typename[opt] '::'[opt] nested-name-specifier

+///                 unqualified-id ';'

+///           'using' '::' unqualified-id ;

+///

+///         using-directive:

+///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]

+///                 namespace-name ';'

+///

+bool Parser::isCXXDeclarationStatement() {

+  switch (Tok.getKind()) {

+    // asm-definition

+  case tok::kw_asm:

+    // namespace-alias-definition

+  case tok::kw_namespace:

+    // using-declaration

+    // using-directive

+  case tok::kw_using:

+    // static_assert-declaration

+  case tok::kw_static_assert:

+  case tok::kw__Static_assert:

+    return true;

+    // simple-declaration

+  default:

+    return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);

+  }

+}

+

+/// isCXXSimpleDeclaration - C++-specialized function that disambiguates

+/// between a simple-declaration or an expression-statement.

+/// If during the disambiguation process a parsing error is encountered,

+/// the function returns true to let the declaration parsing code handle it.

+/// Returns false if the statement is disambiguated as expression.

+///

+/// simple-declaration:

+///   decl-specifier-seq init-declarator-list[opt] ';'

+///

+/// (if AllowForRangeDecl specified)

+/// for ( for-range-declaration : for-range-initializer ) statement

+/// for-range-declaration: 

+///    attribute-specifier-seqopt type-specifier-seq declarator

+bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {

+  // C++ 6.8p1:

+  // There is an ambiguity in the grammar involving expression-statements and

+  // declarations: An expression-statement with a function-style explicit type

+  // conversion (5.2.3) as its leftmost subexpression can be indistinguishable

+  // from a declaration where the first declarator starts with a '('. In those

+  // cases the statement is a declaration. [Note: To disambiguate, the whole

+  // statement might have to be examined to determine if it is an

+  // expression-statement or a declaration].

+

+  // C++ 6.8p3:

+  // The disambiguation is purely syntactic; that is, the meaning of the names

+  // occurring in such a statement, beyond whether they are type-names or not,

+  // is not generally used in or changed by the disambiguation. Class

+  // templates are instantiated as necessary to determine if a qualified name

+  // is a type-name. Disambiguation precedes parsing, and a statement

+  // disambiguated as a declaration may be an ill-formed declaration.

+

+  // We don't have to parse all of the decl-specifier-seq part. There's only

+  // an ambiguity if the first decl-specifier is

+  // simple-type-specifier/typename-specifier followed by a '(', which may

+  // indicate a function-style cast expression.

+  // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such

+  // a case.

+

+  bool InvalidAsDeclaration = false;

+  TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),

+                                           &InvalidAsDeclaration);

+  if (TPR != TPResult::Ambiguous())

+    return TPR != TPResult::False(); // Returns true for TPResult::True() or

+                                     // TPResult::Error().

+

+  // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,

+  // and so gets some cases wrong. We can't carry on if we've already seen

+  // something which makes this statement invalid as a declaration in this case,

+  // since it can cause us to misparse valid code. Revisit this once

+  // TryParseInitDeclaratorList is fixed.

+  if (InvalidAsDeclaration)

+    return false;

+

+  // FIXME: Add statistics about the number of ambiguous statements encountered

+  // and how they were resolved (number of declarations+number of expressions).

+

+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '(',

+  // or an identifier which doesn't resolve as anything. We need tentative

+  // parsing...

+

+  TentativeParsingAction PA(*this);

+  TPR = TryParseSimpleDeclaration(AllowForRangeDecl);

+  PA.Revert();

+

+  // In case of an error, let the declaration parsing code handle it.

+  if (TPR == TPResult::Error())

+    return true;

+

+  // Declarations take precedence over expressions.

+  if (TPR == TPResult::Ambiguous())

+    TPR = TPResult::True();

+

+  assert(TPR == TPResult::True() || TPR == TPResult::False());

+  return TPR == TPResult::True();

+}

+

+/// simple-declaration:

+///   decl-specifier-seq init-declarator-list[opt] ';'

+///

+/// (if AllowForRangeDecl specified)

+/// for ( for-range-declaration : for-range-initializer ) statement

+/// for-range-declaration: 

+///    attribute-specifier-seqopt type-specifier-seq declarator

+///

+Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {

+  if (Tok.is(tok::kw_typeof))

+    TryParseTypeofSpecifier();

+  else {

+    if (Tok.is(tok::annot_cxxscope))

+      ConsumeToken();

+    ConsumeToken();

+

+    if (getLangOpts().ObjC1 && Tok.is(tok::less))

+      TryParseProtocolQualifiers();

+  }

+

+  // Two decl-specifiers in a row conclusively disambiguate this as being a

+  // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the

+  // overwhelmingly common case that the next token is a '('.

+  if (Tok.isNot(tok::l_paren)) {

+    TPResult TPR = isCXXDeclarationSpecifier();

+    if (TPR == TPResult::Ambiguous())

+      return TPResult::True();

+    if (TPR == TPResult::True() || TPR == TPResult::Error())

+      return TPR;

+    assert(TPR == TPResult::False());

+  }

+

+  TPResult TPR = TryParseInitDeclaratorList();

+  if (TPR != TPResult::Ambiguous())

+    return TPR;

+

+  if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))

+    return TPResult::False();

+

+  return TPResult::Ambiguous();

+}

+

+///       init-declarator-list:

+///         init-declarator

+///         init-declarator-list ',' init-declarator

+///

+///       init-declarator:

+///         declarator initializer[opt]

+/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] initializer[opt]

+///

+/// initializer:

+///   '=' initializer-clause

+///   '(' expression-list ')'

+///

+/// initializer-clause:

+///   assignment-expression

+///   '{' initializer-list ','[opt] '}'

+///   '{' '}'

+///

+Parser::TPResult Parser::TryParseInitDeclaratorList() {

+  while (1) {

+    // declarator

+    TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);

+    if (TPR != TPResult::Ambiguous())

+      return TPR;

+

+    // [GNU] simple-asm-expr[opt] attributes[opt]

+    if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))

+      return TPResult::True();

+

+    // initializer[opt]

+    if (Tok.is(tok::l_paren)) {

+      // Parse through the parens.

+      ConsumeParen();

+      if (!SkipUntil(tok::r_paren))

+        return TPResult::Error();

+    } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {

+      // MSVC and g++ won't examine the rest of declarators if '=' is 

+      // encountered; they just conclude that we have a declaration.

+      // EDG parses the initializer completely, which is the proper behavior

+      // for this case.

+      //

+      // At present, Clang follows MSVC and g++, since the parser does not have

+      // the ability to parse an expression fully without recording the

+      // results of that parse.

+      // Also allow 'in' after on objective-c declaration as in: 

+      // for (int (^b)(void) in array). Ideally this should be done in the 

+      // context of parsing for-init-statement of a foreach statement only. But,

+      // in any other context 'in' is invalid after a declaration and parser

+      // issues the error regardless of outcome of this decision.

+      // FIXME. Change if above assumption does not hold.

+      return TPResult::True();

+    }

+

+    if (Tok.isNot(tok::comma))

+      break;

+    ConsumeToken(); // the comma.

+  }

+

+  return TPResult::Ambiguous();

+}

+

+/// isCXXConditionDeclaration - Disambiguates between a declaration or an

+/// expression for a condition of a if/switch/while/for statement.

+/// If during the disambiguation process a parsing error is encountered,

+/// the function returns true to let the declaration parsing code handle it.

+///

+///       condition:

+///         expression

+///         type-specifier-seq declarator '=' assignment-expression

+/// [C++11] type-specifier-seq declarator '=' initializer-clause

+/// [C++11] type-specifier-seq declarator braced-init-list

+/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]

+///             '=' assignment-expression

+///

+bool Parser::isCXXConditionDeclaration() {

+  TPResult TPR = isCXXDeclarationSpecifier();

+  if (TPR != TPResult::Ambiguous())

+    return TPR != TPResult::False(); // Returns true for TPResult::True() or

+                                     // TPResult::Error().

+

+  // FIXME: Add statistics about the number of ambiguous statements encountered

+  // and how they were resolved (number of declarations+number of expressions).

+

+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.

+  // We need tentative parsing...

+

+  TentativeParsingAction PA(*this);

+

+  // type-specifier-seq

+  if (Tok.is(tok::kw_typeof))

+    TryParseTypeofSpecifier();

+  else {

+    ConsumeToken();

+    

+    if (getLangOpts().ObjC1 && Tok.is(tok::less))

+      TryParseProtocolQualifiers();

+  }

+  assert(Tok.is(tok::l_paren) && "Expected '('");

+

+  // declarator

+  TPR = TryParseDeclarator(false/*mayBeAbstract*/);

+

+  // In case of an error, let the declaration parsing code handle it.

+  if (TPR == TPResult::Error())

+    TPR = TPResult::True();

+

+  if (TPR == TPResult::Ambiguous()) {

+    // '='

+    // [GNU] simple-asm-expr[opt] attributes[opt]

+    if (Tok.is(tok::equal)  ||

+        Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))

+      TPR = TPResult::True();

+    else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace))

+      TPR = TPResult::True();

+    else

+      TPR = TPResult::False();

+  }

+

+  PA.Revert();

+

+  assert(TPR == TPResult::True() || TPR == TPResult::False());

+  return TPR == TPResult::True();

+}

+

+  /// \brief Determine whether the next set of tokens contains a type-id.

+  ///

+  /// The context parameter states what context we're parsing right

+  /// now, which affects how this routine copes with the token

+  /// following the type-id. If the context is TypeIdInParens, we have

+  /// already parsed the '(' and we will cease lookahead when we hit

+  /// the corresponding ')'. If the context is

+  /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','

+  /// before this template argument, and will cease lookahead when we

+  /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id

+  /// and false for an expression.  If during the disambiguation

+  /// process a parsing error is encountered, the function returns

+  /// true to let the declaration parsing code handle it.

+  ///

+  /// type-id:

+  ///   type-specifier-seq abstract-declarator[opt]

+  ///

+bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {

+

+  isAmbiguous = false;

+

+  // C++ 8.2p2:

+  // The ambiguity arising from the similarity between a function-style cast and

+  // a type-id can occur in different contexts. The ambiguity appears as a

+  // choice between a function-style cast expression and a declaration of a

+  // type. The resolution is that any construct that could possibly be a type-id

+  // in its syntactic context shall be considered a type-id.

+

+  TPResult TPR = isCXXDeclarationSpecifier();

+  if (TPR != TPResult::Ambiguous())

+    return TPR != TPResult::False(); // Returns true for TPResult::True() or

+                                     // TPResult::Error().

+

+  // FIXME: Add statistics about the number of ambiguous statements encountered

+  // and how they were resolved (number of declarations+number of expressions).

+

+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.

+  // We need tentative parsing...

+

+  TentativeParsingAction PA(*this);

+

+  // type-specifier-seq

+  if (Tok.is(tok::kw_typeof))

+    TryParseTypeofSpecifier();

+  else {

+    ConsumeToken();

+    

+    if (getLangOpts().ObjC1 && Tok.is(tok::less))

+      TryParseProtocolQualifiers();

+  }

+  

+  assert(Tok.is(tok::l_paren) && "Expected '('");

+

+  // declarator

+  TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);

+

+  // In case of an error, let the declaration parsing code handle it.

+  if (TPR == TPResult::Error())

+    TPR = TPResult::True();

+

+  if (TPR == TPResult::Ambiguous()) {

+    // We are supposed to be inside parens, so if after the abstract declarator

+    // we encounter a ')' this is a type-id, otherwise it's an expression.

+    if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {

+      TPR = TPResult::True();

+      isAmbiguous = true;

+

+    // We are supposed to be inside a template argument, so if after

+    // the abstract declarator we encounter a '>', '>>' (in C++0x), or

+    // ',', this is a type-id. Otherwise, it's an expression.

+    } else if (Context == TypeIdAsTemplateArgument &&

+               (Tok.is(tok::greater) || Tok.is(tok::comma) ||

+                (getLangOpts().CPlusPlus0x && Tok.is(tok::greatergreater)))) {

+      TPR = TPResult::True();

+      isAmbiguous = true;

+

+    } else

+      TPR = TPResult::False();

+  }

+

+  PA.Revert();

+

+  assert(TPR == TPResult::True() || TPR == TPResult::False());

+  return TPR == TPResult::True();

+}

+

+/// \brief Returns true if this is a C++11 attribute-specifier. Per

+/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens

+/// always introduce an attribute. In Objective-C++11, this rule does not

+/// apply if either '[' begins a message-send.

+///

+/// If Disambiguate is true, we try harder to determine whether a '[[' starts

+/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not.

+///

+/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an

+/// Obj-C message send or the start of an attribute. Otherwise, we assume it

+/// is not an Obj-C message send.

+///

+/// C++11 [dcl.attr.grammar]:

+///

+///     attribute-specifier:

+///         '[' '[' attribute-list ']' ']'

+///         alignment-specifier

+///

+///     attribute-list:

+///         attribute[opt]

+///         attribute-list ',' attribute[opt]

+///         attribute '...'

+///         attribute-list ',' attribute '...'

+///

+///     attribute:

+///         attribute-token attribute-argument-clause[opt]

+///

+///     attribute-token:

+///         identifier

+///         identifier '::' identifier

+///

+///     attribute-argument-clause:

+///         '(' balanced-token-seq ')'

+Parser::CXX11AttributeKind

+Parser::isCXX11AttributeSpecifier(bool Disambiguate,

+                                  bool OuterMightBeMessageSend) {

+  if (Tok.is(tok::kw_alignas))

+    return CAK_AttributeSpecifier;

+

+  if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))

+    return CAK_NotAttributeSpecifier;

+

+  // No tentative parsing if we don't need to look for ']]' or a lambda.

+  if (!Disambiguate && !getLangOpts().ObjC1)

+    return CAK_AttributeSpecifier;

+

+  TentativeParsingAction PA(*this);

+

+  // Opening brackets were checked for above.

+  ConsumeBracket();

+

+  // Outside Obj-C++11, treat anything with a matching ']]' as an attribute.

+  if (!getLangOpts().ObjC1) {

+    ConsumeBracket();

+

+    bool IsAttribute = SkipUntil(tok::r_square, false);

+    IsAttribute &= Tok.is(tok::r_square);

+

+    PA.Revert();

+

+    return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;

+  }

+

+  // In Obj-C++11, we need to distinguish four situations:

+  //  1a) int x[[attr]];                     C++11 attribute.

+  //  1b) [[attr]];                          C++11 statement attribute.

+  //   2) int x[[obj](){ return 1; }()];     Lambda in array size/index.

+  //  3a) int x[[obj get]];                  Message send in array size/index.

+  //  3b) [[Class alloc] init];              Message send in message send.

+  //   4) [[obj]{ return self; }() doStuff]; Lambda in message send.

+  // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.

+

+  // If we have a lambda-introducer, then this is definitely not a message send.

+  // FIXME: If this disambiguation is too slow, fold the tentative lambda parse

+  // into the tentative attribute parse below.

+  LambdaIntroducer Intro;

+  if (!TryParseLambdaIntroducer(Intro)) {

+    // A lambda cannot end with ']]', and an attribute must.

+    bool IsAttribute = Tok.is(tok::r_square);

+

+    PA.Revert();

+

+    if (IsAttribute)

+      // Case 1: C++11 attribute.

+      return CAK_AttributeSpecifier;

+

+    if (OuterMightBeMessageSend)

+      // Case 4: Lambda in message send.

+      return CAK_NotAttributeSpecifier;

+

+    // Case 2: Lambda in array size / index.

+    return CAK_InvalidAttributeSpecifier;

+  }

+

+  ConsumeBracket();

+

+  // If we don't have a lambda-introducer, then we have an attribute or a

+  // message-send.

+  bool IsAttribute = true;

+  while (Tok.isNot(tok::r_square)) {

+    if (Tok.is(tok::comma)) {

+      // Case 1: Stray commas can only occur in attributes.

+      PA.Revert();

+      return CAK_AttributeSpecifier;

+    }

+

+    // Parse the attribute-token, if present.

+    // C++11 [dcl.attr.grammar]:

+    //   If a keyword or an alternative token that satisfies the syntactic

+    //   requirements of an identifier is contained in an attribute-token,

+    //   it is considered an identifier.

+    SourceLocation Loc;

+    if (!TryParseCXX11AttributeIdentifier(Loc)) {

+      IsAttribute = false;

+      break;

+    }

+    if (Tok.is(tok::coloncolon)) {

+      ConsumeToken();

+      if (!TryParseCXX11AttributeIdentifier(Loc)) {

+        IsAttribute = false;

+        break;

+      }

+    }

+

+    // Parse the attribute-argument-clause, if present.

+    if (Tok.is(tok::l_paren)) {

+      ConsumeParen();

+      if (!SkipUntil(tok::r_paren, false)) {

+        IsAttribute = false;

+        break;

+      }

+    }

+

+    if (Tok.is(tok::ellipsis))

+      ConsumeToken();

+

+    if (Tok.isNot(tok::comma))

+      break;

+

+    ConsumeToken();

+  }

+

+  // An attribute must end ']]'.

+  if (IsAttribute) {

+    if (Tok.is(tok::r_square)) {

+      ConsumeBracket();

+      IsAttribute = Tok.is(tok::r_square);

+    } else {

+      IsAttribute = false;

+    }

+  }

+

+  PA.Revert();

+

+  if (IsAttribute)

+    // Case 1: C++11 statement attribute.

+    return CAK_AttributeSpecifier;

+

+  // Case 3: Message send.

+  return CAK_NotAttributeSpecifier;

+}

+

+///         declarator:

+///           direct-declarator

+///           ptr-operator declarator

+///

+///         direct-declarator:

+///           declarator-id

+///           direct-declarator '(' parameter-declaration-clause ')'

+///                 cv-qualifier-seq[opt] exception-specification[opt]

+///           direct-declarator '[' constant-expression[opt] ']'

+///           '(' declarator ')'

+/// [GNU]     '(' attributes declarator ')'

+///

+///         abstract-declarator:

+///           ptr-operator abstract-declarator[opt]

+///           direct-abstract-declarator

+///           ...

+///

+///         direct-abstract-declarator:

+///           direct-abstract-declarator[opt]

+///           '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]

+///                 exception-specification[opt]

+///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'

+///           '(' abstract-declarator ')'

+///

+///         ptr-operator:

+///           '*' cv-qualifier-seq[opt]

+///           '&'

+/// [C++0x]   '&&'                                                        [TODO]

+///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]

+///

+///         cv-qualifier-seq:

+///           cv-qualifier cv-qualifier-seq[opt]

+///

+///         cv-qualifier:

+///           'const'

+///           'volatile'

+///

+///         declarator-id:

+///           '...'[opt] id-expression

+///

+///         id-expression:

+///           unqualified-id

+///           qualified-id                                                [TODO]

+///

+///         unqualified-id:

+///           identifier

+///           operator-function-id                                        [TODO]

+///           conversion-function-id                                      [TODO]

+///           '~' class-name                                              [TODO]

+///           template-id                                                 [TODO]

+///

+Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,

+                                            bool mayHaveIdentifier) {

+  // declarator:

+  //   direct-declarator

+  //   ptr-operator declarator

+

+  while (1) {

+    if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))

+      if (TryAnnotateCXXScopeToken(true))

+        return TPResult::Error();

+

+    if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||

+        Tok.is(tok::ampamp) ||

+        (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {

+      // ptr-operator

+      ConsumeToken();

+      while (Tok.is(tok::kw_const)    ||

+             Tok.is(tok::kw_volatile) ||

+             Tok.is(tok::kw_restrict))

+        ConsumeToken();

+    } else {

+      break;

+    }

+  }

+

+  // direct-declarator:

+  // direct-abstract-declarator:

+  if (Tok.is(tok::ellipsis))

+    ConsumeToken();

+  

+  if ((Tok.is(tok::identifier) ||

+       (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) &&

+      mayHaveIdentifier) {

+    // declarator-id

+    if (Tok.is(tok::annot_cxxscope))

+      ConsumeToken();

+    else

+      TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());

+    ConsumeToken();

+  } else if (Tok.is(tok::l_paren)) {

+    ConsumeParen();

+    if (mayBeAbstract &&

+        (Tok.is(tok::r_paren) ||       // 'int()' is a function.

+         // 'int(...)' is a function.

+         (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||

+         isDeclarationSpecifier())) {   // 'int(int)' is a function.

+      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]

+      //        exception-specification[opt]

+      TPResult TPR = TryParseFunctionDeclarator();

+      if (TPR != TPResult::Ambiguous())

+        return TPR;

+    } else {

+      // '(' declarator ')'

+      // '(' attributes declarator ')'

+      // '(' abstract-declarator ')'

+      if (Tok.is(tok::kw___attribute) ||

+          Tok.is(tok::kw___declspec) ||

+          Tok.is(tok::kw___cdecl) ||

+          Tok.is(tok::kw___stdcall) ||

+          Tok.is(tok::kw___fastcall) ||

+          Tok.is(tok::kw___thiscall) ||

+          Tok.is(tok::kw___unaligned))

+        return TPResult::True(); // attributes indicate declaration

+      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);

+      if (TPR != TPResult::Ambiguous())

+        return TPR;

+      if (Tok.isNot(tok::r_paren))

+        return TPResult::False();

+      ConsumeParen();

+    }

+  } else if (!mayBeAbstract) {

+    return TPResult::False();

+  }

+

+  while (1) {

+    TPResult TPR(TPResult::Ambiguous());

+

+    // abstract-declarator: ...

+    if (Tok.is(tok::ellipsis))

+      ConsumeToken();

+

+    if (Tok.is(tok::l_paren)) {

+      // Check whether we have a function declarator or a possible ctor-style

+      // initializer that follows the declarator. Note that ctor-style

+      // initializers are not possible in contexts where abstract declarators

+      // are allowed.

+      if (!mayBeAbstract && !isCXXFunctionDeclarator())

+        break;

+

+      // direct-declarator '(' parameter-declaration-clause ')'

+      //        cv-qualifier-seq[opt] exception-specification[opt]

+      ConsumeParen();

+      TPR = TryParseFunctionDeclarator();

+    } else if (Tok.is(tok::l_square)) {

+      // direct-declarator '[' constant-expression[opt] ']'

+      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'

+      TPR = TryParseBracketDeclarator();

+    } else {

+      break;

+    }

+

+    if (TPR != TPResult::Ambiguous())

+      return TPR;

+  }

+

+  return TPResult::Ambiguous();

+}

+

+Parser::TPResult 

+Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {

+  switch (Kind) {

+  // Obviously starts an expression.

+  case tok::numeric_constant:

+  case tok::char_constant:

+  case tok::wide_char_constant:

+  case tok::utf16_char_constant:

+  case tok::utf32_char_constant:

+  case tok::string_literal:

+  case tok::wide_string_literal:

+  case tok::utf8_string_literal:

+  case tok::utf16_string_literal:

+  case tok::utf32_string_literal:

+  case tok::l_square:

+  case tok::l_paren:

+  case tok::amp:

+  case tok::ampamp:

+  case tok::star:

+  case tok::plus:

+  case tok::plusplus:

+  case tok::minus:

+  case tok::minusminus:

+  case tok::tilde:

+  case tok::exclaim:

+  case tok::kw_sizeof:

+  case tok::kw___func__:

+  case tok::kw_const_cast:

+  case tok::kw_delete:

+  case tok::kw_dynamic_cast:

+  case tok::kw_false:

+  case tok::kw_new:

+  case tok::kw_operator:

+  case tok::kw_reinterpret_cast:

+  case tok::kw_static_cast:

+  case tok::kw_this:

+  case tok::kw_throw:

+  case tok::kw_true:

+  case tok::kw_typeid:

+  case tok::kw_alignof:

+  case tok::kw_noexcept:

+  case tok::kw_nullptr:

+  case tok::kw__Alignof:

+  case tok::kw___null:

+  case tok::kw___alignof:

+  case tok::kw___builtin_choose_expr:

+  case tok::kw___builtin_offsetof:

+  case tok::kw___builtin_types_compatible_p:

+  case tok::kw___builtin_va_arg:

+  case tok::kw___imag:

+  case tok::kw___real:

+  case tok::kw___FUNCTION__:

+  case tok::kw_L__FUNCTION__:

+  case tok::kw___PRETTY_FUNCTION__:

+  case tok::kw___has_nothrow_assign:

+  case tok::kw___has_nothrow_copy:

+  case tok::kw___has_nothrow_constructor:

+  case tok::kw___has_trivial_assign:

+  case tok::kw___has_trivial_copy:

+  case tok::kw___has_trivial_constructor:

+  case tok::kw___has_trivial_destructor:

+  case tok::kw___has_virtual_destructor:

+  case tok::kw___is_abstract:

+  case tok::kw___is_base_of:

+  case tok::kw___is_class:

+  case tok::kw___is_convertible_to:

+  case tok::kw___is_empty:

+  case tok::kw___is_enum:

+  case tok::kw___is_interface_class:

+  case tok::kw___is_final:

+  case tok::kw___is_literal:

+  case tok::kw___is_literal_type:

+  case tok::kw___is_pod:

+  case tok::kw___is_polymorphic:

+  case tok::kw___is_trivial:

+  case tok::kw___is_trivially_assignable:

+  case tok::kw___is_trivially_constructible:

+  case tok::kw___is_trivially_copyable:

+  case tok::kw___is_union:

+  case tok::kw___uuidof:

+    return TPResult::True();

+      

+  // Obviously starts a type-specifier-seq:

+  case tok::kw_char:

+  case tok::kw_const:

+  case tok::kw_double:

+  case tok::kw_enum:

+  case tok::kw_half:

+  case tok::kw_float:

+  case tok::kw_int:

+  case tok::kw_long:

+  case tok::kw___int64:

+  case tok::kw___int128:

+  case tok::kw_restrict:

+  case tok::kw_short:

+  case tok::kw_signed:

+  case tok::kw_struct:

+  case tok::kw_union:

+  case tok::kw_unsigned:

+  case tok::kw_void:

+  case tok::kw_volatile:

+  case tok::kw__Bool:

+  case tok::kw__Complex:

+  case tok::kw_class:

+  case tok::kw_typename:

+  case tok::kw_wchar_t:

+  case tok::kw_char16_t:

+  case tok::kw_char32_t:

+  case tok::kw___underlying_type:

+  case tok::kw_thread_local:

+  case tok::kw__Decimal32:

+  case tok::kw__Decimal64:

+  case tok::kw__Decimal128:

+  case tok::kw___thread:

+  case tok::kw_typeof:

+  case tok::kw___cdecl:

+  case tok::kw___stdcall:

+  case tok::kw___fastcall:

+  case tok::kw___thiscall:

+  case tok::kw___unaligned:

+  case tok::kw___vector:

+  case tok::kw___pixel:

+  case tok::kw__Atomic:

+  case tok::kw_image1d_t:

+  case tok::kw_image1d_array_t:

+  case tok::kw_image1d_buffer_t:

+  case tok::kw_image2d_t:

+  case tok::kw_image2d_array_t:

+  case tok::kw_image3d_t:

+  case tok::kw___unknown_anytype:

+    return TPResult::False();

+

+  default:

+    break;

+  }

+  

+  return TPResult::Ambiguous();

+}

+

+bool Parser::isTentativelyDeclared(IdentifierInfo *II) {

+  return std::find(TentativelyDeclaredIdentifiers.begin(),

+                   TentativelyDeclaredIdentifiers.end(), II)

+      != TentativelyDeclaredIdentifiers.end();

+}

+

+/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration

+/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could

+/// be either a decl-specifier or a function-style cast, and TPResult::Error()

+/// if a parsing error was found and reported.

+///

+/// If HasMissingTypename is provided, a name with a dependent scope specifier

+/// will be treated as ambiguous if the 'typename' keyword is missing. If this

+/// happens, *HasMissingTypename will be set to 'true'. This will also be used

+/// as an indicator that undeclared identifiers (which will trigger a later

+/// parse error) should be treated as types. Returns TPResult::Ambiguous() in

+/// such cases.

+///

+///         decl-specifier:

+///           storage-class-specifier

+///           type-specifier

+///           function-specifier

+///           'friend'

+///           'typedef'

+/// [C++0x]   'constexpr'

+/// [GNU]     attributes declaration-specifiers[opt]

+///

+///         storage-class-specifier:

+///           'register'

+///           'static'

+///           'extern'

+///           'mutable'

+///           'auto'

+/// [GNU]     '__thread'

+///

+///         function-specifier:

+///           'inline'

+///           'virtual'

+///           'explicit'

+///

+///         typedef-name:

+///           identifier

+///

+///         type-specifier:

+///           simple-type-specifier

+///           class-specifier

+///           enum-specifier

+///           elaborated-type-specifier

+///           typename-specifier

+///           cv-qualifier

+///

+///         simple-type-specifier:

+///           '::'[opt] nested-name-specifier[opt] type-name

+///           '::'[opt] nested-name-specifier 'template'

+///                 simple-template-id                              [TODO]

+///           'char'

+///           'wchar_t'

+///           'bool'

+///           'short'

+///           'int'

+///           'long'

+///           'signed'

+///           'unsigned'

+///           'float'

+///           'double'

+///           'void'

+/// [GNU]     typeof-specifier

+/// [GNU]     '_Complex'

+/// [C++0x]   'auto'                                                [TODO]

+/// [C++0x]   'decltype' ( expression )

+///

+///         type-name:

+///           class-name

+///           enum-name

+///           typedef-name

+///

+///         elaborated-type-specifier:

+///           class-key '::'[opt] nested-name-specifier[opt] identifier

+///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]

+///               simple-template-id

+///           'enum' '::'[opt] nested-name-specifier[opt] identifier

+///

+///         enum-name:

+///           identifier

+///

+///         enum-specifier:

+///           'enum' identifier[opt] '{' enumerator-list[opt] '}'

+///           'enum' identifier[opt] '{' enumerator-list ',' '}'

+///

+///         class-specifier:

+///           class-head '{' member-specification[opt] '}'

+///

+///         class-head:

+///           class-key identifier[opt] base-clause[opt]

+///           class-key nested-name-specifier identifier base-clause[opt]

+///           class-key nested-name-specifier[opt] simple-template-id

+///               base-clause[opt]

+///

+///         class-key:

+///           'class'

+///           'struct'

+///           'union'

+///

+///         cv-qualifier:

+///           'const'

+///           'volatile'

+/// [GNU]     restrict

+///

+Parser::TPResult

+Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,

+                                  bool *HasMissingTypename) {

+  switch (Tok.getKind()) {

+  case tok::identifier: {

+    // Check for need to substitute AltiVec __vector keyword

+    // for "vector" identifier.

+    if (TryAltiVecVectorToken())

+      return TPResult::True();

+

+    const Token &Next = NextToken();

+    // In 'foo bar', 'foo' is always a type name outside of Objective-C.

+    if (!getLangOpts().ObjC1 && Next.is(tok::identifier))

+      return TPResult::True();

+

+    if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {

+      // Determine whether this is a valid expression. If not, we will hit

+      // a parse error one way or another. In that case, tell the caller that

+      // this is ambiguous. Typo-correct to type and expression keywords and

+      // to types and identifiers, in order to try to recover from errors.

+      CorrectionCandidateCallback TypoCorrection;

+      TypoCorrection.WantRemainingKeywords = false;

+      switch (TryAnnotateName(false /* no nested name specifier */,

+                              &TypoCorrection)) {

+      case ANK_Error:

+        return TPResult::Error();

+      case ANK_TentativeDecl:

+        return TPResult::False();

+      case ANK_TemplateName:

+        // A bare type template-name which can't be a template template

+        // argument is an error, and was probably intended to be a type.

+        return GreaterThanIsOperator ? TPResult::True() : TPResult::False();

+      case ANK_Unresolved:

+        return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False();

+      case ANK_Success:

+        break;

+      }

+      assert(Tok.isNot(tok::identifier) &&

+             "TryAnnotateName succeeded without producing an annotation");

+    } else {

+      // This might possibly be a type with a dependent scope specifier and

+      // a missing 'typename' keyword. Don't use TryAnnotateName in this case,

+      // since it will annotate as a primary expression, and we want to use the

+      // "missing 'typename'" logic.

+      if (TryAnnotateTypeOrScopeToken())

+        return TPResult::Error();

+      // If annotation failed, assume it's a non-type.

+      // FIXME: If this happens due to an undeclared identifier, treat it as

+      // ambiguous.

+      if (Tok.is(tok::identifier))

+        return TPResult::False();

+    }

+

+    // We annotated this token as something. Recurse to handle whatever we got.

+    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);

+  }

+

+  case tok::kw_typename:  // typename T::type

+    // Annotate typenames and C++ scope specifiers.  If we get one, just

+    // recurse to handle whatever we get.

+    if (TryAnnotateTypeOrScopeToken())

+      return TPResult::Error();

+    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);

+

+  case tok::coloncolon: {    // ::foo::bar

+    const Token &Next = NextToken();

+    if (Next.is(tok::kw_new) ||    // ::new

+        Next.is(tok::kw_delete))   // ::delete

+      return TPResult::False();

+  }

+    // Fall through.

+  case tok::kw_decltype:

+    // Annotate typenames and C++ scope specifiers.  If we get one, just

+    // recurse to handle whatever we get.

+    if (TryAnnotateTypeOrScopeToken())

+      return TPResult::Error();

+    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);

+

+    // decl-specifier:

+    //   storage-class-specifier

+    //   type-specifier

+    //   function-specifier

+    //   'friend'

+    //   'typedef'

+    //   'constexpr'

+  case tok::kw_friend:

+  case tok::kw_typedef:

+  case tok::kw_constexpr:

+    // storage-class-specifier

+  case tok::kw_register:

+  case tok::kw_static:

+  case tok::kw_extern:

+  case tok::kw_mutable:

+  case tok::kw_auto:

+  case tok::kw___thread:

+    // function-specifier

+  case tok::kw_inline:

+  case tok::kw_virtual:

+  case tok::kw_explicit:

+

+    // Modules

+  case tok::kw___module_private__:

+

+    // Debugger support

+  case tok::kw___unknown_anytype:

+      

+    // type-specifier:

+    //   simple-type-specifier

+    //   class-specifier

+    //   enum-specifier

+    //   elaborated-type-specifier

+    //   typename-specifier

+    //   cv-qualifier

+

+    // class-specifier

+    // elaborated-type-specifier

+  case tok::kw_class:

+  case tok::kw_struct:

+  case tok::kw_union:

+    // enum-specifier

+  case tok::kw_enum:

+    // cv-qualifier

+  case tok::kw_const:

+  case tok::kw_volatile:

+

+    // GNU

+  case tok::kw_restrict:

+  case tok::kw__Complex:

+  case tok::kw___attribute:

+    return TPResult::True();

+

+    // Microsoft

+  case tok::kw___declspec:

+  case tok::kw___cdecl:

+  case tok::kw___stdcall:

+  case tok::kw___fastcall:

+  case tok::kw___thiscall:

+  case tok::kw___w64:

+  case tok::kw___ptr64:

+  case tok::kw___ptr32:

+  case tok::kw___forceinline:

+  case tok::kw___unaligned:

+    return TPResult::True();

+

+    // Borland

+  case tok::kw___pascal:

+    return TPResult::True();

+  

+    // AltiVec

+  case tok::kw___vector:

+    return TPResult::True();

+

+  case tok::annot_template_id: {

+    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);

+    if (TemplateId->Kind != TNK_Type_template)

+      return TPResult::False();

+    CXXScopeSpec SS;

+    AnnotateTemplateIdTokenAsType();

+    assert(Tok.is(tok::annot_typename));

+    goto case_typename;

+  }

+

+  case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed

+    // We've already annotated a scope; try to annotate a type.

+    if (TryAnnotateTypeOrScopeToken())

+      return TPResult::Error();

+    if (!Tok.is(tok::annot_typename)) {

+      // If the next token is an identifier or a type qualifier, then this

+      // can't possibly be a valid expression either.

+      if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {

+        CXXScopeSpec SS;

+        Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),

+                                                     Tok.getAnnotationRange(),

+                                                     SS);

+        if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {

+          TentativeParsingAction PA(*this);

+          ConsumeToken();

+          ConsumeToken();

+          bool isIdentifier = Tok.is(tok::identifier);

+          TPResult TPR = TPResult::False();

+          if (!isIdentifier)

+            TPR = isCXXDeclarationSpecifier(BracedCastResult,

+                                            HasMissingTypename);

+          PA.Revert();

+

+          if (isIdentifier ||

+              TPR == TPResult::True() || TPR == TPResult::Error())

+            return TPResult::Error();

+

+          if (HasMissingTypename) {

+            // We can't tell whether this is a missing 'typename' or a valid

+            // expression.

+            *HasMissingTypename = true;

+            return TPResult::Ambiguous();

+          }

+        } else {

+          // Try to resolve the name. If it doesn't exist, assume it was

+          // intended to name a type and keep disambiguating.

+          switch (TryAnnotateName(false /* SS is not dependent */)) {

+          case ANK_Error:

+            return TPResult::Error();

+          case ANK_TentativeDecl:

+            return TPResult::False();

+          case ANK_TemplateName:

+            // A bare type template-name which can't be a template template

+            // argument is an error, and was probably intended to be a type.

+            return GreaterThanIsOperator ? TPResult::True() : TPResult::False();

+          case ANK_Unresolved:

+            return HasMissingTypename ? TPResult::Ambiguous()

+                                      : TPResult::False();

+          case ANK_Success:

+            // Annotated it, check again.

+            assert(Tok.isNot(tok::annot_cxxscope) ||

+                   NextToken().isNot(tok::identifier));

+            return isCXXDeclarationSpecifier(BracedCastResult,

+                                             HasMissingTypename);

+          }

+        }

+      }

+      return TPResult::False();

+    }

+    // If that succeeded, fallthrough into the generic simple-type-id case.

+

+    // The ambiguity resides in a simple-type-specifier/typename-specifier

+    // followed by a '('. The '(' could either be the start of:

+    //

+    //   direct-declarator:

+    //     '(' declarator ')'

+    //

+    //   direct-abstract-declarator:

+    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]

+    //              exception-specification[opt]

+    //     '(' abstract-declarator ')'

+    //

+    // or part of a function-style cast expression:

+    //

+    //     simple-type-specifier '(' expression-list[opt] ')'

+    //

+

+    // simple-type-specifier:

+

+  case tok::annot_typename:

+  case_typename:

+    // In Objective-C, we might have a protocol-qualified type.

+    if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {

+      // Tentatively parse the 

+      TentativeParsingAction PA(*this);

+      ConsumeToken(); // The type token

+      

+      TPResult TPR = TryParseProtocolQualifiers();

+      bool isFollowedByParen = Tok.is(tok::l_paren);

+      bool isFollowedByBrace = Tok.is(tok::l_brace);

+      

+      PA.Revert();

+      

+      if (TPR == TPResult::Error())

+        return TPResult::Error();

+      

+      if (isFollowedByParen)

+        return TPResult::Ambiguous();

+

+      if (getLangOpts().CPlusPlus0x && isFollowedByBrace)

+        return BracedCastResult;

+      

+      return TPResult::True();

+    }

+      

+  case tok::kw_char:

+  case tok::kw_wchar_t:

+  case tok::kw_char16_t:

+  case tok::kw_char32_t:

+  case tok::kw_bool:

+  case tok::kw_short:

+  case tok::kw_int:

+  case tok::kw_long:

+  case tok::kw___int64:

+  case tok::kw___int128:

+  case tok::kw_signed:

+  case tok::kw_unsigned:

+  case tok::kw_half:

+  case tok::kw_float:

+  case tok::kw_double:

+  case tok::kw_void:

+  case tok::annot_decltype:

+    if (NextToken().is(tok::l_paren))

+      return TPResult::Ambiguous();

+

+    // This is a function-style cast in all cases we disambiguate other than

+    // one:

+    //   struct S {

+    //     enum E : int { a = 4 }; // enum

+    //     enum E : int { 4 };     // bit-field

+    //   };

+    if (getLangOpts().CPlusPlus0x && NextToken().is(tok::l_brace))

+      return BracedCastResult;

+

+    if (isStartOfObjCClassMessageMissingOpenBracket())

+      return TPResult::False();

+      

+    return TPResult::True();

+

+  // GNU typeof support.

+  case tok::kw_typeof: {

+    if (NextToken().isNot(tok::l_paren))

+      return TPResult::True();

+

+    TentativeParsingAction PA(*this);

+

+    TPResult TPR = TryParseTypeofSpecifier();

+    bool isFollowedByParen = Tok.is(tok::l_paren);

+    bool isFollowedByBrace = Tok.is(tok::l_brace);

+

+    PA.Revert();

+

+    if (TPR == TPResult::Error())

+      return TPResult::Error();

+

+    if (isFollowedByParen)

+      return TPResult::Ambiguous();

+

+    if (getLangOpts().CPlusPlus0x && isFollowedByBrace)

+      return BracedCastResult;

+

+    return TPResult::True();

+  }

+

+  // C++0x type traits support

+  case tok::kw___underlying_type:

+    return TPResult::True();

+

+  // C11 _Atomic

+  case tok::kw__Atomic:

+    return TPResult::True();

+

+  default:

+    return TPResult::False();

+  }

+}

+

+/// [GNU] typeof-specifier:

+///         'typeof' '(' expressions ')'

+///         'typeof' '(' type-name ')'

+///

+Parser::TPResult Parser::TryParseTypeofSpecifier() {

+  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");

+  ConsumeToken();

+

+  assert(Tok.is(tok::l_paren) && "Expected '('");

+  // Parse through the parens after 'typeof'.

+  ConsumeParen();

+  if (!SkipUntil(tok::r_paren))

+    return TPResult::Error();

+

+  return TPResult::Ambiguous();

+}

+

+/// [ObjC] protocol-qualifiers:

+////         '<' identifier-list '>'

+Parser::TPResult Parser::TryParseProtocolQualifiers() {

+  assert(Tok.is(tok::less) && "Expected '<' for qualifier list");

+  ConsumeToken();

+  do {

+    if (Tok.isNot(tok::identifier))

+      return TPResult::Error();

+    ConsumeToken();

+    

+    if (Tok.is(tok::comma)) {

+      ConsumeToken();

+      continue;

+    }

+    

+    if (Tok.is(tok::greater)) {

+      ConsumeToken();

+      return TPResult::Ambiguous();

+    }

+  } while (false);

+  

+  return TPResult::Error();

+}

+

+Parser::TPResult

+Parser::TryParseDeclarationSpecifier(bool *HasMissingTypename) {

+  TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),

+                                           HasMissingTypename);

+  if (TPR != TPResult::Ambiguous())

+    return TPR;

+

+  if (Tok.is(tok::kw_typeof))

+    TryParseTypeofSpecifier();

+  else {

+    if (Tok.is(tok::annot_cxxscope))

+      ConsumeToken();

+    ConsumeToken();

+    

+    if (getLangOpts().ObjC1 && Tok.is(tok::less))

+      TryParseProtocolQualifiers();

+  }

+

+  return TPResult::Ambiguous();

+}

+

+/// isCXXFunctionDeclarator - Disambiguates between a function declarator or

+/// a constructor-style initializer, when parsing declaration statements.

+/// Returns true for function declarator and false for constructor-style

+/// initializer.

+/// If during the disambiguation process a parsing error is encountered,

+/// the function returns true to let the declaration parsing code handle it.

+///

+/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]

+///         exception-specification[opt]

+///

+bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {

+

+  // C++ 8.2p1:

+  // The ambiguity arising from the similarity between a function-style cast and

+  // a declaration mentioned in 6.8 can also occur in the context of a

+  // declaration. In that context, the choice is between a function declaration

+  // with a redundant set of parentheses around a parameter name and an object

+  // declaration with a function-style cast as the initializer. Just as for the

+  // ambiguities mentioned in 6.8, the resolution is to consider any construct

+  // that could possibly be a declaration a declaration.

+

+  TentativeParsingAction PA(*this);

+

+  ConsumeParen();

+  bool InvalidAsDeclaration = false;

+  TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);

+  if (TPR == TPResult::Ambiguous()) {

+    if (Tok.isNot(tok::r_paren))

+      TPR = TPResult::False();

+    else {

+      const Token &Next = NextToken();

+      if (Next.is(tok::amp) || Next.is(tok::ampamp) ||

+          Next.is(tok::kw_const) || Next.is(tok::kw_volatile) ||

+          Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) ||

+          Next.is(tok::l_square) || isCXX0XVirtSpecifier(Next) ||

+          Next.is(tok::l_brace) || Next.is(tok::kw_try) ||

+          Next.is(tok::equal) || Next.is(tok::arrow))

+        // The next token cannot appear after a constructor-style initializer,

+        // and can appear next in a function definition. This must be a function

+        // declarator.

+        TPR = TPResult::True();

+      else if (InvalidAsDeclaration)

+        // Use the absence of 'typename' as a tie-breaker.

+        TPR = TPResult::False();

+    }

+  }

+

+  PA.Revert();

+

+  if (IsAmbiguous && TPR == TPResult::Ambiguous())

+    *IsAmbiguous = true;

+

+  // In case of an error, let the declaration parsing code handle it.

+  return TPR != TPResult::False();

+}

+

+/// parameter-declaration-clause:

+///   parameter-declaration-list[opt] '...'[opt]

+///   parameter-declaration-list ',' '...'

+///

+/// parameter-declaration-list:

+///   parameter-declaration

+///   parameter-declaration-list ',' parameter-declaration

+///

+/// parameter-declaration:

+///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]

+///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]

+///     '=' assignment-expression

+///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]

+///     attributes[opt]

+///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]

+///     attributes[opt] '=' assignment-expression

+///

+Parser::TPResult

+Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration) {

+

+  if (Tok.is(tok::r_paren))

+    return TPResult::Ambiguous();

+

+  //   parameter-declaration-list[opt] '...'[opt]

+  //   parameter-declaration-list ',' '...'

+  //

+  // parameter-declaration-list:

+  //   parameter-declaration

+  //   parameter-declaration-list ',' parameter-declaration

+  //

+  while (1) {

+    // '...'[opt]

+    if (Tok.is(tok::ellipsis)) {

+      ConsumeToken();

+      if (Tok.is(tok::r_paren))

+        return TPResult::True(); // '...)' is a sign of a function declarator.

+      else

+        return TPResult::False();

+    }

+

+    // An attribute-specifier-seq here is a sign of a function declarator.

+    if (isCXX11AttributeSpecifier(/*Disambiguate*/false,

+                                  /*OuterMightBeMessageSend*/true))

+      return TPResult::True();

+

+    ParsedAttributes attrs(AttrFactory);

+    MaybeParseMicrosoftAttributes(attrs);

+

+    // decl-specifier-seq

+    // A parameter-declaration's initializer must be preceded by an '=', so

+    // decl-specifier-seq '{' is not a parameter in C++11.

+    TPResult TPR = TryParseDeclarationSpecifier(InvalidAsDeclaration);

+    if (TPR != TPResult::Ambiguous())

+      return TPR;

+

+    // declarator

+    // abstract-declarator[opt]

+    TPR = TryParseDeclarator(true/*mayBeAbstract*/);

+    if (TPR != TPResult::Ambiguous())

+      return TPR;

+

+    // [GNU] attributes[opt]

+    if (Tok.is(tok::kw___attribute))

+      return TPResult::True();

+

+    if (Tok.is(tok::equal)) {

+      // '=' assignment-expression

+      // Parse through assignment-expression.

+      if (!SkipUntil(tok::comma, tok::r_paren, true/*StopAtSemi*/,

+                     true/*DontConsume*/))

+        return TPResult::Error();

+    }

+

+    if (Tok.is(tok::ellipsis)) {

+      ConsumeToken();

+      if (Tok.is(tok::r_paren))

+        return TPResult::True(); // '...)' is a sign of a function declarator.

+      else

+        return TPResult::False();

+    }

+

+    if (Tok.isNot(tok::comma))

+      break;

+    ConsumeToken(); // the comma.

+  }

+

+  return TPResult::Ambiguous();

+}

+

+/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue

+/// parsing as a function declarator.

+/// If TryParseFunctionDeclarator fully parsed the function declarator, it will

+/// return TPResult::Ambiguous(), otherwise it will return either False() or

+/// Error().

+///

+/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]

+///         exception-specification[opt]

+///

+/// exception-specification:

+///   'throw' '(' type-id-list[opt] ')'

+///

+Parser::TPResult Parser::TryParseFunctionDeclarator() {

+

+  // The '(' is already parsed.

+

+  TPResult TPR = TryParseParameterDeclarationClause();

+  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))

+    TPR = TPResult::False();

+

+  if (TPR == TPResult::False() || TPR == TPResult::Error())

+    return TPR;

+

+  // Parse through the parens.

+  if (!SkipUntil(tok::r_paren))

+    return TPResult::Error();

+

+  // cv-qualifier-seq

+  while (Tok.is(tok::kw_const)    ||

+         Tok.is(tok::kw_volatile) ||

+         Tok.is(tok::kw_restrict)   )

+    ConsumeToken();

+

+  // ref-qualifier[opt]

+  if (Tok.is(tok::amp) || Tok.is(tok::ampamp))

+    ConsumeToken();

+  

+  // exception-specification

+  if (Tok.is(tok::kw_throw)) {

+    ConsumeToken();

+    if (Tok.isNot(tok::l_paren))

+      return TPResult::Error();

+

+    // Parse through the parens after 'throw'.

+    ConsumeParen();

+    if (!SkipUntil(tok::r_paren))

+      return TPResult::Error();

+  }

+  if (Tok.is(tok::kw_noexcept)) {

+    ConsumeToken();

+    // Possibly an expression as well.

+    if (Tok.is(tok::l_paren)) {

+      // Find the matching rparen.

+      ConsumeParen();

+      if (!SkipUntil(tok::r_paren))

+        return TPResult::Error();

+    }

+  }

+

+  return TPResult::Ambiguous();

+}

+

+/// '[' constant-expression[opt] ']'

+///

+Parser::TPResult Parser::TryParseBracketDeclarator() {

+  ConsumeBracket();

+  if (!SkipUntil(tok::r_square))

+    return TPResult::Error();

+

+  return TPResult::Ambiguous();

+}

diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 040e638..b34b953 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -280,6 +280,12 @@
     case TST_unspecified:
     case TST_void:
     case TST_wchar:
+    case TST_image1d_t:
+    case TST_image1d_array_t:
+    case TST_image1d_buffer_t:
+    case TST_image2d_t:
+    case TST_image2d_array_t:
+    case TST_image3d_t:
       return false;
 
     case TST_decltype:
@@ -414,6 +420,12 @@
   case DeclSpec::TST_underlyingType: return "__underlying_type";
   case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
   case DeclSpec::TST_atomic: return "_Atomic";
+  case DeclSpec::TST_image1d_t:   return "image1d_t";
+  case DeclSpec::TST_image1d_array_t: return "image1d_array_t";
+  case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t";
+  case DeclSpec::TST_image2d_t:   return "image2d_t";
+  case DeclSpec::TST_image2d_array_t: return "image2d_array_t";
+  case DeclSpec::TST_image3d_t:   return "image3d_t";
   case DeclSpec::TST_error:       return "(error)";
   }
   llvm_unreachable("Unknown typespec!");
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index f797825..6c70320 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -731,6 +731,12 @@
   case TST_class:
   case TST_auto:
   case TST_unknown_anytype:
+  case TST_image1d_t:
+  case TST_image1d_array_t:
+  case TST_image1d_buffer_t:
+  case TST_image2d_t:
+  case TST_image2d_array_t:
+  case TST_image3d_t:
   case TST_error:
     break;
   }
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 2c7b7c1..1afc8c7 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -903,6 +903,30 @@
     }
     break;
 
+  case DeclSpec::TST_image1d_t:
+    Result = Context.OCLImage1dTy;
+    break;
+
+  case DeclSpec::TST_image1d_array_t:
+    Result = Context.OCLImage1dArrayTy;
+    break;
+
+  case DeclSpec::TST_image1d_buffer_t:
+    Result = Context.OCLImage1dBufferTy;
+    break;
+
+  case DeclSpec::TST_image2d_t:
+    Result = Context.OCLImage2dTy;
+    break;
+
+  case DeclSpec::TST_image2d_array_t:
+    Result = Context.OCLImage2dArrayTy;
+    break;
+
+  case DeclSpec::TST_image3d_t:
+    Result = Context.OCLImage3dTy;
+    break;
+
   case DeclSpec::TST_error:
     Result = Context.IntTy;
     declarator.setInvalidType(true);
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index aec8a81..91eec73 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -1,80 +1,86 @@
-//===--- ASTCommon.cpp - Common stuff for ASTReader/ASTWriter----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines common functions that both ASTReader and ASTWriter use.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTCommon.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Serialization/ASTDeserializationListener.h"
-#include "llvm/ADT/StringExtras.h"
-
-using namespace clang;
-
-// Give ASTDeserializationListener's VTable a home.
-ASTDeserializationListener::~ASTDeserializationListener() { }
-
-serialization::TypeIdx
-serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
-  unsigned ID = 0;
-  switch (BT->getKind()) {
-  case BuiltinType::Void:       ID = PREDEF_TYPE_VOID_ID;       break;
-  case BuiltinType::Bool:       ID = PREDEF_TYPE_BOOL_ID;       break;
-  case BuiltinType::Char_U:     ID = PREDEF_TYPE_CHAR_U_ID;     break;
-  case BuiltinType::UChar:      ID = PREDEF_TYPE_UCHAR_ID;      break;
-  case BuiltinType::UShort:     ID = PREDEF_TYPE_USHORT_ID;     break;
-  case BuiltinType::UInt:       ID = PREDEF_TYPE_UINT_ID;       break;
-  case BuiltinType::ULong:      ID = PREDEF_TYPE_ULONG_ID;      break;
-  case BuiltinType::ULongLong:  ID = PREDEF_TYPE_ULONGLONG_ID;  break;
-  case BuiltinType::UInt128:    ID = PREDEF_TYPE_UINT128_ID;    break;
-  case BuiltinType::Char_S:     ID = PREDEF_TYPE_CHAR_S_ID;     break;
-  case BuiltinType::SChar:      ID = PREDEF_TYPE_SCHAR_ID;      break;
-  case BuiltinType::WChar_S:
-  case BuiltinType::WChar_U:    ID = PREDEF_TYPE_WCHAR_ID;      break;
-  case BuiltinType::Short:      ID = PREDEF_TYPE_SHORT_ID;      break;
-  case BuiltinType::Int:        ID = PREDEF_TYPE_INT_ID;        break;
-  case BuiltinType::Long:       ID = PREDEF_TYPE_LONG_ID;       break;
-  case BuiltinType::LongLong:   ID = PREDEF_TYPE_LONGLONG_ID;   break;
-  case BuiltinType::Int128:     ID = PREDEF_TYPE_INT128_ID;     break;
-  case BuiltinType::Half:       ID = PREDEF_TYPE_HALF_ID;       break;
-  case BuiltinType::Float:      ID = PREDEF_TYPE_FLOAT_ID;      break;
-  case BuiltinType::Double:     ID = PREDEF_TYPE_DOUBLE_ID;     break;
-  case BuiltinType::LongDouble: ID = PREDEF_TYPE_LONGDOUBLE_ID; break;
-  case BuiltinType::NullPtr:    ID = PREDEF_TYPE_NULLPTR_ID;    break;
-  case BuiltinType::Char16:     ID = PREDEF_TYPE_CHAR16_ID;     break;
-  case BuiltinType::Char32:     ID = PREDEF_TYPE_CHAR32_ID;     break;
-  case BuiltinType::Overload:   ID = PREDEF_TYPE_OVERLOAD_ID;   break;
-  case BuiltinType::BoundMember:ID = PREDEF_TYPE_BOUND_MEMBER;  break;
-  case BuiltinType::PseudoObject:ID = PREDEF_TYPE_PSEUDO_OBJECT;break;
-  case BuiltinType::Dependent:  ID = PREDEF_TYPE_DEPENDENT_ID;  break;
-  case BuiltinType::UnknownAny: ID = PREDEF_TYPE_UNKNOWN_ANY;   break;
-  case BuiltinType::ARCUnbridgedCast:
-                                ID = PREDEF_TYPE_ARC_UNBRIDGED_CAST; break;
-  case BuiltinType::ObjCId:     ID = PREDEF_TYPE_OBJC_ID;       break;
-  case BuiltinType::ObjCClass:  ID = PREDEF_TYPE_OBJC_CLASS;    break;
-  case BuiltinType::ObjCSel:    ID = PREDEF_TYPE_OBJC_SEL;      break;
-  case BuiltinType::BuiltinFn:
-                                ID = PREDEF_TYPE_BUILTIN_FN; break;
-
-  }
-
-  return TypeIdx(ID);
-}
-
-unsigned serialization::ComputeHash(Selector Sel) {
-  unsigned N = Sel.getNumArgs();
-  if (N == 0)
-    ++N;
-  unsigned R = 5381;
-  for (unsigned I = 0; I != N; ++I)
-    if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
-      R = llvm::HashString(II->getName(), R);
-  return R;
-}
+//===--- ASTCommon.cpp - Common stuff for ASTReader/ASTWriter----*- C++ -*-===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+//  This file defines common functions that both ASTReader and ASTWriter use.

+//

+//===----------------------------------------------------------------------===//

+

+#include "ASTCommon.h"

+#include "clang/Basic/IdentifierTable.h"

+#include "clang/Serialization/ASTDeserializationListener.h"

+#include "llvm/ADT/StringExtras.h"

+

+using namespace clang;

+

+// Give ASTDeserializationListener's VTable a home.

+ASTDeserializationListener::~ASTDeserializationListener() { }

+

+serialization::TypeIdx

+serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {

+  unsigned ID = 0;

+  switch (BT->getKind()) {

+  case BuiltinType::Void:       ID = PREDEF_TYPE_VOID_ID;       break;

+  case BuiltinType::Bool:       ID = PREDEF_TYPE_BOOL_ID;       break;

+  case BuiltinType::Char_U:     ID = PREDEF_TYPE_CHAR_U_ID;     break;

+  case BuiltinType::UChar:      ID = PREDEF_TYPE_UCHAR_ID;      break;

+  case BuiltinType::UShort:     ID = PREDEF_TYPE_USHORT_ID;     break;

+  case BuiltinType::UInt:       ID = PREDEF_TYPE_UINT_ID;       break;

+  case BuiltinType::ULong:      ID = PREDEF_TYPE_ULONG_ID;      break;

+  case BuiltinType::ULongLong:  ID = PREDEF_TYPE_ULONGLONG_ID;  break;

+  case BuiltinType::UInt128:    ID = PREDEF_TYPE_UINT128_ID;    break;

+  case BuiltinType::Char_S:     ID = PREDEF_TYPE_CHAR_S_ID;     break;

+  case BuiltinType::SChar:      ID = PREDEF_TYPE_SCHAR_ID;      break;

+  case BuiltinType::WChar_S:

+  case BuiltinType::WChar_U:    ID = PREDEF_TYPE_WCHAR_ID;      break;

+  case BuiltinType::Short:      ID = PREDEF_TYPE_SHORT_ID;      break;

+  case BuiltinType::Int:        ID = PREDEF_TYPE_INT_ID;        break;

+  case BuiltinType::Long:       ID = PREDEF_TYPE_LONG_ID;       break;

+  case BuiltinType::LongLong:   ID = PREDEF_TYPE_LONGLONG_ID;   break;

+  case BuiltinType::Int128:     ID = PREDEF_TYPE_INT128_ID;     break;

+  case BuiltinType::Half:       ID = PREDEF_TYPE_HALF_ID;       break;

+  case BuiltinType::Float:      ID = PREDEF_TYPE_FLOAT_ID;      break;

+  case BuiltinType::Double:     ID = PREDEF_TYPE_DOUBLE_ID;     break;

+  case BuiltinType::LongDouble: ID = PREDEF_TYPE_LONGDOUBLE_ID; break;

+  case BuiltinType::NullPtr:    ID = PREDEF_TYPE_NULLPTR_ID;    break;

+  case BuiltinType::Char16:     ID = PREDEF_TYPE_CHAR16_ID;     break;

+  case BuiltinType::Char32:     ID = PREDEF_TYPE_CHAR32_ID;     break;

+  case BuiltinType::Overload:   ID = PREDEF_TYPE_OVERLOAD_ID;   break;

+  case BuiltinType::BoundMember:ID = PREDEF_TYPE_BOUND_MEMBER;  break;

+  case BuiltinType::PseudoObject:ID = PREDEF_TYPE_PSEUDO_OBJECT;break;

+  case BuiltinType::Dependent:  ID = PREDEF_TYPE_DEPENDENT_ID;  break;

+  case BuiltinType::UnknownAny: ID = PREDEF_TYPE_UNKNOWN_ANY;   break;

+  case BuiltinType::ARCUnbridgedCast:

+                                ID = PREDEF_TYPE_ARC_UNBRIDGED_CAST; break;

+  case BuiltinType::ObjCId:     ID = PREDEF_TYPE_OBJC_ID;       break;

+  case BuiltinType::ObjCClass:  ID = PREDEF_TYPE_OBJC_CLASS;    break;

+  case BuiltinType::ObjCSel:    ID = PREDEF_TYPE_OBJC_SEL;      break;

+  case BuiltinType::OCLImage1d:       ID = PREDEF_TYPE_IMAGE1D_ID;      break;

+  case BuiltinType::OCLImage1dArray:  ID = PREDEF_TYPE_IMAGE1D_ARR_ID;  break;

+  case BuiltinType::OCLImage1dBuffer: ID = PREDEF_TYPE_IMAGE1D_BUFF_ID; break;

+  case BuiltinType::OCLImage2d:       ID = PREDEF_TYPE_IMAGE2D_ID;      break;

+  case BuiltinType::OCLImage2dArray:  ID = PREDEF_TYPE_IMAGE2D_ARR_ID;  break;

+  case BuiltinType::OCLImage3d:       ID = PREDEF_TYPE_IMAGE3D_ID;      break;

+  case BuiltinType::BuiltinFn:

+                                ID = PREDEF_TYPE_BUILTIN_FN; break;

+

+  }

+

+  return TypeIdx(ID);

+}

+

+unsigned serialization::ComputeHash(Selector Sel) {

+  unsigned N = Sel.getNumArgs();

+  if (N == 0)

+    ++N;

+  unsigned R = 5381;

+  for (unsigned I = 0; I != N; ++I)

+    if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))

+      R = llvm::HashString(II->getName(), R);

+  return R;

+}

diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index c0976ee..88b5614 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1,6992 +1,6998 @@
-//===--- ASTReader.cpp - AST File Reader ------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the ASTReader class, which reads AST files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/ASTReader.h"
-#include "ASTCommon.h"
-#include "ASTReaderInternals.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLocVisitor.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemStatCache.h"
-#include "clang/Basic/OnDiskHashTable.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/SourceManagerInternals.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/Version.h"
-#include "clang/Basic/VersionTuple.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Sema/Scope.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Serialization/ASTDeserializationListener.h"
-#include "clang/Serialization/ModuleManager.h"
-#include "clang/Serialization/SerializationDiagnostic.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/SaveAndRestore.h"
-#include "llvm/Support/system_error.h"
-#include <algorithm>
-#include <cstdio>
-#include <iterator>
-
-using namespace clang;
-using namespace clang::serialization;
-using namespace clang::serialization::reader;
-
-//===----------------------------------------------------------------------===//
-// PCH validator implementation
-//===----------------------------------------------------------------------===//
-
-ASTReaderListener::~ASTReaderListener() {}
-
-/// \brief Compare the given set of language options against an existing set of
-/// language options.
-///
-/// \param Diags If non-NULL, diagnostics will be emitted via this engine.
-///
-/// \returns true if the languagae options mis-match, false otherwise.
-static bool checkLanguageOptions(const LangOptions &LangOpts,
-                                 const LangOptions &ExistingLangOpts,
-                                 DiagnosticsEngine *Diags) {
-#define LANGOPT(Name, Bits, Default, Description)                 \
-  if (ExistingLangOpts.Name != LangOpts.Name) {                   \
-    if (Diags)                                                    \
-      Diags->Report(diag::err_pch_langopt_mismatch)               \
-        << Description << LangOpts.Name << ExistingLangOpts.Name; \
-    return true;                                                  \
-  }
-
-#define VALUE_LANGOPT(Name, Bits, Default, Description)   \
-  if (ExistingLangOpts.Name != LangOpts.Name) {           \
-    if (Diags)                                            \
-      Diags->Report(diag::err_pch_langopt_value_mismatch) \
-        << Description;                                   \
-    return true;                                          \
-  }
-
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)   \
-  if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) {  \
-    if (Diags)                                                 \
-      Diags->Report(diag::err_pch_langopt_value_mismatch)      \
-        << Description;                                        \
-    return true;                                               \
-  }
-
-#define BENIGN_LANGOPT(Name, Bits, Default, Description)
-#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
-#include "clang/Basic/LangOptions.def"
-
-  if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {
-    if (Diags)
-      Diags->Report(diag::err_pch_langopt_value_mismatch)
-      << "target Objective-C runtime";
-    return true;
-  }
-
-  return false;
-}
-
-/// \brief Compare the given set of target options against an existing set of
-/// target options.
-///
-/// \param Diags If non-NULL, diagnostics will be emitted via this engine.
-///
-/// \returns true if the target options mis-match, false otherwise.
-static bool checkTargetOptions(const TargetOptions &TargetOpts,
-                               const TargetOptions &ExistingTargetOpts,
-                               DiagnosticsEngine *Diags) {
-#define CHECK_TARGET_OPT(Field, Name)                             \
-  if (TargetOpts.Field != ExistingTargetOpts.Field) {             \
-    if (Diags)                                                    \
-      Diags->Report(diag::err_pch_targetopt_mismatch)             \
-        << Name << TargetOpts.Field << ExistingTargetOpts.Field;  \
-    return true;                                                  \
-  }
-
-  CHECK_TARGET_OPT(Triple, "target");
-  CHECK_TARGET_OPT(CPU, "target CPU");
-  CHECK_TARGET_OPT(ABI, "target ABI");
-  CHECK_TARGET_OPT(CXXABI, "target C++ ABI");
-  CHECK_TARGET_OPT(LinkerVersion, "target linker version");
-#undef CHECK_TARGET_OPT
-
-  // Compare feature sets.
-  SmallVector<StringRef, 4> ExistingFeatures(
-                                             ExistingTargetOpts.FeaturesAsWritten.begin(),
-                                             ExistingTargetOpts.FeaturesAsWritten.end());
-  SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(),
-                                         TargetOpts.FeaturesAsWritten.end());
-  std::sort(ExistingFeatures.begin(), ExistingFeatures.end());
-  std::sort(ReadFeatures.begin(), ReadFeatures.end());
-
-  unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size();
-  unsigned ReadIdx = 0, ReadN = ReadFeatures.size();
-  while (ExistingIdx < ExistingN && ReadIdx < ReadN) {
-    if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) {
-      ++ExistingIdx;
-      ++ReadIdx;
-      continue;
-    }
-
-    if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) {
-      if (Diags)
-        Diags->Report(diag::err_pch_targetopt_feature_mismatch)
-          << false << ReadFeatures[ReadIdx];
-      return true;
-    }
-
-    if (Diags)
-      Diags->Report(diag::err_pch_targetopt_feature_mismatch)
-        << true << ExistingFeatures[ExistingIdx];
-    return true;
-  }
-
-  if (ExistingIdx < ExistingN) {
-    if (Diags)
-      Diags->Report(diag::err_pch_targetopt_feature_mismatch)
-        << true << ExistingFeatures[ExistingIdx];
-    return true;
-  }
-
-  if (ReadIdx < ReadN) {
-    if (Diags)
-      Diags->Report(diag::err_pch_targetopt_feature_mismatch)
-        << false << ReadFeatures[ReadIdx];
-    return true;
-  }
-
-  return false;
-}
-
-bool
-PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts,
-                                  bool Complain) {
-  const LangOptions &ExistingLangOpts = PP.getLangOpts();
-  return checkLanguageOptions(LangOpts, ExistingLangOpts,
-                              Complain? &Reader.Diags : 0);
-}
-
-bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
-                                     bool Complain) {
-  const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();
-  return checkTargetOptions(TargetOpts, ExistingTargetOpts,
-                            Complain? &Reader.Diags : 0);
-}
-
-namespace {
-  typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >
-    MacroDefinitionsMap;
-}
-
-/// \brief Collect the macro definitions provided by the given preprocessor
-/// options.
-static void collectMacroDefinitions(const PreprocessorOptions &PPOpts,
-                                    MacroDefinitionsMap &Macros,
-                                    SmallVectorImpl<StringRef> *MacroNames = 0){
-  for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
-    StringRef Macro = PPOpts.Macros[I].first;
-    bool IsUndef = PPOpts.Macros[I].second;
-
-    std::pair<StringRef, StringRef> MacroPair = Macro.split('=');
-    StringRef MacroName = MacroPair.first;
-    StringRef MacroBody = MacroPair.second;
-
-    // For an #undef'd macro, we only care about the name.
-    if (IsUndef) {
-      if (MacroNames && !Macros.count(MacroName))
-        MacroNames->push_back(MacroName);
-
-      Macros[MacroName] = std::make_pair("", true);
-      continue;
-    }
-
-    // For a #define'd macro, figure out the actual definition.
-    if (MacroName.size() == Macro.size())
-      MacroBody = "1";
-    else {
-      // Note: GCC drops anything following an end-of-line character.
-      StringRef::size_type End = MacroBody.find_first_of("\n\r");
-      MacroBody = MacroBody.substr(0, End);
-    }
-
-    if (MacroNames && !Macros.count(MacroName))
-      MacroNames->push_back(MacroName);
-    Macros[MacroName] = std::make_pair(MacroBody, false);
-  }
-}
-         
-/// \brief Check the preprocessor options deserialized from the control block
-/// against the preprocessor options in an existing preprocessor.
-///
-/// \param Diags If non-null, produce diagnostics for any mismatches incurred.
-static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
-                                     const PreprocessorOptions &ExistingPPOpts,
-                                     DiagnosticsEngine *Diags,
-                                     FileManager &FileMgr,
-                                     std::string &SuggestedPredefines) {
-  // Check macro definitions.
-  MacroDefinitionsMap ASTFileMacros;
-  collectMacroDefinitions(PPOpts, ASTFileMacros);
-  MacroDefinitionsMap ExistingMacros;
-  SmallVector<StringRef, 4> ExistingMacroNames;
-  collectMacroDefinitions(ExistingPPOpts, ExistingMacros, &ExistingMacroNames);
-
-  for (unsigned I = 0, N = ExistingMacroNames.size(); I != N; ++I) {
-    // Dig out the macro definition in the existing preprocessor options.
-    StringRef MacroName = ExistingMacroNames[I];
-    std::pair<StringRef, bool> Existing = ExistingMacros[MacroName];
-
-    // Check whether we know anything about this macro name or not.
-    llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known
-      = ASTFileMacros.find(MacroName);
-    if (Known == ASTFileMacros.end()) {
-      // FIXME: Check whether this identifier was referenced anywhere in the
-      // AST file. If so, we should reject the AST file. Unfortunately, this
-      // information isn't in the control block. What shall we do about it?
-
-      if (Existing.second) {
-        SuggestedPredefines += "#undef ";
-        SuggestedPredefines += MacroName.str();
-        SuggestedPredefines += '\n';
-      } else {
-        SuggestedPredefines += "#define ";
-        SuggestedPredefines += MacroName.str();
-        SuggestedPredefines += ' ';
-        SuggestedPredefines += Existing.first.str();
-        SuggestedPredefines += '\n';
-      }
-      continue;
-    }
-
-    // If the macro was defined in one but undef'd in the other, we have a
-    // conflict.
-    if (Existing.second != Known->second.second) {
-      if (Diags) {
-        Diags->Report(diag::err_pch_macro_def_undef)
-          << MacroName << Known->second.second;
-      }
-      return true;
-    }
-
-    // If the macro was #undef'd in both, or if the macro bodies are identical,
-    // it's fine.
-    if (Existing.second || Existing.first == Known->second.first)
-      continue;
-
-    // The macro bodies differ; complain.
-    if (Diags) {
-      Diags->Report(diag::err_pch_macro_def_conflict)
-        << MacroName << Known->second.first << Existing.first;
-    }
-    return true;
-  }
-
-  // Check whether we're using predefines.
-  if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines) {
-    if (Diags) {
-      Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines;
-    }
-    return true;
-  }
-
-  // Compute the #include and #include_macros lines we need.
-  for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) {
-    StringRef File = ExistingPPOpts.Includes[I];
-    if (File == ExistingPPOpts.ImplicitPCHInclude)
-      continue;
-
-    if (std::find(PPOpts.Includes.begin(), PPOpts.Includes.end(), File)
-          != PPOpts.Includes.end())
-      continue;
-
-    SuggestedPredefines += "#include \"";
-    SuggestedPredefines +=
-      HeaderSearch::NormalizeDashIncludePath(File, FileMgr);
-    SuggestedPredefines += "\"\n";
-  }
-
-  for (unsigned I = 0, N = ExistingPPOpts.MacroIncludes.size(); I != N; ++I) {
-    StringRef File = ExistingPPOpts.MacroIncludes[I];
-    if (std::find(PPOpts.MacroIncludes.begin(), PPOpts.MacroIncludes.end(),
-                  File)
-        != PPOpts.MacroIncludes.end())
-      continue;
-
-    SuggestedPredefines += "#__include_macros \"";
-    SuggestedPredefines +=
-      HeaderSearch::NormalizeDashIncludePath(File, FileMgr);
-    SuggestedPredefines += "\"\n##\n";
-  }
-
-  return false;
-}
-
-bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
-                                           bool Complain,
-                                           std::string &SuggestedPredefines) {
-  const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts();
-
-  return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
-                                  Complain? &Reader.Diags : 0,
-                                  PP.getFileManager(),
-                                  SuggestedPredefines);
-}
-
-void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
-                                      unsigned ID) {
-  PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);
-  ++NumHeaderInfos;
-}
-
-void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) {
-  PP.setCounterValue(Value);
-}
-
-//===----------------------------------------------------------------------===//
-// AST reader implementation
-//===----------------------------------------------------------------------===//
-
-void
-ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
-  DeserializationListener = Listener;
-}
-
-
-
-unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
-  return serialization::ComputeHash(Sel);
-}
-
-
-std::pair<unsigned, unsigned>
-ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
-  using namespace clang::io;
-  unsigned KeyLen = ReadUnalignedLE16(d);
-  unsigned DataLen = ReadUnalignedLE16(d);
-  return std::make_pair(KeyLen, DataLen);
-}
-
-ASTSelectorLookupTrait::internal_key_type 
-ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
-  using namespace clang::io;
-  SelectorTable &SelTable = Reader.getContext().Selectors;
-  unsigned N = ReadUnalignedLE16(d);
-  IdentifierInfo *FirstII
-    = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
-  if (N == 0)
-    return SelTable.getNullarySelector(FirstII);
-  else if (N == 1)
-    return SelTable.getUnarySelector(FirstII);
-
-  SmallVector<IdentifierInfo *, 16> Args;
-  Args.push_back(FirstII);
-  for (unsigned I = 1; I != N; ++I)
-    Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)));
-
-  return SelTable.getSelector(N, Args.data());
-}
-
-ASTSelectorLookupTrait::data_type 
-ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, 
-                                 unsigned DataLen) {
-  using namespace clang::io;
-
-  data_type Result;
-
-  Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));
-  unsigned NumInstanceMethods = ReadUnalignedLE16(d);
-  unsigned NumFactoryMethods = ReadUnalignedLE16(d);
-
-  // Load instance methods
-  for (unsigned I = 0; I != NumInstanceMethods; ++I) {
-    if (ObjCMethodDecl *Method
-          = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
-      Result.Instance.push_back(Method);
-  }
-
-  // Load factory methods
-  for (unsigned I = 0; I != NumFactoryMethods; ++I) {
-    if (ObjCMethodDecl *Method
-          = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
-      Result.Factory.push_back(Method);
-  }
-
-  return Result;
-}
-
-unsigned ASTIdentifierLookupTrait::ComputeHash(const internal_key_type& a) {
-  return llvm::HashString(StringRef(a.first, a.second));
-}
-
-std::pair<unsigned, unsigned>
-ASTIdentifierLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
-  using namespace clang::io;
-  unsigned DataLen = ReadUnalignedLE16(d);
-  unsigned KeyLen = ReadUnalignedLE16(d);
-  return std::make_pair(KeyLen, DataLen);
-}
-
-std::pair<const char*, unsigned>
-ASTIdentifierLookupTrait::ReadKey(const unsigned char* d, unsigned n) {
-  assert(n >= 2 && d[n-1] == '\0');
-  return std::make_pair((const char*) d, n-1);
-}
-
-IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
-                                                   const unsigned char* d,
-                                                   unsigned DataLen) {
-  using namespace clang::io;
-  unsigned RawID = ReadUnalignedLE32(d);
-  bool IsInteresting = RawID & 0x01;
-
-  // Wipe out the "is interesting" bit.
-  RawID = RawID >> 1;
-
-  IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
-  if (!IsInteresting) {
-    // For uninteresting identifiers, just build the IdentifierInfo
-    // and associate it with the persistent ID.
-    IdentifierInfo *II = KnownII;
-    if (!II) {
-      II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
-      KnownII = II;
-    }
-    Reader.SetIdentifierInfo(ID, II);
-    II->setIsFromAST();
-    Reader.markIdentifierUpToDate(II);    
-    return II;
-  }
-
-  unsigned ObjCOrBuiltinID = ReadUnalignedLE16(d);
-  unsigned Bits = ReadUnalignedLE16(d);
-  bool CPlusPlusOperatorKeyword = Bits & 0x01;
-  Bits >>= 1;
-  bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
-  Bits >>= 1;
-  bool Poisoned = Bits & 0x01;
-  Bits >>= 1;
-  bool ExtensionToken = Bits & 0x01;
-  Bits >>= 1;
-  bool hadMacroDefinition = Bits & 0x01;
-  Bits >>= 1;
-
-  assert(Bits == 0 && "Extra bits in the identifier?");
-  DataLen -= 8;
-
-  // Build the IdentifierInfo itself and link the identifier ID with
-  // the new IdentifierInfo.
-  IdentifierInfo *II = KnownII;
-  if (!II) {
-    II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
-    KnownII = II;
-  }
-  Reader.markIdentifierUpToDate(II);
-  II->setIsFromAST();
-
-  // Set or check the various bits in the IdentifierInfo structure.
-  // Token IDs are read-only.
-  if (HasRevertedTokenIDToIdentifier)
-    II->RevertTokenIDToIdentifier();
-  II->setObjCOrBuiltinID(ObjCOrBuiltinID);
-  assert(II->isExtensionToken() == ExtensionToken &&
-         "Incorrect extension token flag");
-  (void)ExtensionToken;
-  if (Poisoned)
-    II->setIsPoisoned(true);
-  assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
-         "Incorrect C++ operator keyword flag");
-  (void)CPlusPlusOperatorKeyword;
-
-  // If this identifier is a macro, deserialize the macro
-  // definition.
-  if (hadMacroDefinition) {
-    SmallVector<MacroID, 4> MacroIDs;
-    while (uint32_t LocalID = ReadUnalignedLE32(d)) {
-      MacroIDs.push_back(Reader.getGlobalMacroID(F, LocalID));
-      DataLen -= 4;
-    }
-    DataLen -= 4;
-    Reader.setIdentifierIsMacro(II, MacroIDs);
-  }
-
-  Reader.SetIdentifierInfo(ID, II);
-
-  // Read all of the declarations visible at global scope with this
-  // name.
-  if (DataLen > 0) {
-    SmallVector<uint32_t, 4> DeclIDs;
-    for (; DataLen > 0; DataLen -= 4)
-      DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));
-    Reader.SetGloballyVisibleDecls(II, DeclIDs);
-  }
-
-  return II;
-}
-
-unsigned 
-ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {
-  llvm::FoldingSetNodeID ID;
-  ID.AddInteger(Key.Kind);
-
-  switch (Key.Kind) {
-  case DeclarationName::Identifier:
-  case DeclarationName::CXXLiteralOperatorName:
-    ID.AddString(((IdentifierInfo*)Key.Data)->getName());
-    break;
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-    ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
-    break;
-  case DeclarationName::CXXOperatorName:
-    ID.AddInteger((OverloadedOperatorKind)Key.Data);
-    break;
-  case DeclarationName::CXXConstructorName:
-  case DeclarationName::CXXDestructorName:
-  case DeclarationName::CXXConversionFunctionName:
-  case DeclarationName::CXXUsingDirective:
-    break;
-  }
-
-  return ID.ComputeHash();
-}
-
-ASTDeclContextNameLookupTrait::internal_key_type 
-ASTDeclContextNameLookupTrait::GetInternalKey(
-                                          const external_key_type& Name) const {
-  DeclNameKey Key;
-  Key.Kind = Name.getNameKind();
-  switch (Name.getNameKind()) {
-  case DeclarationName::Identifier:
-    Key.Data = (uint64_t)Name.getAsIdentifierInfo();
-    break;
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-    Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
-    break;
-  case DeclarationName::CXXOperatorName:
-    Key.Data = Name.getCXXOverloadedOperator();
-    break;
-  case DeclarationName::CXXLiteralOperatorName:
-    Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
-    break;
-  case DeclarationName::CXXConstructorName:
-  case DeclarationName::CXXDestructorName:
-  case DeclarationName::CXXConversionFunctionName:
-  case DeclarationName::CXXUsingDirective:
-    Key.Data = 0;
-    break;
-  }
-
-  return Key;
-}
-
-std::pair<unsigned, unsigned>
-ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
-  using namespace clang::io;
-  unsigned KeyLen = ReadUnalignedLE16(d);
-  unsigned DataLen = ReadUnalignedLE16(d);
-  return std::make_pair(KeyLen, DataLen);
-}
-
-ASTDeclContextNameLookupTrait::internal_key_type 
-ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) {
-  using namespace clang::io;
-
-  DeclNameKey Key;
-  Key.Kind = (DeclarationName::NameKind)*d++;
-  switch (Key.Kind) {
-  case DeclarationName::Identifier:
-    Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
-    break;
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-    Key.Data =
-       (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d))
-                   .getAsOpaquePtr();
-    break;
-  case DeclarationName::CXXOperatorName:
-    Key.Data = *d++; // OverloadedOperatorKind
-    break;
-  case DeclarationName::CXXLiteralOperatorName:
-    Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
-    break;
-  case DeclarationName::CXXConstructorName:
-  case DeclarationName::CXXDestructorName:
-  case DeclarationName::CXXConversionFunctionName:
-  case DeclarationName::CXXUsingDirective:
-    Key.Data = 0;
-    break;
-  }
-
-  return Key;
-}
-
-ASTDeclContextNameLookupTrait::data_type 
-ASTDeclContextNameLookupTrait::ReadData(internal_key_type, 
-                                        const unsigned char* d,
-                                        unsigned DataLen) {
-  using namespace clang::io;
-  unsigned NumDecls = ReadUnalignedLE16(d);
-  LE32DeclID *Start = (LE32DeclID *)d;
-  return std::make_pair(Start, Start + NumDecls);
-}
-
-bool ASTReader::ReadDeclContextStorage(ModuleFile &M,
-                                       llvm::BitstreamCursor &Cursor,
-                                   const std::pair<uint64_t, uint64_t> &Offsets,
-                                       DeclContextInfo &Info) {
-  SavedStreamPosition SavedPosition(Cursor);
-  // First the lexical decls.
-  if (Offsets.first != 0) {
-    Cursor.JumpToBit(Offsets.first);
-
-    RecordData Record;
-    const char *Blob;
-    unsigned BlobLen;
-    unsigned Code = Cursor.ReadCode();
-    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
-    if (RecCode != DECL_CONTEXT_LEXICAL) {
-      Error("Expected lexical block");
-      return true;
-    }
-
-    Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob);
-    Info.NumLexicalDecls = BlobLen / sizeof(KindDeclIDPair);
-  }
-
-  // Now the lookup table.
-  if (Offsets.second != 0) {
-    Cursor.JumpToBit(Offsets.second);
-
-    RecordData Record;
-    const char *Blob;
-    unsigned BlobLen;
-    unsigned Code = Cursor.ReadCode();
-    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
-    if (RecCode != DECL_CONTEXT_VISIBLE) {
-      Error("Expected visible lookup table block");
-      return true;
-    }
-    Info.NameLookupTableData
-      = ASTDeclContextNameLookupTable::Create(
-                    (const unsigned char *)Blob + Record[0],
-                    (const unsigned char *)Blob,
-                    ASTDeclContextNameLookupTrait(*this, M));
-  }
-
-  return false;
-}
-
-void ASTReader::Error(StringRef Msg) {
-  Error(diag::err_fe_pch_malformed, Msg);
-}
-
-void ASTReader::Error(unsigned DiagID,
-                      StringRef Arg1, StringRef Arg2) {
-  if (Diags.isDiagnosticInFlight())
-    Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);
-  else
-    Diag(DiagID) << Arg1 << Arg2;
-}
-
-//===----------------------------------------------------------------------===//
-// Source Manager Deserialization
-//===----------------------------------------------------------------------===//
-
-/// \brief Read the line table in the source manager block.
-/// \returns true if there was an error.
-bool ASTReader::ParseLineTable(ModuleFile &F,
-                               SmallVectorImpl<uint64_t> &Record) {
-  unsigned Idx = 0;
-  LineTableInfo &LineTable = SourceMgr.getLineTable();
-
-  // Parse the file names
-  std::map<int, int> FileIDs;
-  for (int I = 0, N = Record[Idx++]; I != N; ++I) {
-    // Extract the file name
-    unsigned FilenameLen = Record[Idx++];
-    std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
-    Idx += FilenameLen;
-    MaybeAddSystemRootToFilename(F, Filename);
-    FileIDs[I] = LineTable.getLineTableFilenameID(Filename);
-  }
-
-  // Parse the line entries
-  std::vector<LineEntry> Entries;
-  while (Idx < Record.size()) {
-    int FID = Record[Idx++];
-    assert(FID >= 0 && "Serialized line entries for non-local file.");
-    // Remap FileID from 1-based old view.
-    FID += F.SLocEntryBaseID - 1;
-
-    // Extract the line entries
-    unsigned NumEntries = Record[Idx++];
-    assert(NumEntries && "Numentries is 00000");
-    Entries.clear();
-    Entries.reserve(NumEntries);
-    for (unsigned I = 0; I != NumEntries; ++I) {
-      unsigned FileOffset = Record[Idx++];
-      unsigned LineNo = Record[Idx++];
-      int FilenameID = FileIDs[Record[Idx++]];
-      SrcMgr::CharacteristicKind FileKind
-        = (SrcMgr::CharacteristicKind)Record[Idx++];
-      unsigned IncludeOffset = Record[Idx++];
-      Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
-                                       FileKind, IncludeOffset));
-    }
-    LineTable.AddEntry(FileID::get(FID), Entries);
-  }
-
-  return false;
-}
-
-/// \brief Read a source manager block
-bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
-  using namespace SrcMgr;
-
-  llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
-
-  // Set the source-location entry cursor to the current position in
-  // the stream. This cursor will be used to read the contents of the
-  // source manager block initially, and then lazily read
-  // source-location entries as needed.
-  SLocEntryCursor = F.Stream;
-
-  // The stream itself is going to skip over the source manager block.
-  if (F.Stream.SkipBlock()) {
-    Error("malformed block record in AST file");
-    return true;
-  }
-
-  // Enter the source manager block.
-  if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
-    Error("malformed source manager block record in AST file");
-    return true;
-  }
-
-  RecordData Record;
-  while (true) {
-    unsigned Code = SLocEntryCursor.ReadCode();
-    if (Code == llvm::bitc::END_BLOCK) {
-      if (SLocEntryCursor.ReadBlockEnd()) {
-        Error("error at end of Source Manager block in AST file");
-        return true;
-      }
-      return false;
-    }
-
-    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-      // No known subblocks, always skip them.
-      SLocEntryCursor.ReadSubBlockID();
-      if (SLocEntryCursor.SkipBlock()) {
-        Error("malformed block record in AST file");
-        return true;
-      }
-      continue;
-    }
-
-    if (Code == llvm::bitc::DEFINE_ABBREV) {
-      SLocEntryCursor.ReadAbbrevRecord();
-      continue;
-    }
-
-    // Read a record.
-    const char *BlobStart;
-    unsigned BlobLen;
-    Record.clear();
-    switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
-    default:  // Default behavior: ignore.
-      break;
-
-    case SM_SLOC_FILE_ENTRY:
-    case SM_SLOC_BUFFER_ENTRY:
-    case SM_SLOC_EXPANSION_ENTRY:
-      // Once we hit one of the source location entries, we're done.
-      return false;
-    }
-  }
-}
-
-/// \brief If a header file is not found at the path that we expect it to be
-/// and the PCH file was moved from its original location, try to resolve the
-/// file by assuming that header+PCH were moved together and the header is in
-/// the same place relative to the PCH.
-static std::string
-resolveFileRelativeToOriginalDir(const std::string &Filename,
-                                 const std::string &OriginalDir,
-                                 const std::string &CurrDir) {
-  assert(OriginalDir != CurrDir &&
-         "No point trying to resolve the file if the PCH dir didn't change");
-  using namespace llvm::sys;
-  SmallString<128> filePath(Filename);
-  fs::make_absolute(filePath);
-  assert(path::is_absolute(OriginalDir));
-  SmallString<128> currPCHPath(CurrDir);
-
-  path::const_iterator fileDirI = path::begin(path::parent_path(filePath)),
-                       fileDirE = path::end(path::parent_path(filePath));
-  path::const_iterator origDirI = path::begin(OriginalDir),
-                       origDirE = path::end(OriginalDir);
-  // Skip the common path components from filePath and OriginalDir.
-  while (fileDirI != fileDirE && origDirI != origDirE &&
-         *fileDirI == *origDirI) {
-    ++fileDirI;
-    ++origDirI;
-  }
-  for (; origDirI != origDirE; ++origDirI)
-    path::append(currPCHPath, "..");
-  path::append(currPCHPath, fileDirI, fileDirE);
-  path::append(currPCHPath, path::filename(Filename));
-  return currPCHPath.str();
-}
-
-bool ASTReader::ReadSLocEntry(int ID) {
-  if (ID == 0)
-    return false;
-
-  if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
-    Error("source location entry ID out-of-range for AST file");
-    return true;
-  }
-
-  ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second;
-  F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);
-  llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
-  unsigned BaseOffset = F->SLocEntryBaseOffset;
-
-  ++NumSLocEntriesRead;
-  unsigned Code = SLocEntryCursor.ReadCode();
-  if (Code == llvm::bitc::END_BLOCK ||
-      Code == llvm::bitc::ENTER_SUBBLOCK ||
-      Code == llvm::bitc::DEFINE_ABBREV) {
-    Error("incorrectly-formatted source location entry in AST file");
-    return true;
-  }
-
-  RecordData Record;
-  const char *BlobStart;
-  unsigned BlobLen;
-  switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
-  default:
-    Error("incorrectly-formatted source location entry in AST file");
-    return true;
-
-  case SM_SLOC_FILE_ENTRY: {
-    // We will detect whether a file changed and return 'Failure' for it, but
-    // we will also try to fail gracefully by setting up the SLocEntry.
-    unsigned InputID = Record[4];
-    InputFile IF = getInputFile(*F, InputID);
-    const FileEntry *File = IF.getPointer();
-    bool OverriddenBuffer = IF.getInt();
-
-    if (!IF.getPointer())
-      return true;
-
-    SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
-    if (IncludeLoc.isInvalid() && F->Kind != MK_MainFile) {
-      // This is the module's main file.
-      IncludeLoc = getImportLocation(F);
-    }
-    SrcMgr::CharacteristicKind
-      FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
-    FileID FID = SourceMgr.createFileID(File, IncludeLoc, FileCharacter,
-                                        ID, BaseOffset + Record[0]);
-    SrcMgr::FileInfo &FileInfo =
-          const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());
-    FileInfo.NumCreatedFIDs = Record[5];
-    if (Record[3])
-      FileInfo.setHasLineDirectives();
-
-    const DeclID *FirstDecl = F->FileSortedDecls + Record[6];
-    unsigned NumFileDecls = Record[7];
-    if (NumFileDecls) {
-      assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");
-      FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl,
-                                                             NumFileDecls));
-    }
-    
-    const SrcMgr::ContentCache *ContentCache
-      = SourceMgr.getOrCreateContentCache(File,
-                              /*isSystemFile=*/FileCharacter != SrcMgr::C_User);
-    if (OverriddenBuffer && !ContentCache->BufferOverridden &&
-        ContentCache->ContentsEntry == ContentCache->OrigEntry) {
-      unsigned Code = SLocEntryCursor.ReadCode();
-      Record.clear();
-      unsigned RecCode
-        = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
-      
-      if (RecCode != SM_SLOC_BUFFER_BLOB) {
-        Error("AST record has invalid code");
-        return true;
-      }
-      
-      llvm::MemoryBuffer *Buffer
-        = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),
-                                           File->getName());
-      SourceMgr.overrideFileContents(File, Buffer);
-    }
-
-    break;
-  }
-
-  case SM_SLOC_BUFFER_ENTRY: {
-    const char *Name = BlobStart;
-    unsigned Offset = Record[0];
-    SrcMgr::CharacteristicKind
-      FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
-    SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
-    if (IncludeLoc.isInvalid() && F->Kind == MK_Module) {
-      IncludeLoc = getImportLocation(F);
-    }
-    unsigned Code = SLocEntryCursor.ReadCode();
-    Record.clear();
-    unsigned RecCode
-      = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
-
-    if (RecCode != SM_SLOC_BUFFER_BLOB) {
-      Error("AST record has invalid code");
-      return true;
-    }
-
-    llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),
-                                         Name);
-    SourceMgr.createFileIDForMemBuffer(Buffer, FileCharacter, ID,
-                                       BaseOffset + Offset, IncludeLoc);
-    break;
-  }
-
-  case SM_SLOC_EXPANSION_ENTRY: {
-    SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1]);
-    SourceMgr.createExpansionLoc(SpellingLoc,
-                                     ReadSourceLocation(*F, Record[2]),
-                                     ReadSourceLocation(*F, Record[3]),
-                                     Record[4],
-                                     ID,
-                                     BaseOffset + Record[0]);
-    break;
-  }
-  }
-
-  return false;
-}
-
-std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {
-  if (ID == 0)
-    return std::make_pair(SourceLocation(), "");
-
-  if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
-    Error("source location entry ID out-of-range for AST file");
-    return std::make_pair(SourceLocation(), "");
-  }
-
-  // Find which module file this entry lands in.
-  ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second;
-  if (M->Kind != MK_Module)
-    return std::make_pair(SourceLocation(), "");
-
-  // FIXME: Can we map this down to a particular submodule? That would be
-  // ideal.
-  return std::make_pair(M->ImportLoc, llvm::sys::path::stem(M->FileName));
-}
-
-/// \brief Find the location where the module F is imported.
-SourceLocation ASTReader::getImportLocation(ModuleFile *F) {
-  if (F->ImportLoc.isValid())
-    return F->ImportLoc;
-  
-  // Otherwise we have a PCH. It's considered to be "imported" at the first
-  // location of its includer.
-  if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
-    // Main file is the importer. We assume that it is the first entry in the
-    // entry table. We can't ask the manager, because at the time of PCH loading
-    // the main file entry doesn't exist yet.
-    // The very first entry is the invalid instantiation loc, which takes up
-    // offsets 0 and 1.
-    return SourceLocation::getFromRawEncoding(2U);
-  }
-  //return F->Loaders[0]->FirstLoc;
-  return F->ImportedBy[0]->FirstLoc;
-}
-
-/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
-/// specified cursor.  Read the abbreviations that are at the top of the block
-/// and then leave the cursor pointing into the block.
-bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
-                                 unsigned BlockID) {
-  if (Cursor.EnterSubBlock(BlockID)) {
-    Error("malformed block record in AST file");
-    return Failure;
-  }
-
-  while (true) {
-    uint64_t Offset = Cursor.GetCurrentBitNo();
-    unsigned Code = Cursor.ReadCode();
-
-    // We expect all abbrevs to be at the start of the block.
-    if (Code != llvm::bitc::DEFINE_ABBREV) {
-      Cursor.JumpToBit(Offset);
-      return false;
-    }
-    Cursor.ReadAbbrevRecord();
-  }
-}
-
-void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset,
-                                MacroInfo *Hint) {
-  llvm::BitstreamCursor &Stream = F.MacroCursor;
-
-  // Keep track of where we are in the stream, then jump back there
-  // after reading this macro.
-  SavedStreamPosition SavedPosition(Stream);
-
-  Stream.JumpToBit(Offset);
-  RecordData Record;
-  SmallVector<IdentifierInfo*, 16> MacroArgs;
-  MacroInfo *Macro = 0;
-
-  // RAII object to add the loaded macro information once we're done
-  // adding tokens.
-  struct AddLoadedMacroInfoRAII {
-    Preprocessor &PP;
-    MacroInfo *Hint;
-    MacroInfo *MI;
-    IdentifierInfo *II;
-
-    AddLoadedMacroInfoRAII(Preprocessor &PP, MacroInfo *Hint)
-      : PP(PP), Hint(Hint), MI(), II() { }
-    ~AddLoadedMacroInfoRAII( ) {
-      if (MI) {
-        // Finally, install the macro.
-        PP.addLoadedMacroInfo(II, MI, Hint);
-      }
-    }
-  } AddLoadedMacroInfo(PP, Hint);
-
-  while (true) {
-    unsigned Code = Stream.ReadCode();
-    switch (Code) {
-    case llvm::bitc::END_BLOCK:
-      return;
-
-    case llvm::bitc::ENTER_SUBBLOCK:
-      // No known subblocks, always skip them.
-      Stream.ReadSubBlockID();
-      if (Stream.SkipBlock()) {
-        Error("malformed block record in AST file");
-        return;
-      }
-      continue;
-
-    case llvm::bitc::DEFINE_ABBREV:
-      Stream.ReadAbbrevRecord();
-      continue;
-    default: break;
-    }
-
-    // Read a record.
-    const char *BlobStart = 0;
-    unsigned BlobLen = 0;
-    Record.clear();
-    PreprocessorRecordTypes RecType =
-      (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record, BlobStart,
-                                                 BlobLen);
-    switch (RecType) {
-    case PP_MACRO_OBJECT_LIKE:
-    case PP_MACRO_FUNCTION_LIKE: {
-      // If we already have a macro, that means that we've hit the end
-      // of the definition of the macro we were looking for. We're
-      // done.
-      if (Macro)
-        return;
-
-      IdentifierInfo *II = getLocalIdentifier(F, Record[0]);
-      if (II == 0) {
-        Error("macro must have a name in AST file");
-        return;
-      }
-
-      unsigned GlobalID = getGlobalMacroID(F, Record[1]);
-
-      // If this macro has already been loaded, don't do so again.
-      if (MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS])
-        return;
-
-      SubmoduleID GlobalSubmoduleID = getGlobalSubmoduleID(F, Record[2]);
-      unsigned NextIndex = 3;
-      SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
-      MacroInfo *MI = PP.AllocateMacroInfo(Loc);
-
-      // Record this macro.
-      MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS] = MI;
-
-      SourceLocation UndefLoc = ReadSourceLocation(F, Record, NextIndex);
-      if (UndefLoc.isValid())
-        MI->setUndefLoc(UndefLoc);
-
-      MI->setIsUsed(Record[NextIndex++]);
-      MI->setIsFromAST();
-
-      bool IsPublic = Record[NextIndex++];
-      MI->setVisibility(IsPublic, ReadSourceLocation(F, Record, NextIndex));
-
-      if (RecType == PP_MACRO_FUNCTION_LIKE) {
-        // Decode function-like macro info.
-        bool isC99VarArgs = Record[NextIndex++];
-        bool isGNUVarArgs = Record[NextIndex++];
-        bool hasCommaPasting = Record[NextIndex++];
-        MacroArgs.clear();
-        unsigned NumArgs = Record[NextIndex++];
-        for (unsigned i = 0; i != NumArgs; ++i)
-          MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++]));
-
-        // Install function-like macro info.
-        MI->setIsFunctionLike();
-        if (isC99VarArgs) MI->setIsC99Varargs();
-        if (isGNUVarArgs) MI->setIsGNUVarargs();
-        if (hasCommaPasting) MI->setHasCommaPasting();
-        MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
-                            PP.getPreprocessorAllocator());
-      }
-
-      if (DeserializationListener)
-        DeserializationListener->MacroRead(GlobalID, MI);
-
-      // If an update record marked this as undefined, do so now.
-      // FIXME: Only if the submodule this update came from is visible?
-      MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID);
-      if (Update != MacroUpdates.end()) {
-        if (MI->getUndefLoc().isInvalid()) {
-          for (unsigned I = 0, N = Update->second.size(); I != N; ++I) {
-            bool Hidden = false;
-            if (unsigned SubmoduleID = Update->second[I].first) {
-              if (Module *Owner = getSubmodule(SubmoduleID)) {
-                if (Owner->NameVisibility == Module::Hidden) {
-                  // Note that this #undef is hidden.
-                  Hidden = true;
-
-                  // Record this hiding for later.
-                  HiddenNamesMap[Owner].push_back(
-                    HiddenName(II, MI, Update->second[I].second.UndefLoc));
-                }
-              }
-            }
-
-            if (!Hidden) {
-              MI->setUndefLoc(Update->second[I].second.UndefLoc);
-              if (PPMutationListener *Listener = PP.getPPMutationListener())
-                Listener->UndefinedMacro(MI);
-              break;
-            }
-          }
-        }
-        MacroUpdates.erase(Update);
-      }
-
-      // Determine whether this macro definition is visible.
-      bool Hidden = !MI->isPublic();
-      if (!Hidden && GlobalSubmoduleID) {
-        if (Module *Owner = getSubmodule(GlobalSubmoduleID)) {
-          if (Owner->NameVisibility == Module::Hidden) {
-            // The owning module is not visible, and this macro definition
-            // should not be, either.
-            Hidden = true;
-
-            // Note that this macro definition was hidden because its owning
-            // module is not yet visible.
-            HiddenNamesMap[Owner].push_back(HiddenName(II, MI));
-          }
-        }
-      }
-      MI->setHidden(Hidden);
-
-      // Make sure we install the macro once we're done.
-      AddLoadedMacroInfo.MI = MI;
-      AddLoadedMacroInfo.II = II;
-
-      // Remember that we saw this macro last so that we add the tokens that
-      // form its body to it.
-      Macro = MI;
-
-      if (NextIndex + 1 == Record.size() && PP.getPreprocessingRecord() &&
-          Record[NextIndex]) {
-        // We have a macro definition. Register the association
-        PreprocessedEntityID
-            GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]);
-        PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
-        PPRec.RegisterMacroDefinition(Macro,
-                            PPRec.getPPEntityID(GlobalID-1, /*isLoaded=*/true));
-      }
-
-      ++NumMacrosRead;
-      break;
-    }
-
-    case PP_TOKEN: {
-      // If we see a TOKEN before a PP_MACRO_*, then the file is
-      // erroneous, just pretend we didn't see this.
-      if (Macro == 0) break;
-
-      Token Tok;
-      Tok.startToken();
-      Tok.setLocation(ReadSourceLocation(F, Record[0]));
-      Tok.setLength(Record[1]);
-      if (IdentifierInfo *II = getLocalIdentifier(F, Record[2]))
-        Tok.setIdentifierInfo(II);
-      Tok.setKind((tok::TokenKind)Record[3]);
-      Tok.setFlag((Token::TokenFlags)Record[4]);
-      Macro->AddTokenToBody(Tok);
-      break;
-    }
-    }
-  }
-}
-
-PreprocessedEntityID 
-ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const {
-  ContinuousRangeMap<uint32_t, int, 2>::const_iterator 
-    I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);
-  assert(I != M.PreprocessedEntityRemap.end() 
-         && "Invalid index into preprocessed entity index remap");
-  
-  return LocalID + I->second;
-}
-
-unsigned HeaderFileInfoTrait::ComputeHash(const char *path) {
-  return llvm::HashString(llvm::sys::path::filename(path));
-}
-    
-HeaderFileInfoTrait::internal_key_type 
-HeaderFileInfoTrait::GetInternalKey(const char *path) { return path; }
-    
-bool HeaderFileInfoTrait::EqualKey(internal_key_type a, internal_key_type b) {
-  if (strcmp(a, b) == 0)
-    return true;
-  
-  if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b))
-    return false;
-
-  // Determine whether the actual files are equivalent.
-  bool Result = false;
-  if (llvm::sys::fs::equivalent(a, b, Result))
-    return false;
-  
-  return Result;
-}
-    
-std::pair<unsigned, unsigned>
-HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
-  unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
-  unsigned DataLen = (unsigned) *d++;
-  return std::make_pair(KeyLen + 1, DataLen);
-}
-    
-HeaderFileInfoTrait::data_type 
-HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d,
-                              unsigned DataLen) {
-  const unsigned char *End = d + DataLen;
-  using namespace clang::io;
-  HeaderFileInfo HFI;
-  unsigned Flags = *d++;
-  HFI.isImport = (Flags >> 5) & 0x01;
-  HFI.isPragmaOnce = (Flags >> 4) & 0x01;
-  HFI.DirInfo = (Flags >> 2) & 0x03;
-  HFI.Resolved = (Flags >> 1) & 0x01;
-  HFI.IndexHeaderMapHeader = Flags & 0x01;
-  HFI.NumIncludes = ReadUnalignedLE16(d);
-  HFI.ControllingMacroID = Reader.getGlobalIdentifierID(M, 
-                                                        ReadUnalignedLE32(d));
-  if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) {
-    // The framework offset is 1 greater than the actual offset, 
-    // since 0 is used as an indicator for "no framework name".
-    StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
-    HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
-  }
-  
-  assert(End == d && "Wrong data length in HeaderFileInfo deserialization");
-  (void)End;
-        
-  // This HeaderFileInfo was externally loaded.
-  HFI.External = true;
-  return HFI;
-}
-
-void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ArrayRef<MacroID> IDs){
-  II->setHadMacroDefinition(true);
-  assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
-  PendingMacroIDs[II].append(IDs.begin(), IDs.end());
-}
-
-void ASTReader::ReadDefinedMacros() {
-  // Note that we are loading defined macros.
-  Deserializing Macros(this);
-
-  for (ModuleReverseIterator I = ModuleMgr.rbegin(),
-      E = ModuleMgr.rend(); I != E; ++I) {
-    llvm::BitstreamCursor &MacroCursor = (*I)->MacroCursor;
-
-    // If there was no preprocessor block, skip this file.
-    if (!MacroCursor.getBitStreamReader())
-      continue;
-
-    llvm::BitstreamCursor Cursor = MacroCursor;
-    Cursor.JumpToBit((*I)->MacroStartOffset);
-
-    RecordData Record;
-    while (true) {
-      unsigned Code = Cursor.ReadCode();
-      if (Code == llvm::bitc::END_BLOCK)
-        break;
-
-      if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-        // No known subblocks, always skip them.
-        Cursor.ReadSubBlockID();
-        if (Cursor.SkipBlock()) {
-          Error("malformed block record in AST file");
-          return;
-        }
-        continue;
-      }
-
-      if (Code == llvm::bitc::DEFINE_ABBREV) {
-        Cursor.ReadAbbrevRecord();
-        continue;
-      }
-
-      // Read a record.
-      const char *BlobStart;
-      unsigned BlobLen;
-      Record.clear();
-      switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
-      default:  // Default behavior: ignore.
-        break;
-
-      case PP_MACRO_OBJECT_LIKE:
-      case PP_MACRO_FUNCTION_LIKE:
-        getLocalIdentifier(**I, Record[0]);
-        break;
-
-      case PP_TOKEN:
-        // Ignore tokens.
-        break;
-      }
-    }
-  }
-}
-
-namespace {
-  /// \brief Visitor class used to look up identifirs in an AST file.
-  class IdentifierLookupVisitor {
-    StringRef Name;
-    unsigned PriorGeneration;
-    IdentifierInfo *Found;
-  public:
-    IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration) 
-      : Name(Name), PriorGeneration(PriorGeneration), Found() { }
-    
-    static bool visit(ModuleFile &M, void *UserData) {
-      IdentifierLookupVisitor *This
-        = static_cast<IdentifierLookupVisitor *>(UserData);
-      
-      // If we've already searched this module file, skip it now.
-      if (M.Generation <= This->PriorGeneration)
-        return true;
-      
-      ASTIdentifierLookupTable *IdTable
-        = (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
-      if (!IdTable)
-        return false;
-      
-      ASTIdentifierLookupTrait Trait(IdTable->getInfoObj().getReader(),
-                                     M, This->Found);
-                                     
-      std::pair<const char*, unsigned> Key(This->Name.begin(), 
-                                           This->Name.size());
-      ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Trait);
-      if (Pos == IdTable->end())
-        return false;
-      
-      // Dereferencing the iterator has the effect of building the
-      // IdentifierInfo node and populating it with the various
-      // declarations it needs.
-      This->Found = *Pos;
-      return true;
-    }
-    
-    // \brief Retrieve the identifier info found within the module
-    // files.
-    IdentifierInfo *getIdentifierInfo() const { return Found; }
-  };
-}
-
-void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
-  // Note that we are loading an identifier.
-  Deserializing AnIdentifier(this);
-
-  unsigned PriorGeneration = 0;
-  if (getContext().getLangOpts().Modules)
-    PriorGeneration = IdentifierGeneration[&II];
-  
-  IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration);
-  ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
-  markIdentifierUpToDate(&II);
-}
-
-void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
-  if (!II)
-    return;
-  
-  II->setOutOfDate(false);
-
-  // Update the generation for this identifier.
-  if (getContext().getLangOpts().Modules)
-    IdentifierGeneration[II] = CurrentGeneration;
-}
-
-llvm::PointerIntPair<const FileEntry *, 1, bool> 
-ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
-  // If this ID is bogus, just return an empty input file.
-  if (ID == 0 || ID > F.InputFilesLoaded.size())
-    return InputFile();
-
-  // If we've already loaded this input file, return it.
-  if (F.InputFilesLoaded[ID-1].getPointer())
-    return F.InputFilesLoaded[ID-1];
-
-  // Go find this input file.
-  llvm::BitstreamCursor &Cursor = F.InputFilesCursor;
-  SavedStreamPosition SavedPosition(Cursor);
-  Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
-  
-  unsigned Code = Cursor.ReadCode();
-  RecordData Record;
-  const char *BlobStart = 0;
-  unsigned BlobLen = 0;
-  switch ((InputFileRecordTypes)Cursor.ReadRecord(Code, Record,
-                                                  &BlobStart, &BlobLen)) {
-  case INPUT_FILE: {
-    unsigned StoredID = Record[0];
-    assert(ID == StoredID && "Bogus stored ID or offset");
-    (void)StoredID;
-    off_t StoredSize = (off_t)Record[1];
-    time_t StoredTime = (time_t)Record[2];
-    bool Overridden = (bool)Record[3];
-    
-    // Get the file entry for this input file.
-    StringRef OrigFilename(BlobStart, BlobLen);
-    std::string Filename = OrigFilename;
-    MaybeAddSystemRootToFilename(F, Filename);
-    const FileEntry *File 
-      = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)
-                  : FileMgr.getFile(Filename, /*OpenFile=*/false);
-    
-    // If we didn't find the file, resolve it relative to the
-    // original directory from which this AST file was created.
-    if (File == 0 && !F.OriginalDir.empty() && !CurrentDir.empty() &&
-        F.OriginalDir != CurrentDir) {
-      std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
-                                                              F.OriginalDir,
-                                                              CurrentDir);
-      if (!Resolved.empty())
-        File = FileMgr.getFile(Resolved);
-    }
-    
-    // For an overridden file, create a virtual file with the stored
-    // size/timestamp.
-    if (Overridden && File == 0) {
-      File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
-    }
-    
-    if (File == 0) {
-      if (Complain) {
-        std::string ErrorStr = "could not find file '";
-        ErrorStr += Filename;
-        ErrorStr += "' referenced by AST file";
-        Error(ErrorStr.c_str());
-      }
-      return InputFile();
-    }
-    
-    // Note that we've loaded this input file.
-    F.InputFilesLoaded[ID-1] = InputFile(File, Overridden);
-    
-    // Check if there was a request to override the contents of the file
-    // that was part of the precompiled header. Overridding such a file
-    // can lead to problems when lexing using the source locations from the
-    // PCH.
-    SourceManager &SM = getSourceManager();
-    if (!Overridden && SM.isFileOverridden(File)) {
-      Error(diag::err_fe_pch_file_overridden, Filename);
-      // After emitting the diagnostic, recover by disabling the override so
-      // that the original file will be used.
-      SM.disableFileContentsOverride(File);
-      // The FileEntry is a virtual file entry with the size of the contents
-      // that would override the original contents. Set it to the original's
-      // size/time.
-      FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
-                              StoredSize, StoredTime);
-    }
-
-    // For an overridden file, there is nothing to validate.
-    if (Overridden)
-      return InputFile(File, Overridden);
-
-    if ((StoredSize != File->getSize()
-#if !defined(LLVM_ON_WIN32)
-         // In our regression testing, the Windows file system seems to
-         // have inconsistent modification times that sometimes
-         // erroneously trigger this error-handling path.
-         || StoredTime != File->getModificationTime()
-#endif
-         )) {
-      if (Complain)
-        Error(diag::err_fe_pch_file_modified, Filename);
-      
-      return InputFile();
-    }
-
-    return InputFile(File, Overridden);
-  }
-  }
-
-  return InputFile();
-}
-
-const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
-  ModuleFile &M = ModuleMgr.getPrimaryModule();
-  std::string Filename = filenameStrRef;
-  MaybeAddSystemRootToFilename(M, Filename);
-  const FileEntry *File = FileMgr.getFile(Filename);
-  if (File == 0 && !M.OriginalDir.empty() && !CurrentDir.empty() &&
-      M.OriginalDir != CurrentDir) {
-    std::string resolved = resolveFileRelativeToOriginalDir(Filename,
-                                                            M.OriginalDir,
-                                                            CurrentDir);
-    if (!resolved.empty())
-      File = FileMgr.getFile(resolved);
-  }
-
-  return File;
-}
-
-/// \brief If we are loading a relocatable PCH file, and the filename is
-/// not an absolute path, add the system root to the beginning of the file
-/// name.
-void ASTReader::MaybeAddSystemRootToFilename(ModuleFile &M,
-                                             std::string &Filename) {
-  // If this is not a relocatable PCH file, there's nothing to do.
-  if (!M.RelocatablePCH)
-    return;
-
-  if (Filename.empty() || llvm::sys::path::is_absolute(Filename))
-    return;
-
-  if (isysroot.empty()) {
-    // If no system root was given, default to '/'
-    Filename.insert(Filename.begin(), '/');
-    return;
-  }
-
-  unsigned Length = isysroot.size();
-  if (isysroot[Length - 1] != '/')
-    Filename.insert(Filename.begin(), '/');
-
-  Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end());
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadControlBlock(ModuleFile &F,
-                            llvm::SmallVectorImpl<ImportedModule> &Loaded,
-                            unsigned ClientLoadCapabilities) {
-  llvm::BitstreamCursor &Stream = F.Stream;
-
-  if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
-    Error("malformed block record in AST file");
-    return Failure;
-  }
-
-  // Read all of the records and blocks in the control block.
-  RecordData Record;
-  while (!Stream.AtEndOfStream()) {
-    unsigned Code = Stream.ReadCode();
-    if (Code == llvm::bitc::END_BLOCK) {
-      if (Stream.ReadBlockEnd()) {
-        Error("error at end of control block in AST file");
-        return Failure;
-      }
-
-      // Validate all of the input files.
-      if (!DisableValidation) {
-        bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
-        for (unsigned I = 0, N = Record[0]; I < N; ++I)
-          if (!getInputFile(F, I+1, Complain).getPointer())
-            return OutOfDate;
-      }
-
-      return Success;
-    }
-
-    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-      switch (Stream.ReadSubBlockID()) {
-      case INPUT_FILES_BLOCK_ID:
-        F.InputFilesCursor = Stream;
-        if (Stream.SkipBlock() || // Skip with the main cursor
-            // Read the abbreviations
-            ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) {
-          Error("malformed block record in AST file");
-          return Failure;
-        }
-        continue;
-        
-      default:
-        if (!Stream.SkipBlock())
-          continue;
-        break;
-      }
-
-      Error("malformed block record in AST file");
-      return Failure;
-    }
-
-    if (Code == llvm::bitc::DEFINE_ABBREV) {
-      Stream.ReadAbbrevRecord();
-      continue;
-    }
-
-    // Read and process a record.
-    Record.clear();
-    const char *BlobStart = 0;
-    unsigned BlobLen = 0;
-    switch ((ControlRecordTypes)Stream.ReadRecord(Code, Record,
-                                                  &BlobStart, &BlobLen)) {
-    case METADATA: {
-      if (Record[0] != VERSION_MAJOR && !DisableValidation) {
-        if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
-          Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
-                                        : diag::warn_pch_version_too_new);
-        return VersionMismatch;
-      }
-
-      bool hasErrors = Record[5];
-      if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {
-        Diag(diag::err_pch_with_compiler_errors);
-        return HadErrors;
-      }
-
-      F.RelocatablePCH = Record[4];
-
-      const std::string &CurBranch = getClangFullRepositoryVersion();
-      StringRef ASTBranch(BlobStart, BlobLen);
-      if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
-        if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
-          Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
-        return VersionMismatch;
-      }
-      break;
-    }
-
-    case IMPORTS: {
-      // Load each of the imported PCH files. 
-      unsigned Idx = 0, N = Record.size();
-      while (Idx < N) {
-        // Read information about the AST file.
-        ModuleKind ImportedKind = (ModuleKind)Record[Idx++];
-        // The import location will be the local one for now; we will adjust
-        // all import locations of module imports after the global source
-        // location info are setup.
-        SourceLocation ImportLoc =
-            SourceLocation::getFromRawEncoding(Record[Idx++]);
-        unsigned Length = Record[Idx++];
-        SmallString<128> ImportedFile(Record.begin() + Idx,
-                                      Record.begin() + Idx + Length);
-        Idx += Length;
-
-        // Load the AST file.
-        switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded,
-                           ClientLoadCapabilities)) {
-        case Failure: return Failure;
-          // If we have to ignore the dependency, we'll have to ignore this too.
-        case OutOfDate: return OutOfDate;
-        case VersionMismatch: return VersionMismatch;
-        case ConfigurationMismatch: return ConfigurationMismatch;
-        case HadErrors: return HadErrors;
-        case Success: break;
-        }
-      }
-      break;
-    }
-
-    case LANGUAGE_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
-      if (Listener && &F == *ModuleMgr.begin() &&
-          ParseLanguageOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
-        return ConfigurationMismatch;
-      break;
-    }
-
-    case TARGET_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
-      if (Listener && &F == *ModuleMgr.begin() &&
-          ParseTargetOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
-        return ConfigurationMismatch;
-      break;
-    }
-
-    case DIAGNOSTIC_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
-      if (Listener && &F == *ModuleMgr.begin() &&
-          ParseDiagnosticOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
-        return ConfigurationMismatch;
-      break;
-    }
-
-    case FILE_SYSTEM_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
-      if (Listener && &F == *ModuleMgr.begin() &&
-          ParseFileSystemOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
-        return ConfigurationMismatch;
-      break;
-    }
-
-    case HEADER_SEARCH_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
-      if (Listener && &F == *ModuleMgr.begin() &&
-          ParseHeaderSearchOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
-        return ConfigurationMismatch;
-      break;
-    }
-
-    case PREPROCESSOR_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
-      if (Listener && &F == *ModuleMgr.begin() &&
-          ParsePreprocessorOptions(Record, Complain, *Listener,
-                                   SuggestedPredefines) &&
-          !DisableValidation)
-        return ConfigurationMismatch;
-      break;
-    }
-
-    case ORIGINAL_FILE:
-      F.OriginalSourceFileID = FileID::get(Record[0]);
-      F.ActualOriginalSourceFileName.assign(BlobStart, BlobLen);
-      F.OriginalSourceFileName = F.ActualOriginalSourceFileName;
-      MaybeAddSystemRootToFilename(F, F.OriginalSourceFileName);
-      break;
-
-    case ORIGINAL_FILE_ID:
-      F.OriginalSourceFileID = FileID::get(Record[0]);
-      break;
-
-    case ORIGINAL_PCH_DIR:
-      F.OriginalDir.assign(BlobStart, BlobLen);
-      break;
-
-    case INPUT_FILE_OFFSETS:
-      F.InputFileOffsets = (const uint32_t *)BlobStart;
-      F.InputFilesLoaded.resize(Record[0]);
-      break;
-    }
-  }
-
-  Error("premature end of bitstream in AST file");
-  return Failure;
-}
-
-bool ASTReader::ReadASTBlock(ModuleFile &F) {
-  llvm::BitstreamCursor &Stream = F.Stream;
-
-  if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
-    Error("malformed block record in AST file");
-    return true;
-  }
-
-  // Read all of the records and blocks for the AST file.
-  RecordData Record;
-  while (!Stream.AtEndOfStream()) {
-    unsigned Code = Stream.ReadCode();
-    if (Code == llvm::bitc::END_BLOCK) {
-      if (Stream.ReadBlockEnd()) {
-        Error("error at end of module block in AST file");
-        return true;
-      }
-
-      DeclContext *DC = Context.getTranslationUnitDecl();
-      if (!DC->hasExternalVisibleStorage() && DC->hasExternalLexicalStorage())
-        DC->setMustBuildLookupTable();
-
-      return false;
-    }
-
-    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-      switch (Stream.ReadSubBlockID()) {
-      case DECLTYPES_BLOCK_ID:
-        // We lazily load the decls block, but we want to set up the
-        // DeclsCursor cursor to point into it.  Clone our current bitcode
-        // cursor to it, enter the block and read the abbrevs in that block.
-        // With the main cursor, we just skip over it.
-        F.DeclsCursor = Stream;
-        if (Stream.SkipBlock() ||  // Skip with the main cursor.
-            // Read the abbrevs.
-            ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
-          Error("malformed block record in AST file");
-          return true;
-        }
-        break;
-
-      case DECL_UPDATES_BLOCK_ID:
-        if (Stream.SkipBlock()) {
-          Error("malformed block record in AST file");
-          return true;
-        }
-        break;
-
-      case PREPROCESSOR_BLOCK_ID:
-        F.MacroCursor = Stream;
-        if (!PP.getExternalSource())
-          PP.setExternalSource(this);
-
-        if (Stream.SkipBlock() ||
-            ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
-          Error("malformed block record in AST file");
-          return true;
-        }
-        F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
-        break;
-
-      case PREPROCESSOR_DETAIL_BLOCK_ID:
-        F.PreprocessorDetailCursor = Stream;
-        if (Stream.SkipBlock() ||
-            ReadBlockAbbrevs(F.PreprocessorDetailCursor, 
-                             PREPROCESSOR_DETAIL_BLOCK_ID)) {
-          Error("malformed preprocessor detail record in AST file");
-          return true;
-        }
-        F.PreprocessorDetailStartOffset
-          = F.PreprocessorDetailCursor.GetCurrentBitNo();
-          
-        if (!PP.getPreprocessingRecord())
-          PP.createPreprocessingRecord();
-        if (!PP.getPreprocessingRecord()->getExternalSource())
-          PP.getPreprocessingRecord()->SetExternalSource(*this);
-        break;
-        
-      case SOURCE_MANAGER_BLOCK_ID:
-        if (ReadSourceManagerBlock(F))
-          return true;
-        break;
-
-      case SUBMODULE_BLOCK_ID:
-        if (ReadSubmoduleBlock(F))
-          return true;
-        break;
-
-      case COMMENTS_BLOCK_ID: {
-        llvm::BitstreamCursor C = Stream;
-        if (Stream.SkipBlock() ||
-            ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
-          Error("malformed comments block in AST file");
-          return true;
-        }
-        CommentsCursors.push_back(std::make_pair(C, &F));
-        break;
-      }
-
-      default:
-        if (!Stream.SkipBlock())
-          break;
-        Error("malformed block record in AST file");
-        return true;
-      }
-      continue;
-    }
-
-    if (Code == llvm::bitc::DEFINE_ABBREV) {
-      Stream.ReadAbbrevRecord();
-      continue;
-    }
-
-    // Read and process a record.
-    Record.clear();
-    const char *BlobStart = 0;
-    unsigned BlobLen = 0;
-    switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
-                                              &BlobStart, &BlobLen)) {
-    default:  // Default behavior: ignore.
-      break;
-
-    case TYPE_OFFSET: {
-      if (F.LocalNumTypes != 0) {
-        Error("duplicate TYPE_OFFSET record in AST file");
-        return true;
-      }
-      F.TypeOffsets = (const uint32_t *)BlobStart;
-      F.LocalNumTypes = Record[0];
-      unsigned LocalBaseTypeIndex = Record[1];
-      F.BaseTypeIndex = getTotalNumTypes();
-        
-      if (F.LocalNumTypes > 0) {
-        // Introduce the global -> local mapping for types within this module.
-        GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));
-        
-        // Introduce the local -> global mapping for types within this module.
-        F.TypeRemap.insertOrReplace(
-          std::make_pair(LocalBaseTypeIndex, 
-                         F.BaseTypeIndex - LocalBaseTypeIndex));
-        
-        TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);
-      }
-      break;
-    }
-        
-    case DECL_OFFSET: {
-      if (F.LocalNumDecls != 0) {
-        Error("duplicate DECL_OFFSET record in AST file");
-        return true;
-      }
-      F.DeclOffsets = (const DeclOffset *)BlobStart;
-      F.LocalNumDecls = Record[0];
-      unsigned LocalBaseDeclID = Record[1];
-      F.BaseDeclID = getTotalNumDecls();
-        
-      if (F.LocalNumDecls > 0) {
-        // Introduce the global -> local mapping for declarations within this 
-        // module.
-        GlobalDeclMap.insert(
-          std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));
-        
-        // Introduce the local -> global mapping for declarations within this
-        // module.
-        F.DeclRemap.insertOrReplace(
-          std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID));
-        
-        // Introduce the global -> local mapping for declarations within this
-        // module.
-        F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID;
-        
-        DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);
-      }
-      break;
-    }
-        
-    case TU_UPDATE_LEXICAL: {
-      DeclContext *TU = Context.getTranslationUnitDecl();
-      DeclContextInfo &Info = F.DeclContextInfos[TU];
-      Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair *>(BlobStart);
-      Info.NumLexicalDecls 
-        = static_cast<unsigned int>(BlobLen / sizeof(KindDeclIDPair));
-      TU->setHasExternalLexicalStorage(true);
-      break;
-    }
-
-    case UPDATE_VISIBLE: {
-      unsigned Idx = 0;
-      serialization::DeclID ID = ReadDeclID(F, Record, Idx);
-      ASTDeclContextNameLookupTable *Table =
-        ASTDeclContextNameLookupTable::Create(
-                        (const unsigned char *)BlobStart + Record[Idx++],
-                        (const unsigned char *)BlobStart,
-                        ASTDeclContextNameLookupTrait(*this, F));
-      if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?
-        DeclContext *TU = Context.getTranslationUnitDecl();
-        F.DeclContextInfos[TU].NameLookupTableData = Table;
-        TU->setHasExternalVisibleStorage(true);
-      } else
-        PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));
-      break;
-    }
-
-    case IDENTIFIER_TABLE:
-      F.IdentifierTableData = BlobStart;
-      if (Record[0]) {
-        F.IdentifierLookupTable
-          = ASTIdentifierLookupTable::Create(
-                       (const unsigned char *)F.IdentifierTableData + Record[0],
-                       (const unsigned char *)F.IdentifierTableData,
-                       ASTIdentifierLookupTrait(*this, F));
-        
-        PP.getIdentifierTable().setExternalIdentifierLookup(this);
-      }
-      break;
-
-    case IDENTIFIER_OFFSET: {
-      if (F.LocalNumIdentifiers != 0) {
-        Error("duplicate IDENTIFIER_OFFSET record in AST file");
-        return true;
-      }
-      F.IdentifierOffsets = (const uint32_t *)BlobStart;
-      F.LocalNumIdentifiers = Record[0];
-      unsigned LocalBaseIdentifierID = Record[1];
-      F.BaseIdentifierID = getTotalNumIdentifiers();
-        
-      if (F.LocalNumIdentifiers > 0) {
-        // Introduce the global -> local mapping for identifiers within this
-        // module.
-        GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, 
-                                                  &F));
-        
-        // Introduce the local -> global mapping for identifiers within this
-        // module.
-        F.IdentifierRemap.insertOrReplace(
-          std::make_pair(LocalBaseIdentifierID,
-                         F.BaseIdentifierID - LocalBaseIdentifierID));
-        
-        IdentifiersLoaded.resize(IdentifiersLoaded.size() 
-                                 + F.LocalNumIdentifiers);
-      }
-      break;
-    }
-
-    case EXTERNAL_DEFINITIONS:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case SPECIAL_TYPES:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        SpecialTypes.push_back(getGlobalTypeID(F, Record[I]));
-      break;
-
-    case STATISTICS:
-      TotalNumStatements += Record[0];
-      TotalNumMacros += Record[1];
-      TotalLexicalDeclContexts += Record[2];
-      TotalVisibleDeclContexts += Record[3];
-      break;
-
-    case UNUSED_FILESCOPED_DECLS:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case DELEGATING_CTORS:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case WEAK_UNDECLARED_IDENTIFIERS:
-      if (Record.size() % 4 != 0) {
-        Error("invalid weak identifiers record");
-        return true;
-      }
-        
-      // FIXME: Ignore weak undeclared identifiers from non-original PCH 
-      // files. This isn't the way to do it :)
-      WeakUndeclaredIdentifiers.clear();
-        
-      // Translate the weak, undeclared identifiers into global IDs.
-      for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) {
-        WeakUndeclaredIdentifiers.push_back(
-          getGlobalIdentifierID(F, Record[I++]));
-        WeakUndeclaredIdentifiers.push_back(
-          getGlobalIdentifierID(F, Record[I++]));
-        WeakUndeclaredIdentifiers.push_back(
-          ReadSourceLocation(F, Record, I).getRawEncoding());
-        WeakUndeclaredIdentifiers.push_back(Record[I++]);
-      }
-      break;
-
-    case LOCALLY_SCOPED_EXTERNAL_DECLS:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        LocallyScopedExternalDecls.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case SELECTOR_OFFSETS: {
-      F.SelectorOffsets = (const uint32_t *)BlobStart;
-      F.LocalNumSelectors = Record[0];
-      unsigned LocalBaseSelectorID = Record[1];
-      F.BaseSelectorID = getTotalNumSelectors();
-        
-      if (F.LocalNumSelectors > 0) {
-        // Introduce the global -> local mapping for selectors within this 
-        // module.
-        GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F));
-        
-        // Introduce the local -> global mapping for selectors within this 
-        // module.
-        F.SelectorRemap.insertOrReplace(
-          std::make_pair(LocalBaseSelectorID,
-                         F.BaseSelectorID - LocalBaseSelectorID));
-
-        SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);        
-      }
-      break;
-    }
-        
-    case METHOD_POOL:
-      F.SelectorLookupTableData = (const unsigned char *)BlobStart;
-      if (Record[0])
-        F.SelectorLookupTable
-          = ASTSelectorLookupTable::Create(
-                        F.SelectorLookupTableData + Record[0],
-                        F.SelectorLookupTableData,
-                        ASTSelectorLookupTrait(*this, F));
-      TotalNumMethodPoolEntries += Record[1];
-      break;
-
-    case REFERENCED_SELECTOR_POOL:
-      if (!Record.empty()) {
-        for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {
-          ReferencedSelectorsData.push_back(getGlobalSelectorID(F, 
-                                                                Record[Idx++]));
-          ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx).
-                                              getRawEncoding());
-        }
-      }
-      break;
-
-    case PP_COUNTER_VALUE:
-      if (!Record.empty() && Listener)
-        Listener->ReadCounter(F, Record[0]);
-      break;
-      
-    case FILE_SORTED_DECLS:
-      F.FileSortedDecls = (const DeclID *)BlobStart;
-      F.NumFileSortedDecls = Record[0];
-      break;
-
-    case SOURCE_LOCATION_OFFSETS: {
-      F.SLocEntryOffsets = (const uint32_t *)BlobStart;
-      F.LocalNumSLocEntries = Record[0];
-      unsigned SLocSpaceSize = Record[1];
-      llvm::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
-          SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
-                                              SLocSpaceSize);
-      // Make our entry in the range map. BaseID is negative and growing, so
-      // we invert it. Because we invert it, though, we need the other end of
-      // the range.
-      unsigned RangeStart =
-          unsigned(-F.SLocEntryBaseID) - F.LocalNumSLocEntries + 1;
-      GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F));
-      F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset);
-
-      // SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing.
-      assert((F.SLocEntryBaseOffset & (1U << 31U)) == 0);
-      GlobalSLocOffsetMap.insert(
-          std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset
-                           - SLocSpaceSize,&F));
-
-      // Initialize the remapping table.
-      // Invalid stays invalid.
-      F.SLocRemap.insert(std::make_pair(0U, 0));
-      // This module. Base was 2 when being compiled.
-      F.SLocRemap.insert(std::make_pair(2U,
-                                  static_cast<int>(F.SLocEntryBaseOffset - 2)));
-      
-      TotalNumSLocEntries += F.LocalNumSLocEntries;
-      break;
-    }
-
-    case MODULE_OFFSET_MAP: {
-      // Additional remapping information.
-      const unsigned char *Data = (const unsigned char*)BlobStart;
-      const unsigned char *DataEnd = Data + BlobLen;
-      
-      // Continuous range maps we may be updating in our module.
-      ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder 
-        IdentifierRemap(F.IdentifierRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder
-        MacroRemap(F.MacroRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder
-        PreprocessedEntityRemap(F.PreprocessedEntityRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder 
-        SubmoduleRemap(F.SubmoduleRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder 
-        SelectorRemap(F.SelectorRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap);
-      ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap);
-
-      while(Data < DataEnd) {
-        uint16_t Len = io::ReadUnalignedLE16(Data);
-        StringRef Name = StringRef((const char*)Data, Len);
-        Data += Len;
-        ModuleFile *OM = ModuleMgr.lookup(Name);
-        if (!OM) {
-          Error("SourceLocation remap refers to unknown module");
-          return true;
-        }
-
-        uint32_t SLocOffset = io::ReadUnalignedLE32(Data);
-        uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t MacroIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t SubmoduleIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t DeclIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t TypeIndexOffset = io::ReadUnalignedLE32(Data);
-        
-        // Source location offset is mapped to OM->SLocEntryBaseOffset.
-        SLocRemap.insert(std::make_pair(SLocOffset,
-          static_cast<int>(OM->SLocEntryBaseOffset - SLocOffset)));
-        IdentifierRemap.insert(
-          std::make_pair(IdentifierIDOffset, 
-                         OM->BaseIdentifierID - IdentifierIDOffset));
-        MacroRemap.insert(std::make_pair(MacroIDOffset,
-                                         OM->BaseMacroID - MacroIDOffset));
-        PreprocessedEntityRemap.insert(
-          std::make_pair(PreprocessedEntityIDOffset, 
-            OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset));
-        SubmoduleRemap.insert(std::make_pair(SubmoduleIDOffset, 
-                                      OM->BaseSubmoduleID - SubmoduleIDOffset));
-        SelectorRemap.insert(std::make_pair(SelectorIDOffset, 
-                               OM->BaseSelectorID - SelectorIDOffset));
-        DeclRemap.insert(std::make_pair(DeclIDOffset, 
-                                        OM->BaseDeclID - DeclIDOffset));
-        
-        TypeRemap.insert(std::make_pair(TypeIndexOffset, 
-                                    OM->BaseTypeIndex - TypeIndexOffset));
-
-        // Global -> local mappings.
-        F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;
-      }
-      break;
-    }
-
-    case SOURCE_MANAGER_LINE_TABLE:
-      if (ParseLineTable(F, Record))
-        return true;
-      break;
-
-    case SOURCE_LOCATION_PRELOADS: {
-      // Need to transform from the local view (1-based IDs) to the global view,
-      // which is based off F.SLocEntryBaseID.
-      if (!F.PreloadSLocEntries.empty()) {
-        Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
-        return true;
-      }
-      
-      F.PreloadSLocEntries.swap(Record);
-      break;
-    }
-
-    case EXT_VECTOR_DECLS:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case VTABLE_USES:
-      if (Record.size() % 3 != 0) {
-        Error("Invalid VTABLE_USES record");
-        return true;
-      }
-        
-      // Later tables overwrite earlier ones.
-      // FIXME: Modules will have some trouble with this. This is clearly not
-      // the right way to do this.
-      VTableUses.clear();
-        
-      for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
-        VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));
-        VTableUses.push_back(
-          ReadSourceLocation(F, Record, Idx).getRawEncoding());
-        VTableUses.push_back(Record[Idx++]);
-      }
-      break;
-
-    case DYNAMIC_CLASSES:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        DynamicClasses.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case PENDING_IMPLICIT_INSTANTIATIONS:
-      if (PendingInstantiations.size() % 2 != 0) {
-        Error("Invalid existing PendingInstantiations");
-        return true;
-      }
-
-      if (Record.size() % 2 != 0) {
-        Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
-        return true;
-      }
-
-      for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
-        PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));
-        PendingInstantiations.push_back(
-          ReadSourceLocation(F, Record, I).getRawEncoding());
-      }
-      break;
-
-    case SEMA_DECL_REFS:
-      // Later tables overwrite earlier ones.
-      // FIXME: Modules will have some trouble with this.
-      SemaDeclRefs.clear();
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case PPD_ENTITIES_OFFSETS: {
-      F.PreprocessedEntityOffsets = (const PPEntityOffset *)BlobStart;
-      assert(BlobLen % sizeof(PPEntityOffset) == 0);
-      F.NumPreprocessedEntities = BlobLen / sizeof(PPEntityOffset);
-
-      unsigned LocalBasePreprocessedEntityID = Record[0];
-      
-      unsigned StartingID;
-      if (!PP.getPreprocessingRecord())
-        PP.createPreprocessingRecord();
-      if (!PP.getPreprocessingRecord()->getExternalSource())
-        PP.getPreprocessingRecord()->SetExternalSource(*this);
-      StartingID 
-        = PP.getPreprocessingRecord()
-            ->allocateLoadedEntities(F.NumPreprocessedEntities);
-      F.BasePreprocessedEntityID = StartingID;
-
-      if (F.NumPreprocessedEntities > 0) {
-        // Introduce the global -> local mapping for preprocessed entities in
-        // this module.
-        GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));
-       
-        // Introduce the local -> global mapping for preprocessed entities in
-        // this module.
-        F.PreprocessedEntityRemap.insertOrReplace(
-          std::make_pair(LocalBasePreprocessedEntityID,
-            F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID));
-      }
-
-      break;
-    }
-        
-    case DECL_UPDATE_OFFSETS: {
-      if (Record.size() % 2 != 0) {
-        Error("invalid DECL_UPDATE_OFFSETS block in AST file");
-        return true;
-      }
-      for (unsigned I = 0, N = Record.size(); I != N; I += 2)
-        DeclUpdateOffsets[getGlobalDeclID(F, Record[I])]
-          .push_back(std::make_pair(&F, Record[I+1]));
-      break;
-    }
-
-    case DECL_REPLACEMENTS: {
-      if (Record.size() % 3 != 0) {
-        Error("invalid DECL_REPLACEMENTS block in AST file");
-        return true;
-      }
-      for (unsigned I = 0, N = Record.size(); I != N; I += 3)
-        ReplacedDecls[getGlobalDeclID(F, Record[I])]
-          = ReplacedDeclInfo(&F, Record[I+1], Record[I+2]);
-      break;
-    }
-
-    case OBJC_CATEGORIES_MAP: {
-      if (F.LocalNumObjCCategoriesInMap != 0) {
-        Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
-        return true;
-      }
-      
-      F.LocalNumObjCCategoriesInMap = Record[0];
-      F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)BlobStart;
-      break;
-    }
-        
-    case OBJC_CATEGORIES:
-      F.ObjCCategories.swap(Record);
-      break;
-        
-    case CXX_BASE_SPECIFIER_OFFSETS: {
-      if (F.LocalNumCXXBaseSpecifiers != 0) {
-        Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file");
-        return true;
-      }
-      
-      F.LocalNumCXXBaseSpecifiers = Record[0];
-      F.CXXBaseSpecifiersOffsets = (const uint32_t *)BlobStart;
-      NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers;
-      break;
-    }
-
-    case DIAG_PRAGMA_MAPPINGS:
-      if (F.PragmaDiagMappings.empty())
-        F.PragmaDiagMappings.swap(Record);
-      else
-        F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),
-                                    Record.begin(), Record.end());
-      break;
-        
-    case CUDA_SPECIAL_DECL_REFS:
-      // Later tables overwrite earlier ones.
-      // FIXME: Modules will have trouble with this.
-      CUDASpecialDeclRefs.clear();
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
-    case HEADER_SEARCH_TABLE: {
-      F.HeaderFileInfoTableData = BlobStart;
-      F.LocalNumHeaderFileInfos = Record[1];
-      F.HeaderFileFrameworkStrings = BlobStart + Record[2];
-      if (Record[0]) {
-        F.HeaderFileInfoTable
-          = HeaderFileInfoLookupTable::Create(
-                   (const unsigned char *)F.HeaderFileInfoTableData + Record[0],
-                   (const unsigned char *)F.HeaderFileInfoTableData,
-                   HeaderFileInfoTrait(*this, F, 
-                                       &PP.getHeaderSearchInfo(),
-                                       BlobStart + Record[2]));
-        
-        PP.getHeaderSearchInfo().SetExternalSource(this);
-        if (!PP.getHeaderSearchInfo().getExternalLookup())
-          PP.getHeaderSearchInfo().SetExternalLookup(this);
-      }
-      break;
-    }
-        
-    case FP_PRAGMA_OPTIONS:
-      // Later tables overwrite earlier ones.
-      FPPragmaOptions.swap(Record);
-      break;
-
-    case OPENCL_EXTENSIONS:
-      // Later tables overwrite earlier ones.
-      OpenCLExtensions.swap(Record);
-      break;
-
-    case TENTATIVE_DEFINITIONS:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-        
-    case KNOWN_NAMESPACES:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-        
-    case IMPORTED_MODULES: {
-      if (F.Kind != MK_Module) {
-        // If we aren't loading a module (which has its own exports), make
-        // all of the imported modules visible.
-        // FIXME: Deal with macros-only imports.
-        for (unsigned I = 0, N = Record.size(); I != N; ++I) {
-          if (unsigned GlobalID = getGlobalSubmoduleID(F, Record[I]))
-            ImportedModules.push_back(GlobalID);
-        }
-      }
-      break;
-    }
-
-    case LOCAL_REDECLARATIONS: {
-      F.RedeclarationChains.swap(Record);
-      break;
-    }
-        
-    case LOCAL_REDECLARATIONS_MAP: {
-      if (F.LocalNumRedeclarationsInMap != 0) {
-        Error("duplicate LOCAL_REDECLARATIONS_MAP record in AST file");
-        return true;
-      }
-      
-      F.LocalNumRedeclarationsInMap = Record[0];
-      F.RedeclarationsMap = (const LocalRedeclarationsInfo *)BlobStart;
-      break;
-    }
-        
-    case MERGED_DECLARATIONS: {
-      for (unsigned Idx = 0; Idx < Record.size(); /* increment in loop */) {
-        GlobalDeclID CanonID = getGlobalDeclID(F, Record[Idx++]);
-        SmallVectorImpl<GlobalDeclID> &Decls = StoredMergedDecls[CanonID];
-        for (unsigned N = Record[Idx++]; N > 0; --N)
-          Decls.push_back(getGlobalDeclID(F, Record[Idx++]));
-      }
-      break;
-    }
-
-    case MACRO_OFFSET: {
-      if (F.LocalNumMacros != 0) {
-        Error("duplicate MACRO_OFFSET record in AST file");
-        return true;
-      }
-      F.MacroOffsets = (const uint32_t *)BlobStart;
-      F.LocalNumMacros = Record[0];
-      unsigned LocalBaseMacroID = Record[1];
-      F.BaseMacroID = getTotalNumMacros();
-
-      if (F.LocalNumMacros > 0) {
-        // Introduce the global -> local mapping for macros within this module.
-        GlobalMacroMap.insert(std::make_pair(getTotalNumMacros() + 1, &F));
-
-        // Introduce the local -> global mapping for macros within this module.
-        F.MacroRemap.insertOrReplace(
-          std::make_pair(LocalBaseMacroID,
-                         F.BaseMacroID - LocalBaseMacroID));
-
-        MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros);
-      }
-      break;
-    }
-
-    case MACRO_UPDATES: {
-      for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
-        MacroID ID = getGlobalMacroID(F, Record[I++]);
-        if (I == N)
-          break;
-
-        SourceLocation UndefLoc = ReadSourceLocation(F, Record, I);
-        SubmoduleID SubmoduleID = getGlobalSubmoduleID(F, Record[I++]);;
-        MacroUpdate Update;
-        Update.UndefLoc = UndefLoc;
-        MacroUpdates[ID].push_back(std::make_pair(SubmoduleID, Update));
-      }
-      break;
-    }
-    }
-  }
-  Error("premature end of bitstream in AST file");
-  return true;
-}
-
-void ASTReader::makeNamesVisible(const HiddenNames &Names) {
-  for (unsigned I = 0, N = Names.size(); I != N; ++I) {
-    switch (Names[I].getKind()) {
-    case HiddenName::Declaration:
-      Names[I].getDecl()->Hidden = false;
-      break;
-
-    case HiddenName::MacroVisibility: {
-      std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro();
-      Macro.second->setHidden(!Macro.second->isPublic());
-      if (Macro.second->isDefined()) {
-        PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
-      }
-      break;
-    }
-
-    case HiddenName::MacroUndef: {
-      std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro();
-      if (Macro.second->isDefined()) {
-        Macro.second->setUndefLoc(Names[I].getMacroUndefLoc());
-        if (PPMutationListener *Listener = PP.getPPMutationListener())
-          Listener->UndefinedMacro(Macro.second);
-        PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
-      }
-      break;
-    }
-    }
-  }
-}
-
-void ASTReader::makeModuleVisible(Module *Mod, 
-                                  Module::NameVisibilityKind NameVisibility) {
-  llvm::SmallPtrSet<Module *, 4> Visited;
-  llvm::SmallVector<Module *, 4> Stack;
-  Stack.push_back(Mod);  
-  while (!Stack.empty()) {
-    Mod = Stack.back();
-    Stack.pop_back();
-
-    if (NameVisibility <= Mod->NameVisibility) {
-      // This module already has this level of visibility (or greater), so 
-      // there is nothing more to do.
-      continue;
-    }
-    
-    if (!Mod->isAvailable()) {
-      // Modules that aren't available cannot be made visible.
-      continue;
-    }
-
-    // Update the module's name visibility.
-    Mod->NameVisibility = NameVisibility;
-    
-    // If we've already deserialized any names from this module,
-    // mark them as visible.
-    HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod);
-    if (Hidden != HiddenNamesMap.end()) {
-      makeNamesVisible(Hidden->second);
-      HiddenNamesMap.erase(Hidden);
-    }
-    
-    // Push any non-explicit submodules onto the stack to be marked as
-    // visible.
-    for (Module::submodule_iterator Sub = Mod->submodule_begin(),
-                                 SubEnd = Mod->submodule_end();
-         Sub != SubEnd; ++Sub) {
-      if (!(*Sub)->IsExplicit && Visited.insert(*Sub))
-        Stack.push_back(*Sub);
-    }
-    
-    // Push any exported modules onto the stack to be marked as visible.
-    bool AnyWildcard = false;
-    bool UnrestrictedWildcard = false;
-    llvm::SmallVector<Module *, 4> WildcardRestrictions;
-    for (unsigned I = 0, N = Mod->Exports.size(); I != N; ++I) {
-      Module *Exported = Mod->Exports[I].getPointer();
-      if (!Mod->Exports[I].getInt()) {
-        // Export a named module directly; no wildcards involved.
-        if (Visited.insert(Exported))
-          Stack.push_back(Exported);
-        
-        continue;
-      }
-      
-      // Wildcard export: export all of the imported modules that match
-      // the given pattern.
-      AnyWildcard = true;
-      if (UnrestrictedWildcard)
-        continue;
-
-      if (Module *Restriction = Mod->Exports[I].getPointer())
-        WildcardRestrictions.push_back(Restriction);
-      else {
-        WildcardRestrictions.clear();
-        UnrestrictedWildcard = true;
-      }
-    }
-    
-    // If there were any wildcards, push any imported modules that were
-    // re-exported by the wildcard restriction.
-    if (!AnyWildcard)
-      continue;
-    
-    for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) {
-      Module *Imported = Mod->Imports[I];
-      if (!Visited.insert(Imported))
-        continue;
-      
-      bool Acceptable = UnrestrictedWildcard;
-      if (!Acceptable) {
-        // Check whether this module meets one of the restrictions.
-        for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
-          Module *Restriction = WildcardRestrictions[R];
-          if (Imported == Restriction || Imported->isSubModuleOf(Restriction)) {
-            Acceptable = true;
-            break;
-          }
-        }
-      }
-      
-      if (!Acceptable)
-        continue;
-      
-      Stack.push_back(Imported);
-    }
-  }
-}
-
-ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
-                                            ModuleKind Type,
-                                            SourceLocation ImportLoc,
-                                            unsigned ClientLoadCapabilities) {
-  // Bump the generation number.
-  unsigned PreviousGeneration = CurrentGeneration++;
-
-  unsigned NumModules = ModuleMgr.size();
-  llvm::SmallVector<ImportedModule, 4> Loaded;
-  switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
-                                                /*ImportedBy=*/0, Loaded,
-                                                ClientLoadCapabilities)) {
-  case Failure:
-  case OutOfDate:
-  case VersionMismatch:
-  case ConfigurationMismatch:
-  case HadErrors:
-    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end());
-    return ReadResult;
-
-  case Success:
-    break;
-  }
-
-  // Here comes stuff that we only do once the entire chain is loaded.
-
-  // Load the AST blocks of all of the modules that we loaded.
-  for (llvm::SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),
-                                                  MEnd = Loaded.end();
-       M != MEnd; ++M) {
-    ModuleFile &F = *M->Mod;
-
-    // Read the AST block.
-    if (ReadASTBlock(F))
-      return Failure;
-
-    // Once read, set the ModuleFile bit base offset and update the size in 
-    // bits of all files we've seen.
-    F.GlobalBitOffset = TotalModulesSizeInBits;
-    TotalModulesSizeInBits += F.SizeInBits;
-    GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
-    
-    // Preload SLocEntries.
-    for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {
-      int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
-      // Load it through the SourceManager and don't call ReadSLocEntry()
-      // directly because the entry may have already been loaded in which case
-      // calling ReadSLocEntry() directly would trigger an assertion in
-      // SourceManager.
-      SourceMgr.getLoadedSLocEntryByID(Index);
-    }
-  }
-
-  // Setup the import locations.
-  for (llvm::SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),
-                                                    MEnd = Loaded.end();
-       M != MEnd; ++M) {
-    ModuleFile &F = *M->Mod;
-    if (!M->ImportedBy)
-      F.ImportLoc = M->ImportLoc;
-    else
-      F.ImportLoc = ReadSourceLocation(*M->ImportedBy,
-                                       M->ImportLoc.getRawEncoding());
-  }
-
-  // Mark all of the identifiers in the identifier table as being out of date,
-  // so that various accessors know to check the loaded modules when the
-  // identifier is used.
-  for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
-                              IdEnd = PP.getIdentifierTable().end();
-       Id != IdEnd; ++Id)
-    Id->second->setOutOfDate(true);
-  
-  // Resolve any unresolved module exports.
-  for (unsigned I = 0, N = UnresolvedModuleImportExports.size(); I != N; ++I) {
-    UnresolvedModuleImportExport &Unresolved = UnresolvedModuleImportExports[I];
-    SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID);
-    Module *ResolvedMod = getSubmodule(GlobalID);
-    
-    if (Unresolved.IsImport) {
-      if (ResolvedMod)
-        Unresolved.Mod->Imports.push_back(ResolvedMod);
-      continue;
-    }
-
-    if (ResolvedMod || Unresolved.IsWildcard)
-      Unresolved.Mod->Exports.push_back(
-        Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));
-  }
-  UnresolvedModuleImportExports.clear();
-  
-  InitializeContext();
-
-  if (DeserializationListener)
-    DeserializationListener->ReaderInitialized(this);
-
-  ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule();
-  if (!PrimaryModule.OriginalSourceFileID.isInvalid()) {
-    PrimaryModule.OriginalSourceFileID 
-      = FileID::get(PrimaryModule.SLocEntryBaseID
-                    + PrimaryModule.OriginalSourceFileID.getOpaqueValue() - 1);
-
-    // If this AST file is a precompiled preamble, then set the
-    // preamble file ID of the source manager to the file source file
-    // from which the preamble was built.
-    if (Type == MK_Preamble) {
-      SourceMgr.setPreambleFileID(PrimaryModule.OriginalSourceFileID);
-    } else if (Type == MK_MainFile) {
-      SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID);
-    }
-  }
-  
-  // For any Objective-C class definitions we have already loaded, make sure
-  // that we load any additional categories.
-  for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) {
-    loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), 
-                       ObjCClassesLoaded[I],
-                       PreviousGeneration);
-  }
-  
-  return Success;
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadASTCore(StringRef FileName,
-                       ModuleKind Type,
-                       SourceLocation ImportLoc,
-                       ModuleFile *ImportedBy,
-                       llvm::SmallVectorImpl<ImportedModule> &Loaded,
-                       unsigned ClientLoadCapabilities) {
-  ModuleFile *M;
-  bool NewModule;
-  std::string ErrorStr;
-  llvm::tie(M, NewModule) = ModuleMgr.addModule(FileName, Type, ImportLoc,
-                                                ImportedBy, CurrentGeneration,
-                                                ErrorStr);
-
-  if (!M) {
-    // We couldn't load the module.
-    std::string Msg = "Unable to load module \"" + FileName.str() + "\": "
-      + ErrorStr;
-    Error(Msg);
-    return Failure;
-  }
-
-  if (!NewModule) {
-    // We've already loaded this module.
-    return Success;
-  }
-
-  // FIXME: This seems rather a hack. Should CurrentDir be part of the
-  // module?
-  if (FileName != "-") {
-    CurrentDir = llvm::sys::path::parent_path(FileName);
-    if (CurrentDir.empty()) CurrentDir = ".";
-  }
-
-  ModuleFile &F = *M;
-  llvm::BitstreamCursor &Stream = F.Stream;
-  Stream.init(F.StreamFile);
-  F.SizeInBits = F.Buffer->getBufferSize() * 8;
-  
-  // Sniff for the signature.
-  if (Stream.Read(8) != 'C' ||
-      Stream.Read(8) != 'P' ||
-      Stream.Read(8) != 'C' ||
-      Stream.Read(8) != 'H') {
-    Diag(diag::err_not_a_pch_file) << FileName;
-    return Failure;
-  }
-
-  // This is used for compatibility with older PCH formats.
-  bool HaveReadControlBlock = false;
-
-  while (!Stream.AtEndOfStream()) {
-    unsigned Code = Stream.ReadCode();
-
-    if (Code != llvm::bitc::ENTER_SUBBLOCK) {
-      Error("invalid record at top-level of AST file");
-      return Failure;
-    }
-
-    unsigned BlockID = Stream.ReadSubBlockID();
-
-    // We only know the control subblock ID.
-    switch (BlockID) {
-    case llvm::bitc::BLOCKINFO_BLOCK_ID:
-      if (Stream.ReadBlockInfoBlock()) {
-        Error("malformed BlockInfoBlock in AST file");
-        return Failure;
-      }
-      break;
-    case CONTROL_BLOCK_ID:
-      HaveReadControlBlock = true;
-      switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {
-      case Success:
-        break;
-
-      case Failure: return Failure;
-      case OutOfDate: return OutOfDate;
-      case VersionMismatch: return VersionMismatch;
-      case ConfigurationMismatch: return ConfigurationMismatch;
-      case HadErrors: return HadErrors;
-      }
-      break;
-    case AST_BLOCK_ID:
-      if (!HaveReadControlBlock) {
-        if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
-          Diag(diag::warn_pch_version_too_old);
-        return VersionMismatch;
-      }
-
-      // Record that we've loaded this module.
-      Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
-      return Success;
-
-    default:
-      if (Stream.SkipBlock()) {
-        Error("malformed block record in AST file");
-        return Failure;
-      }
-      break;
-    }
-  }
-  
-  return Success;
-}
-
-void ASTReader::InitializeContext() {  
-  // If there's a listener, notify them that we "read" the translation unit.
-  if (DeserializationListener)
-    DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, 
-                                      Context.getTranslationUnitDecl());
-
-  // Make sure we load the declaration update records for the translation unit,
-  // if there are any.
-  loadDeclUpdateRecords(PREDEF_DECL_TRANSLATION_UNIT_ID, 
-                        Context.getTranslationUnitDecl());
-  
-  // FIXME: Find a better way to deal with collisions between these
-  // built-in types. Right now, we just ignore the problem.
-  
-  // Load the special types.
-  if (SpecialTypes.size() >= NumSpecialTypeIDs) {
-    if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
-      if (!Context.CFConstantStringTypeDecl)
-        Context.setCFConstantStringType(GetType(String));
-    }
-    
-    if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
-      QualType FileType = GetType(File);
-      if (FileType.isNull()) {
-        Error("FILE type is NULL");
-        return;
-      }
-      
-      if (!Context.FILEDecl) {
-        if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
-          Context.setFILEDecl(Typedef->getDecl());
-        else {
-          const TagType *Tag = FileType->getAs<TagType>();
-          if (!Tag) {
-            Error("Invalid FILE type in AST file");
-            return;
-          }
-          Context.setFILEDecl(Tag->getDecl());
-        }
-      }
-    }
-    
-    if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {
-      QualType Jmp_bufType = GetType(Jmp_buf);
-      if (Jmp_bufType.isNull()) {
-        Error("jmp_buf type is NULL");
-        return;
-      }
-      
-      if (!Context.jmp_bufDecl) {
-        if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
-          Context.setjmp_bufDecl(Typedef->getDecl());
-        else {
-          const TagType *Tag = Jmp_bufType->getAs<TagType>();
-          if (!Tag) {
-            Error("Invalid jmp_buf type in AST file");
-            return;
-          }
-          Context.setjmp_bufDecl(Tag->getDecl());
-        }
-      }
-    }
-    
-    if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {
-      QualType Sigjmp_bufType = GetType(Sigjmp_buf);
-      if (Sigjmp_bufType.isNull()) {
-        Error("sigjmp_buf type is NULL");
-        return;
-      }
-      
-      if (!Context.sigjmp_bufDecl) {
-        if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
-          Context.setsigjmp_bufDecl(Typedef->getDecl());
-        else {
-          const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
-          assert(Tag && "Invalid sigjmp_buf type in AST file");
-          Context.setsigjmp_bufDecl(Tag->getDecl());
-        }
-      }
-    }
-
-    if (unsigned ObjCIdRedef
-          = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {
-      if (Context.ObjCIdRedefinitionType.isNull())
-        Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef);
-    }
-
-    if (unsigned ObjCClassRedef
-          = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {
-      if (Context.ObjCClassRedefinitionType.isNull())
-        Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef);
-    }
-
-    if (unsigned ObjCSelRedef
-          = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {
-      if (Context.ObjCSelRedefinitionType.isNull())
-        Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef);
-    }
-
-    if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) {
-      QualType Ucontext_tType = GetType(Ucontext_t);
-      if (Ucontext_tType.isNull()) {
-        Error("ucontext_t type is NULL");
-        return;
-      }
-
-      if (!Context.ucontext_tDecl) {
-        if (const TypedefType *Typedef = Ucontext_tType->getAs<TypedefType>())
-          Context.setucontext_tDecl(Typedef->getDecl());
-        else {
-          const TagType *Tag = Ucontext_tType->getAs<TagType>();
-          assert(Tag && "Invalid ucontext_t type in AST file");
-          Context.setucontext_tDecl(Tag->getDecl());
-        }
-      }
-    }
-  }
-  
-  ReadPragmaDiagnosticMappings(Context.getDiagnostics());
-
-  // If there were any CUDA special declarations, deserialize them.
-  if (!CUDASpecialDeclRefs.empty()) {
-    assert(CUDASpecialDeclRefs.size() == 1 && "More decl refs than expected!");
-    Context.setcudaConfigureCallDecl(
-                           cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));
-  }
-  
-  // Re-export any modules that were imported by a non-module AST file.
-  for (unsigned I = 0, N = ImportedModules.size(); I != N; ++I) {
-    if (Module *Imported = getSubmodule(ImportedModules[I]))
-      makeModuleVisible(Imported, Module::AllVisible);
-  }
-  ImportedModules.clear();
-}
-
-void ASTReader::finalizeForWriting() {
-  for (HiddenNamesMapType::iterator Hidden = HiddenNamesMap.begin(),
-                                 HiddenEnd = HiddenNamesMap.end();
-       Hidden != HiddenEnd; ++Hidden) {
-    makeNamesVisible(Hidden->second);
-  }
-  HiddenNamesMap.clear();
-}
-
-/// \brief Retrieve the name of the original source file name
-/// directly from the AST file, without actually loading the AST
-/// file.
-std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
-                                             FileManager &FileMgr,
-                                             DiagnosticsEngine &Diags) {
-  // Open the AST file.
-  std::string ErrStr;
-  OwningPtr<llvm::MemoryBuffer> Buffer;
-  Buffer.reset(FileMgr.getBufferForFile(ASTFileName, &ErrStr));
-  if (!Buffer) {
-    Diags.Report(diag::err_fe_unable_to_read_pch_file) << ASTFileName << ErrStr;
-    return std::string();
-  }
-
-  // Initialize the stream
-  llvm::BitstreamReader StreamFile;
-  llvm::BitstreamCursor Stream;
-  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
-                  (const unsigned char *)Buffer->getBufferEnd());
-  Stream.init(StreamFile);
-
-  // Sniff for the signature.
-  if (Stream.Read(8) != 'C' ||
-      Stream.Read(8) != 'P' ||
-      Stream.Read(8) != 'C' ||
-      Stream.Read(8) != 'H') {
-    Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
-    return std::string();
-  }
-
-  RecordData Record;
-  while (!Stream.AtEndOfStream()) {
-    unsigned Code = Stream.ReadCode();
-
-    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-      unsigned BlockID = Stream.ReadSubBlockID();
-
-      // We only know the AST subblock ID.
-      switch (BlockID) {
-      case CONTROL_BLOCK_ID:
-        if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
-          Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
-          return std::string();
-        }
-        break;
-
-      default:
-        if (Stream.SkipBlock()) {
-          Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
-          return std::string();
-        }
-        break;
-      }
-      continue;
-    }
-
-    if (Code == llvm::bitc::END_BLOCK) {
-      if (Stream.ReadBlockEnd()) {
-        Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
-        return std::string();
-      }
-      continue;
-    }
-
-    if (Code == llvm::bitc::DEFINE_ABBREV) {
-      Stream.ReadAbbrevRecord();
-      continue;
-    }
-
-    Record.clear();
-    const char *BlobStart = 0;
-    unsigned BlobLen = 0;
-    if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen) == ORIGINAL_FILE)
-      return std::string(BlobStart, BlobLen);
-  }
-
-  return std::string();
-}
-
-namespace {
-  class SimplePCHValidator : public ASTReaderListener {
-    const LangOptions &ExistingLangOpts;
-    const TargetOptions &ExistingTargetOpts;
-    const PreprocessorOptions &ExistingPPOpts;
-    FileManager &FileMgr;
-    
-  public:
-    SimplePCHValidator(const LangOptions &ExistingLangOpts,
-                       const TargetOptions &ExistingTargetOpts,
-                       const PreprocessorOptions &ExistingPPOpts,
-                       FileManager &FileMgr)
-      : ExistingLangOpts(ExistingLangOpts),
-        ExistingTargetOpts(ExistingTargetOpts),
-        ExistingPPOpts(ExistingPPOpts),
-        FileMgr(FileMgr)
-    {
-    }
-
-    virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
-                                     bool Complain) {
-      return checkLanguageOptions(ExistingLangOpts, LangOpts, 0);
-    }
-    virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
-                                   bool Complain) {
-      return checkTargetOptions(ExistingTargetOpts, TargetOpts, 0);
-    }
-    virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
-                                         bool Complain,
-                                         std::string &SuggestedPredefines) {
-      return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr,
-                                      SuggestedPredefines);
-    }
-  };
-}
-
-bool ASTReader::readASTFileControlBlock(StringRef Filename,
-                                        FileManager &FileMgr,
-                                        ASTReaderListener &Listener) {
-  // Open the AST file.
-  std::string ErrStr;
-  OwningPtr<llvm::MemoryBuffer> Buffer;
-  Buffer.reset(FileMgr.getBufferForFile(Filename, &ErrStr));
-  if (!Buffer) {
-    return true;
-  }
-
-  // Initialize the stream
-  llvm::BitstreamReader StreamFile;
-  llvm::BitstreamCursor Stream;
-  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
-                  (const unsigned char *)Buffer->getBufferEnd());
-  Stream.init(StreamFile);
-
-  // Sniff for the signature.
-  if (Stream.Read(8) != 'C' ||
-      Stream.Read(8) != 'P' ||
-      Stream.Read(8) != 'C' ||
-      Stream.Read(8) != 'H') {
-    return true;
-  }
-
-  RecordData Record;
-  bool InControlBlock = false;
-  while (!Stream.AtEndOfStream()) {
-    unsigned Code = Stream.ReadCode();
-
-    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-      unsigned BlockID = Stream.ReadSubBlockID();
-
-      // We only know the control subblock ID.
-      switch (BlockID) {
-      case CONTROL_BLOCK_ID:
-        if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
-          return true;
-        } else {
-          InControlBlock = true;
-        }
-        break;
-
-      default:
-        if (Stream.SkipBlock())
-          return true;
-        break;
-      }
-      continue;
-    }
-
-    if (Code == llvm::bitc::END_BLOCK) {
-      if (Stream.ReadBlockEnd()) {
-        return true;
-      }
-
-      InControlBlock = false;
-      continue;
-    }
-
-    if (Code == llvm::bitc::DEFINE_ABBREV) {
-      Stream.ReadAbbrevRecord();
-      continue;
-    }
-
-    Record.clear();
-    const char *BlobStart = 0;
-    unsigned BlobLen = 0;
-    unsigned RecCode = Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen);
-    if (InControlBlock) {
-      switch ((ControlRecordTypes)RecCode) {
-      case METADATA: {
-        if (Record[0] != VERSION_MAJOR) {
-          return true;
-        }
-
-        const std::string &CurBranch = getClangFullRepositoryVersion();
-        StringRef ASTBranch(BlobStart, BlobLen);
-        if (StringRef(CurBranch) != ASTBranch)
-          return true;
-
-        break;
-      }
-      case LANGUAGE_OPTIONS:
-        if (ParseLanguageOptions(Record, false, Listener))
-          return true;
-        break;
-
-      case TARGET_OPTIONS:
-        if (ParseTargetOptions(Record, false, Listener))
-          return true;
-        break;
-
-      case DIAGNOSTIC_OPTIONS:
-        if (ParseDiagnosticOptions(Record, false, Listener))
-          return true;
-        break;
-
-      case FILE_SYSTEM_OPTIONS:
-        if (ParseFileSystemOptions(Record, false, Listener))
-          return true;
-        break;
-
-      case HEADER_SEARCH_OPTIONS:
-        if (ParseHeaderSearchOptions(Record, false, Listener))
-          return true;
-        break;
-
-      case PREPROCESSOR_OPTIONS: {
-        std::string IgnoredSuggestedPredefines;
-        if (ParsePreprocessorOptions(Record, false, Listener,
-                                     IgnoredSuggestedPredefines))
-          return true;
-        break;
-      }
-
-      default:
-        // No other validation to perform.
-        break;
-      }
-    }
-  }
-  
-  return false;
-}
-
-
-bool ASTReader::isAcceptableASTFile(StringRef Filename,
-                                    FileManager &FileMgr,
-                                    const LangOptions &LangOpts,
-                                    const TargetOptions &TargetOpts,
-                                    const PreprocessorOptions &PPOpts) {
-  SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, FileMgr);
-  return !readASTFileControlBlock(Filename, FileMgr, validator);
-}
-
-bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
-  // Enter the submodule block.
-  if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
-    Error("malformed submodule block record in AST file");
-    return true;
-  }
-
-  ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
-  bool First = true;
-  Module *CurrentModule = 0;
-  RecordData Record;
-  while (true) {
-    unsigned Code = F.Stream.ReadCode();
-    if (Code == llvm::bitc::END_BLOCK) {
-      if (F.Stream.ReadBlockEnd()) {
-        Error("error at end of submodule block in AST file");
-        return true;
-      }
-      return false;
-    }
-    
-    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-      // No known subblocks, always skip them.
-      F.Stream.ReadSubBlockID();
-      if (F.Stream.SkipBlock()) {
-        Error("malformed block record in AST file");
-        return true;
-      }
-      continue;
-    }
-    
-    if (Code == llvm::bitc::DEFINE_ABBREV) {
-      F.Stream.ReadAbbrevRecord();
-      continue;
-    }
-    
-    // Read a record.
-    const char *BlobStart;
-    unsigned BlobLen;
-    Record.clear();
-    switch (F.Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
-    default:  // Default behavior: ignore.
-      break;
-      
-    case SUBMODULE_DEFINITION: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-
-      if (Record.size() < 7) {
-        Error("malformed module definition");
-        return true;
-      }
-      
-      StringRef Name(BlobStart, BlobLen);
-      SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[0]);
-      SubmoduleID Parent = getGlobalSubmoduleID(F, Record[1]);
-      bool IsFramework = Record[2];
-      bool IsExplicit = Record[3];
-      bool IsSystem = Record[4];
-      bool InferSubmodules = Record[5];
-      bool InferExplicitSubmodules = Record[6];
-      bool InferExportWildcard = Record[7];
-      
-      Module *ParentModule = 0;
-      if (Parent)
-        ParentModule = getSubmodule(Parent);
-      
-      // Retrieve this (sub)module from the module map, creating it if
-      // necessary.
-      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, 
-                                                IsFramework, 
-                                                IsExplicit).first;
-      SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
-      if (GlobalIndex >= SubmodulesLoaded.size() ||
-          SubmodulesLoaded[GlobalIndex]) {
-        Error("too many submodules");
-        return true;
-      }
-      
-      CurrentModule->setASTFile(F.File);
-      CurrentModule->IsFromModuleFile = true;
-      CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
-      CurrentModule->InferSubmodules = InferSubmodules;
-      CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
-      CurrentModule->InferExportWildcard = InferExportWildcard;
-      if (DeserializationListener)
-        DeserializationListener->ModuleRead(GlobalID, CurrentModule);
-      
-      SubmodulesLoaded[GlobalIndex] = CurrentModule;
-      break;
-    }
-        
-    case SUBMODULE_UMBRELLA_HEADER: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-
-      if (!CurrentModule)
-        break;
-      
-      StringRef FileName(BlobStart, BlobLen);
-      if (const FileEntry *Umbrella = PP.getFileManager().getFile(FileName)) {
-        if (!CurrentModule->getUmbrellaHeader())
-          ModMap.setUmbrellaHeader(CurrentModule, Umbrella);
-        else if (CurrentModule->getUmbrellaHeader() != Umbrella) {
-          Error("mismatched umbrella headers in submodule");
-          return true;
-        }
-      }
-      break;
-    }
-        
-    case SUBMODULE_HEADER: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-
-      if (!CurrentModule)
-        break;
-      
-      // FIXME: Be more lazy about this!
-      StringRef FileName(BlobStart, BlobLen);
-      if (const FileEntry *File = PP.getFileManager().getFile(FileName)) {
-        if (std::find(CurrentModule->Headers.begin(), 
-                      CurrentModule->Headers.end(), 
-                      File) == CurrentModule->Headers.end())
-          ModMap.addHeader(CurrentModule, File, false);
-      }
-      break;      
-    }
-
-    case SUBMODULE_EXCLUDED_HEADER: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-
-      if (!CurrentModule)
-        break;
-      
-      // FIXME: Be more lazy about this!
-      StringRef FileName(BlobStart, BlobLen);
-      if (const FileEntry *File = PP.getFileManager().getFile(FileName)) {
-        if (std::find(CurrentModule->Headers.begin(), 
-                      CurrentModule->Headers.end(), 
-                      File) == CurrentModule->Headers.end())
-          ModMap.addHeader(CurrentModule, File, true);
-      }
-      break;      
-    }
-
-    case SUBMODULE_TOPHEADER: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-
-      if (!CurrentModule)
-        break;
-
-      // FIXME: Be more lazy about this!
-      StringRef FileName(BlobStart, BlobLen);
-      if (const FileEntry *File = PP.getFileManager().getFile(FileName))
-        CurrentModule->TopHeaders.insert(File);
-      break;
-    }
-
-    case SUBMODULE_UMBRELLA_DIR: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-      
-      if (!CurrentModule)
-        break;
-      
-      StringRef DirName(BlobStart, BlobLen);
-      if (const DirectoryEntry *Umbrella
-                                  = PP.getFileManager().getDirectory(DirName)) {
-        if (!CurrentModule->getUmbrellaDir())
-          ModMap.setUmbrellaDir(CurrentModule, Umbrella);
-        else if (CurrentModule->getUmbrellaDir() != Umbrella) {
-          Error("mismatched umbrella directories in submodule");
-          return true;
-        }
-      }
-      break;
-    }
-        
-    case SUBMODULE_METADATA: {
-      if (!First) {
-        Error("submodule metadata record not at beginning of block");
-        return true;
-      }
-      First = false;
-      
-      F.BaseSubmoduleID = getTotalNumSubmodules();
-      F.LocalNumSubmodules = Record[0];
-      unsigned LocalBaseSubmoduleID = Record[1];
-      if (F.LocalNumSubmodules > 0) {
-        // Introduce the global -> local mapping for submodules within this 
-        // module.
-        GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F));
-        
-        // Introduce the local -> global mapping for submodules within this 
-        // module.
-        F.SubmoduleRemap.insertOrReplace(
-          std::make_pair(LocalBaseSubmoduleID,
-                         F.BaseSubmoduleID - LocalBaseSubmoduleID));
-        
-        SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
-      }      
-      break;
-    }
-        
-    case SUBMODULE_IMPORTS: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-      
-      if (!CurrentModule)
-        break;
-      
-      for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
-        UnresolvedModuleImportExport Unresolved;
-        Unresolved.File = &F;
-        Unresolved.Mod = CurrentModule;
-        Unresolved.ID = Record[Idx];
-        Unresolved.IsImport = true;
-        Unresolved.IsWildcard = false;
-        UnresolvedModuleImportExports.push_back(Unresolved);
-      }
-      break;
-    }
-
-    case SUBMODULE_EXPORTS: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-      
-      if (!CurrentModule)
-        break;
-      
-      for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
-        UnresolvedModuleImportExport Unresolved;
-        Unresolved.File = &F;
-        Unresolved.Mod = CurrentModule;
-        Unresolved.ID = Record[Idx];
-        Unresolved.IsImport = false;
-        Unresolved.IsWildcard = Record[Idx + 1];
-        UnresolvedModuleImportExports.push_back(Unresolved);
-      }
-      
-      // Once we've loaded the set of exports, there's no reason to keep 
-      // the parsed, unresolved exports around.
-      CurrentModule->UnresolvedExports.clear();
-      break;
-    }
-    case SUBMODULE_REQUIRES: {
-      if (First) {
-        Error("missing submodule metadata record at beginning of block");
-        return true;
-      }
-
-      if (!CurrentModule)
-        break;
-
-      CurrentModule->addRequirement(StringRef(BlobStart, BlobLen), 
-                                    Context.getLangOpts(),
-                                    Context.getTargetInfo());
-      break;
-    }
-    }
-  }
-}
-
-/// \brief Parse the record that corresponds to a LangOptions data
-/// structure.
-///
-/// This routine parses the language options from the AST file and then gives
-/// them to the AST listener if one is set.
-///
-/// \returns true if the listener deems the file unacceptable, false otherwise.
-bool ASTReader::ParseLanguageOptions(const RecordData &Record,
-                                     bool Complain,
-                                     ASTReaderListener &Listener) {
-  LangOptions LangOpts;
-  unsigned Idx = 0;
-#define LANGOPT(Name, Bits, Default, Description) \
-  LangOpts.Name = Record[Idx++];
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
-  LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));
-#include "clang/Basic/LangOptions.def"
-
-  ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];
-  VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx);
-  LangOpts.ObjCRuntime = ObjCRuntime(runtimeKind, runtimeVersion);
-  
-  unsigned Length = Record[Idx++];
-  LangOpts.CurrentModule.assign(Record.begin() + Idx, 
-                                Record.begin() + Idx + Length);
-  return Listener.ReadLanguageOptions(LangOpts, Complain);
-}
-
-bool ASTReader::ParseTargetOptions(const RecordData &Record,
-                                   bool Complain,
-                                   ASTReaderListener &Listener) {
-  unsigned Idx = 0;
-  TargetOptions TargetOpts;
-  TargetOpts.Triple = ReadString(Record, Idx);
-  TargetOpts.CPU = ReadString(Record, Idx);
-  TargetOpts.ABI = ReadString(Record, Idx);
-  TargetOpts.CXXABI = ReadString(Record, Idx);
-  TargetOpts.LinkerVersion = ReadString(Record, Idx);
-  for (unsigned N = Record[Idx++]; N; --N) {
-    TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
-  }
-  for (unsigned N = Record[Idx++]; N; --N) {
-    TargetOpts.Features.push_back(ReadString(Record, Idx));
-  }
-
-  return Listener.ReadTargetOptions(TargetOpts, Complain);
-}
-
-bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
-                                       ASTReaderListener &Listener) {
-  DiagnosticOptions DiagOpts;
-  unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
-#include "clang/Basic/DiagnosticOptions.def"
-
-  for (unsigned N = Record[Idx++]; N; --N) {
-    DiagOpts.Warnings.push_back(ReadString(Record, Idx));
-  }
-
-  return Listener.ReadDiagnosticOptions(DiagOpts, Complain);
-}
-
-bool ASTReader::ParseFileSystemOptions(const RecordData &Record, bool Complain,
-                                       ASTReaderListener &Listener) {
-  FileSystemOptions FSOpts;
-  unsigned Idx = 0;
-  FSOpts.WorkingDir = ReadString(Record, Idx);
-  return Listener.ReadFileSystemOptions(FSOpts, Complain);
-}
-
-bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
-                                         bool Complain,
-                                         ASTReaderListener &Listener) {
-  HeaderSearchOptions HSOpts;
-  unsigned Idx = 0;
-  HSOpts.Sysroot = ReadString(Record, Idx);
-
-  // Include entries.
-  for (unsigned N = Record[Idx++]; N; --N) {
-    std::string Path = ReadString(Record, Idx);
-    frontend::IncludeDirGroup Group
-      = static_cast<frontend::IncludeDirGroup>(Record[Idx++]);
-    bool IsUserSupplied = Record[Idx++];
-    bool IsFramework = Record[Idx++];
-    bool IgnoreSysRoot = Record[Idx++];
-    bool IsInternal = Record[Idx++];
-    bool ImplicitExternC = Record[Idx++];
-    HSOpts.UserEntries.push_back(
-      HeaderSearchOptions::Entry(Path, Group, IsUserSupplied, IsFramework,
-                                 IgnoreSysRoot, IsInternal, ImplicitExternC));
-  }
-
-  // System header prefixes.
-  for (unsigned N = Record[Idx++]; N; --N) {
-    std::string Prefix = ReadString(Record, Idx);
-    bool IsSystemHeader = Record[Idx++];
-    HSOpts.SystemHeaderPrefixes.push_back(
-      HeaderSearchOptions::SystemHeaderPrefix(Prefix, IsSystemHeader));
-  }
-
-  HSOpts.ResourceDir = ReadString(Record, Idx);
-  HSOpts.ModuleCachePath = ReadString(Record, Idx);
-  HSOpts.DisableModuleHash = Record[Idx++];
-  HSOpts.UseBuiltinIncludes = Record[Idx++];
-  HSOpts.UseStandardSystemIncludes = Record[Idx++];
-  HSOpts.UseStandardCXXIncludes = Record[Idx++];
-  HSOpts.UseLibcxx = Record[Idx++];
-
-  return Listener.ReadHeaderSearchOptions(HSOpts, Complain);
-}
-
-bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
-                                         bool Complain,
-                                         ASTReaderListener &Listener,
-                                         std::string &SuggestedPredefines) {
-  PreprocessorOptions PPOpts;
-  unsigned Idx = 0;
-
-  // Macro definitions/undefs
-  for (unsigned N = Record[Idx++]; N; --N) {
-    std::string Macro = ReadString(Record, Idx);
-    bool IsUndef = Record[Idx++];
-    PPOpts.Macros.push_back(std::make_pair(Macro, IsUndef));
-  }
-
-  // Includes
-  for (unsigned N = Record[Idx++]; N; --N) {
-    PPOpts.Includes.push_back(ReadString(Record, Idx));
-  }
-
-  // Macro Includes
-  for (unsigned N = Record[Idx++]; N; --N) {
-    PPOpts.MacroIncludes.push_back(ReadString(Record, Idx));
-  }
-
-  PPOpts.UsePredefines = Record[Idx++];
-  PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);
-  PPOpts.ImplicitPTHInclude = ReadString(Record, Idx);
-  PPOpts.ObjCXXARCStandardLibrary =
-    static_cast<ObjCXXARCStandardLibraryKind>(Record[Idx++]);
-  SuggestedPredefines.clear();
-  return Listener.ReadPreprocessorOptions(PPOpts, Complain,
-                                          SuggestedPredefines);
-}
-
-std::pair<ModuleFile *, unsigned>
-ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {
-  GlobalPreprocessedEntityMapType::iterator
-  I = GlobalPreprocessedEntityMap.find(GlobalIndex);
-  assert(I != GlobalPreprocessedEntityMap.end() && 
-         "Corrupted global preprocessed entity map");
-  ModuleFile *M = I->second;
-  unsigned LocalIndex = GlobalIndex - M->BasePreprocessedEntityID;
-  return std::make_pair(M, LocalIndex);
-}
-
-std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
-ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {
-  if (PreprocessingRecord *PPRec = PP.getPreprocessingRecord())
-    return PPRec->getIteratorsForLoadedRange(Mod.BasePreprocessedEntityID,
-                                             Mod.NumPreprocessedEntities);
-
-  return std::make_pair(PreprocessingRecord::iterator(),
-                        PreprocessingRecord::iterator());
-}
-
-std::pair<ASTReader::ModuleDeclIterator, ASTReader::ModuleDeclIterator>
-ASTReader::getModuleFileLevelDecls(ModuleFile &Mod) {
-  return std::make_pair(ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls),
-                        ModuleDeclIterator(this, &Mod,
-                                 Mod.FileSortedDecls + Mod.NumFileSortedDecls));
-}
-
-PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
-  PreprocessedEntityID PPID = Index+1;
-  std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
-  ModuleFile &M = *PPInfo.first;
-  unsigned LocalIndex = PPInfo.second;
-  const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
-
-  SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);  
-  M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);
-
-  unsigned Code = M.PreprocessorDetailCursor.ReadCode();
-  switch (Code) {
-  case llvm::bitc::END_BLOCK:
-    return 0;
-    
-  case llvm::bitc::ENTER_SUBBLOCK:
-    Error("unexpected subblock record in preprocessor detail block");
-    return 0;
-      
-  case llvm::bitc::DEFINE_ABBREV:
-    Error("unexpected abbrevation record in preprocessor detail block");
-    return 0;
-      
-  default:
-    break;
-  }
-
-  if (!PP.getPreprocessingRecord()) {
-    Error("no preprocessing record");
-    return 0;
-  }
-  
-  // Read the record.
-  SourceRange Range(ReadSourceLocation(M, PPOffs.Begin),
-                    ReadSourceLocation(M, PPOffs.End));
-  PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
-  const char *BlobStart = 0;
-  unsigned BlobLen = 0;
-  RecordData Record;
-  PreprocessorDetailRecordTypes RecType =
-    (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.ReadRecord(
-                                             Code, Record, BlobStart, BlobLen);
-  switch (RecType) {
-  case PPD_MACRO_EXPANSION: {
-    bool isBuiltin = Record[0];
-    IdentifierInfo *Name = 0;
-    MacroDefinition *Def = 0;
-    if (isBuiltin)
-      Name = getLocalIdentifier(M, Record[1]);
-    else {
-      PreprocessedEntityID
-          GlobalID = getGlobalPreprocessedEntityID(M, Record[1]);
-      Def =cast<MacroDefinition>(PPRec.getLoadedPreprocessedEntity(GlobalID-1));
-    }
-
-    MacroExpansion *ME;
-    if (isBuiltin)
-      ME = new (PPRec) MacroExpansion(Name, Range);
-    else
-      ME = new (PPRec) MacroExpansion(Def, Range);
-
-    return ME;
-  }
-      
-  case PPD_MACRO_DEFINITION: {
-    // Decode the identifier info and then check again; if the macro is
-    // still defined and associated with the identifier,
-    IdentifierInfo *II = getLocalIdentifier(M, Record[0]);
-    MacroDefinition *MD
-      = new (PPRec) MacroDefinition(II, Range);
-
-    if (DeserializationListener)
-      DeserializationListener->MacroDefinitionRead(PPID, MD);
-
-    return MD;
-  }
-      
-  case PPD_INCLUSION_DIRECTIVE: {
-    const char *FullFileNameStart = BlobStart + Record[0];
-    StringRef FullFileName(FullFileNameStart, BlobLen - Record[0]);
-    const FileEntry *File = 0;
-    if (!FullFileName.empty())
-      File = PP.getFileManager().getFile(FullFileName);
-    
-    // FIXME: Stable encoding
-    InclusionDirective::InclusionKind Kind
-      = static_cast<InclusionDirective::InclusionKind>(Record[2]);
-    InclusionDirective *ID
-      = new (PPRec) InclusionDirective(PPRec, Kind,
-                                       StringRef(BlobStart, Record[0]),
-                                       Record[1], Record[3],
-                                       File,
-                                       Range);
-    return ID;
-  }
-  }
-
-  llvm_unreachable("Invalid PreprocessorDetailRecordTypes");
-}
-
-/// \brief \arg SLocMapI points at a chunk of a module that contains no
-/// preprocessed entities or the entities it contains are not the ones we are
-/// looking for. Find the next module that contains entities and return the ID
-/// of the first entry.
-PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
-                       GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
-  ++SLocMapI;
-  for (GlobalSLocOffsetMapType::const_iterator
-         EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {
-    ModuleFile &M = *SLocMapI->second;
-    if (M.NumPreprocessedEntities)
-      return M.BasePreprocessedEntityID;
-  }
-
-  return getTotalNumPreprocessedEntities();
-}
-
-namespace {
-
-template <unsigned PPEntityOffset::*PPLoc>
-struct PPEntityComp {
-  const ASTReader &Reader;
-  ModuleFile &M;
-
-  PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) { }
-
-  bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const {
-    SourceLocation LHS = getLoc(L);
-    SourceLocation RHS = getLoc(R);
-    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
-  }
-
-  bool operator()(const PPEntityOffset &L, SourceLocation RHS) const {
-    SourceLocation LHS = getLoc(L);
-    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
-  }
-
-  bool operator()(SourceLocation LHS, const PPEntityOffset &R) const {
-    SourceLocation RHS = getLoc(R);
-    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
-  }
-
-  SourceLocation getLoc(const PPEntityOffset &PPE) const {
-    return Reader.ReadSourceLocation(M, PPE.*PPLoc);
-  }
-};
-
-}
-
-/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.
-PreprocessedEntityID
-ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
-  if (SourceMgr.isLocalSourceLocation(BLoc))
-    return getTotalNumPreprocessedEntities();
-
-  GlobalSLocOffsetMapType::const_iterator
-    SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
-                                        BLoc.getOffset());
-  assert(SLocMapI != GlobalSLocOffsetMap.end() &&
-         "Corrupted global sloc offset map");
-
-  if (SLocMapI->second->NumPreprocessedEntities == 0)
-    return findNextPreprocessedEntity(SLocMapI);
-
-  ModuleFile &M = *SLocMapI->second;
-  typedef const PPEntityOffset *pp_iterator;
-  pp_iterator pp_begin = M.PreprocessedEntityOffsets;
-  pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
-
-  size_t Count = M.NumPreprocessedEntities;
-  size_t Half;
-  pp_iterator First = pp_begin;
-  pp_iterator PPI;
-
-  // Do a binary search manually instead of using std::lower_bound because
-  // The end locations of entities may be unordered (when a macro expansion
-  // is inside another macro argument), but for this case it is not important
-  // whether we get the first macro expansion or its containing macro.
-  while (Count > 0) {
-    Half = Count/2;
-    PPI = First;
-    std::advance(PPI, Half);
-    if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
-                                            BLoc)){
-      First = PPI;
-      ++First;
-      Count = Count - Half - 1;
-    } else
-      Count = Half;
-  }
-
-  if (PPI == pp_end)
-    return findNextPreprocessedEntity(SLocMapI);
-
-  return M.BasePreprocessedEntityID + (PPI - pp_begin);
-}
-
-/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.
-PreprocessedEntityID
-ASTReader::findEndPreprocessedEntity(SourceLocation ELoc) const {
-  if (SourceMgr.isLocalSourceLocation(ELoc))
-    return getTotalNumPreprocessedEntities();
-
-  GlobalSLocOffsetMapType::const_iterator
-    SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
-                                        ELoc.getOffset());
-  assert(SLocMapI != GlobalSLocOffsetMap.end() &&
-         "Corrupted global sloc offset map");
-
-  if (SLocMapI->second->NumPreprocessedEntities == 0)
-    return findNextPreprocessedEntity(SLocMapI);
-
-  ModuleFile &M = *SLocMapI->second;
-  typedef const PPEntityOffset *pp_iterator;
-  pp_iterator pp_begin = M.PreprocessedEntityOffsets;
-  pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
-  pp_iterator PPI =
-      std::upper_bound(pp_begin, pp_end, ELoc,
-                       PPEntityComp<&PPEntityOffset::Begin>(*this, M));
-
-  if (PPI == pp_end)
-    return findNextPreprocessedEntity(SLocMapI);
-
-  return M.BasePreprocessedEntityID + (PPI - pp_begin);
-}
-
-/// \brief Returns a pair of [Begin, End) indices of preallocated
-/// preprocessed entities that \arg Range encompasses.
-std::pair<unsigned, unsigned>
-    ASTReader::findPreprocessedEntitiesInRange(SourceRange Range) {
-  if (Range.isInvalid())
-    return std::make_pair(0,0);
-  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
-
-  PreprocessedEntityID BeginID = findBeginPreprocessedEntity(Range.getBegin());
-  PreprocessedEntityID EndID = findEndPreprocessedEntity(Range.getEnd());
-  return std::make_pair(BeginID, EndID);
-}
-
-/// \brief Optionally returns true or false if the preallocated preprocessed
-/// entity with index \arg Index came from file \arg FID.
-llvm::Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,
-                                                             FileID FID) {
-  if (FID.isInvalid())
-    return false;
-
-  std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
-  ModuleFile &M = *PPInfo.first;
-  unsigned LocalIndex = PPInfo.second;
-  const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
-  
-  SourceLocation Loc = ReadSourceLocation(M, PPOffs.Begin);
-  if (Loc.isInvalid())
-    return false;
-  
-  if (SourceMgr.isInFileID(SourceMgr.getFileLoc(Loc), FID))
-    return true;
-  else
-    return false;
-}
-
-namespace {
-  /// \brief Visitor used to search for information about a header file.
-  class HeaderFileInfoVisitor {
-    ASTReader &Reader;
-    const FileEntry *FE;
-    
-    llvm::Optional<HeaderFileInfo> HFI;
-    
-  public:
-    HeaderFileInfoVisitor(ASTReader &Reader, const FileEntry *FE)
-      : Reader(Reader), FE(FE) { }
-    
-    static bool visit(ModuleFile &M, void *UserData) {
-      HeaderFileInfoVisitor *This
-        = static_cast<HeaderFileInfoVisitor *>(UserData);
-      
-      HeaderFileInfoTrait Trait(This->Reader, M, 
-                                &This->Reader.getPreprocessor().getHeaderSearchInfo(),
-                                M.HeaderFileFrameworkStrings,
-                                This->FE->getName());
-      
-      HeaderFileInfoLookupTable *Table
-        = static_cast<HeaderFileInfoLookupTable *>(M.HeaderFileInfoTable);
-      if (!Table)
-        return false;
-
-      // Look in the on-disk hash table for an entry for this file name.
-      HeaderFileInfoLookupTable::iterator Pos = Table->find(This->FE->getName(),
-                                                            &Trait);
-      if (Pos == Table->end())
-        return false;
-
-      This->HFI = *Pos;
-      return true;
-    }
-    
-    llvm::Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
-  };
-}
-
-HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
-  HeaderFileInfoVisitor Visitor(*this, FE);
-  ModuleMgr.visit(&HeaderFileInfoVisitor::visit, &Visitor);
-  if (llvm::Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) {
-    if (Listener)
-      Listener->ReadHeaderFileInfo(*HFI, FE->getUID());
-    return *HFI;
-  }
-  
-  return HeaderFileInfo();
-}
-
-void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
-  // FIXME: Make it work properly with modules.
-  llvm::SmallVector<DiagnosticsEngine::DiagState *, 32> DiagStates;
-  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
-    ModuleFile &F = *(*I);
-    unsigned Idx = 0;
-    DiagStates.clear();
-    assert(!Diag.DiagStates.empty());
-    DiagStates.push_back(&Diag.DiagStates.front()); // the command-line one.
-    while (Idx < F.PragmaDiagMappings.size()) {
-      SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
-      unsigned DiagStateID = F.PragmaDiagMappings[Idx++];
-      if (DiagStateID != 0) {
-        Diag.DiagStatePoints.push_back(
-                    DiagnosticsEngine::DiagStatePoint(DiagStates[DiagStateID-1],
-                    FullSourceLoc(Loc, SourceMgr)));
-        continue;
-      }
-      
-      assert(DiagStateID == 0);
-      // A new DiagState was created here.
-      Diag.DiagStates.push_back(*Diag.GetCurDiagState());
-      DiagnosticsEngine::DiagState *NewState = &Diag.DiagStates.back();
-      DiagStates.push_back(NewState);
-      Diag.DiagStatePoints.push_back(
-          DiagnosticsEngine::DiagStatePoint(NewState,
-                                            FullSourceLoc(Loc, SourceMgr)));
-      while (1) {
-        assert(Idx < F.PragmaDiagMappings.size() &&
-               "Invalid data, didn't find '-1' marking end of diag/map pairs");
-        if (Idx >= F.PragmaDiagMappings.size()) {
-          break; // Something is messed up but at least avoid infinite loop in
-                 // release build.
-        }
-        unsigned DiagID = F.PragmaDiagMappings[Idx++];
-        if (DiagID == (unsigned)-1) {
-          break; // no more diag/map pairs for this location.
-        }
-        diag::Mapping Map = (diag::Mapping)F.PragmaDiagMappings[Idx++];
-        DiagnosticMappingInfo MappingInfo = Diag.makeMappingInfo(Map, Loc);
-        Diag.GetCurDiagState()->setMappingInfo(DiagID, MappingInfo);
-      }
-    }
-  }
-}
-
-/// \brief Get the correct cursor and offset for loading a type.
-ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
-  GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index);
-  assert(I != GlobalTypeMap.end() && "Corrupted global type map");
-  ModuleFile *M = I->second;
-  return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]);
-}
-
-/// \brief Read and return the type with the given index..
-///
-/// The index is the type ID, shifted and minus the number of predefs. This
-/// routine actually reads the record corresponding to the type at the given
-/// location. It is a helper routine for GetType, which deals with reading type
-/// IDs.
-QualType ASTReader::readTypeRecord(unsigned Index) {
-  RecordLocation Loc = TypeCursorForIndex(Index);
-  llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
-
-  // Keep track of where we are in the stream, then jump back there
-  // after reading this type.
-  SavedStreamPosition SavedPosition(DeclsCursor);
-
-  ReadingKindTracker ReadingKind(Read_Type, *this);
-
-  // Note that we are loading a type record.
-  Deserializing AType(this);
-
-  unsigned Idx = 0;
-  DeclsCursor.JumpToBit(Loc.Offset);
-  RecordData Record;
-  unsigned Code = DeclsCursor.ReadCode();
-  switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
-  case TYPE_EXT_QUAL: {
-    if (Record.size() != 2) {
-      Error("Incorrect encoding of extended qualifier type");
-      return QualType();
-    }
-    QualType Base = readType(*Loc.F, Record, Idx);
-    Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[Idx++]);
-    return Context.getQualifiedType(Base, Quals);
-  }
-
-  case TYPE_COMPLEX: {
-    if (Record.size() != 1) {
-      Error("Incorrect encoding of complex type");
-      return QualType();
-    }
-    QualType ElemType = readType(*Loc.F, Record, Idx);
-    return Context.getComplexType(ElemType);
-  }
-
-  case TYPE_POINTER: {
-    if (Record.size() != 1) {
-      Error("Incorrect encoding of pointer type");
-      return QualType();
-    }
-    QualType PointeeType = readType(*Loc.F, Record, Idx);
-    return Context.getPointerType(PointeeType);
-  }
-
-  case TYPE_BLOCK_POINTER: {
-    if (Record.size() != 1) {
-      Error("Incorrect encoding of block pointer type");
-      return QualType();
-    }
-    QualType PointeeType = readType(*Loc.F, Record, Idx);
-    return Context.getBlockPointerType(PointeeType);
-  }
-
-  case TYPE_LVALUE_REFERENCE: {
-    if (Record.size() != 2) {
-      Error("Incorrect encoding of lvalue reference type");
-      return QualType();
-    }
-    QualType PointeeType = readType(*Loc.F, Record, Idx);
-    return Context.getLValueReferenceType(PointeeType, Record[1]);
-  }
-
-  case TYPE_RVALUE_REFERENCE: {
-    if (Record.size() != 1) {
-      Error("Incorrect encoding of rvalue reference type");
-      return QualType();
-    }
-    QualType PointeeType = readType(*Loc.F, Record, Idx);
-    return Context.getRValueReferenceType(PointeeType);
-  }
-
-  case TYPE_MEMBER_POINTER: {
-    if (Record.size() != 2) {
-      Error("Incorrect encoding of member pointer type");
-      return QualType();
-    }
-    QualType PointeeType = readType(*Loc.F, Record, Idx);
-    QualType ClassType = readType(*Loc.F, Record, Idx);
-    if (PointeeType.isNull() || ClassType.isNull())
-      return QualType();
-    
-    return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
-  }
-
-  case TYPE_CONSTANT_ARRAY: {
-    QualType ElementType = readType(*Loc.F, Record, Idx);
-    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
-    unsigned IndexTypeQuals = Record[2];
-    unsigned Idx = 3;
-    llvm::APInt Size = ReadAPInt(Record, Idx);
-    return Context.getConstantArrayType(ElementType, Size,
-                                         ASM, IndexTypeQuals);
-  }
-
-  case TYPE_INCOMPLETE_ARRAY: {
-    QualType ElementType = readType(*Loc.F, Record, Idx);
-    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
-    unsigned IndexTypeQuals = Record[2];
-    return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
-  }
-
-  case TYPE_VARIABLE_ARRAY: {
-    QualType ElementType = readType(*Loc.F, Record, Idx);
-    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
-    unsigned IndexTypeQuals = Record[2];
-    SourceLocation LBLoc = ReadSourceLocation(*Loc.F, Record[3]);
-    SourceLocation RBLoc = ReadSourceLocation(*Loc.F, Record[4]);
-    return Context.getVariableArrayType(ElementType, ReadExpr(*Loc.F),
-                                         ASM, IndexTypeQuals,
-                                         SourceRange(LBLoc, RBLoc));
-  }
-
-  case TYPE_VECTOR: {
-    if (Record.size() != 3) {
-      Error("incorrect encoding of vector type in AST file");
-      return QualType();
-    }
-
-    QualType ElementType = readType(*Loc.F, Record, Idx);
-    unsigned NumElements = Record[1];
-    unsigned VecKind = Record[2];
-    return Context.getVectorType(ElementType, NumElements,
-                                  (VectorType::VectorKind)VecKind);
-  }
-
-  case TYPE_EXT_VECTOR: {
-    if (Record.size() != 3) {
-      Error("incorrect encoding of extended vector type in AST file");
-      return QualType();
-    }
-
-    QualType ElementType = readType(*Loc.F, Record, Idx);
-    unsigned NumElements = Record[1];
-    return Context.getExtVectorType(ElementType, NumElements);
-  }
-
-  case TYPE_FUNCTION_NO_PROTO: {
-    if (Record.size() != 6) {
-      Error("incorrect encoding of no-proto function type");
-      return QualType();
-    }
-    QualType ResultType = readType(*Loc.F, Record, Idx);
-    FunctionType::ExtInfo Info(Record[1], Record[2], Record[3],
-                               (CallingConv)Record[4], Record[5]);
-    return Context.getFunctionNoProtoType(ResultType, Info);
-  }
-
-  case TYPE_FUNCTION_PROTO: {
-    QualType ResultType = readType(*Loc.F, Record, Idx);
-
-    FunctionProtoType::ExtProtoInfo EPI;
-    EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1],
-                                        /*hasregparm*/ Record[2],
-                                        /*regparm*/ Record[3],
-                                        static_cast<CallingConv>(Record[4]),
-                                        /*produces*/ Record[5]);
-
-    unsigned Idx = 6;
-    unsigned NumParams = Record[Idx++];
-    SmallVector<QualType, 16> ParamTypes;
-    for (unsigned I = 0; I != NumParams; ++I)
-      ParamTypes.push_back(readType(*Loc.F, Record, Idx));
-
-    EPI.Variadic = Record[Idx++];
-    EPI.HasTrailingReturn = Record[Idx++];
-    EPI.TypeQuals = Record[Idx++];
-    EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);
-    ExceptionSpecificationType EST =
-        static_cast<ExceptionSpecificationType>(Record[Idx++]);
-    EPI.ExceptionSpecType = EST;
-    SmallVector<QualType, 2> Exceptions;
-    if (EST == EST_Dynamic) {
-      EPI.NumExceptions = Record[Idx++];
-      for (unsigned I = 0; I != EPI.NumExceptions; ++I)
-        Exceptions.push_back(readType(*Loc.F, Record, Idx));
-      EPI.Exceptions = Exceptions.data();
-    } else if (EST == EST_ComputedNoexcept) {
-      EPI.NoexceptExpr = ReadExpr(*Loc.F);
-    } else if (EST == EST_Uninstantiated) {
-      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
-      EPI.ExceptionSpecTemplate = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
-    } else if (EST == EST_Unevaluated) {
-      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
-    }
-    return Context.getFunctionType(ResultType, ParamTypes.data(), NumParams,
-                                    EPI);
-  }
-
-  case TYPE_UNRESOLVED_USING: {
-    unsigned Idx = 0;
-    return Context.getTypeDeclType(
-                  ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx));
-  }
-      
-  case TYPE_TYPEDEF: {
-    if (Record.size() != 2) {
-      Error("incorrect encoding of typedef type");
-      return QualType();
-    }
-    unsigned Idx = 0;
-    TypedefNameDecl *Decl = ReadDeclAs<TypedefNameDecl>(*Loc.F, Record, Idx);
-    QualType Canonical = readType(*Loc.F, Record, Idx);
-    if (!Canonical.isNull())
-      Canonical = Context.getCanonicalType(Canonical);
-    return Context.getTypedefType(Decl, Canonical);
-  }
-
-  case TYPE_TYPEOF_EXPR:
-    return Context.getTypeOfExprType(ReadExpr(*Loc.F));
-
-  case TYPE_TYPEOF: {
-    if (Record.size() != 1) {
-      Error("incorrect encoding of typeof(type) in AST file");
-      return QualType();
-    }
-    QualType UnderlyingType = readType(*Loc.F, Record, Idx);
-    return Context.getTypeOfType(UnderlyingType);
-  }
-
-  case TYPE_DECLTYPE: {
-    QualType UnderlyingType = readType(*Loc.F, Record, Idx);
-    return Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType);
-  }
-
-  case TYPE_UNARY_TRANSFORM: {
-    QualType BaseType = readType(*Loc.F, Record, Idx);
-    QualType UnderlyingType = readType(*Loc.F, Record, Idx);
-    UnaryTransformType::UTTKind UKind = (UnaryTransformType::UTTKind)Record[2];
-    return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind);
-  }
-
-  case TYPE_AUTO:
-    return Context.getAutoType(readType(*Loc.F, Record, Idx));
-
-  case TYPE_RECORD: {
-    if (Record.size() != 2) {
-      Error("incorrect encoding of record type");
-      return QualType();
-    }
-    unsigned Idx = 0;
-    bool IsDependent = Record[Idx++];
-    RecordDecl *RD = ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx);
-    RD = cast_or_null<RecordDecl>(RD->getCanonicalDecl());
-    QualType T = Context.getRecordType(RD);
-    const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
-    return T;
-  }
-
-  case TYPE_ENUM: {
-    if (Record.size() != 2) {
-      Error("incorrect encoding of enum type");
-      return QualType();
-    }
-    unsigned Idx = 0;
-    bool IsDependent = Record[Idx++];
-    QualType T
-      = Context.getEnumType(ReadDeclAs<EnumDecl>(*Loc.F, Record, Idx));
-    const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
-    return T;
-  }
-
-  case TYPE_ATTRIBUTED: {
-    if (Record.size() != 3) {
-      Error("incorrect encoding of attributed type");
-      return QualType();
-    }
-    QualType modifiedType = readType(*Loc.F, Record, Idx);
-    QualType equivalentType = readType(*Loc.F, Record, Idx);
-    AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);
-    return Context.getAttributedType(kind, modifiedType, equivalentType);
-  }
-
-  case TYPE_PAREN: {
-    if (Record.size() != 1) {
-      Error("incorrect encoding of paren type");
-      return QualType();
-    }
-    QualType InnerType = readType(*Loc.F, Record, Idx);
-    return Context.getParenType(InnerType);
-  }
-
-  case TYPE_PACK_EXPANSION: {
-    if (Record.size() != 2) {
-      Error("incorrect encoding of pack expansion type");
-      return QualType();
-    }
-    QualType Pattern = readType(*Loc.F, Record, Idx);
-    if (Pattern.isNull())
-      return QualType();
-    llvm::Optional<unsigned> NumExpansions;
-    if (Record[1])
-      NumExpansions = Record[1] - 1;
-    return Context.getPackExpansionType(Pattern, NumExpansions);
-  }
-
-  case TYPE_ELABORATED: {
-    unsigned Idx = 0;
-    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
-    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
-    QualType NamedType = readType(*Loc.F, Record, Idx);
-    return Context.getElaboratedType(Keyword, NNS, NamedType);
-  }
-
-  case TYPE_OBJC_INTERFACE: {
-    unsigned Idx = 0;
-    ObjCInterfaceDecl *ItfD
-      = ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);
-    return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
-  }
-
-  case TYPE_OBJC_OBJECT: {
-    unsigned Idx = 0;
-    QualType Base = readType(*Loc.F, Record, Idx);
-    unsigned NumProtos = Record[Idx++];
-    SmallVector<ObjCProtocolDecl*, 4> Protos;
-    for (unsigned I = 0; I != NumProtos; ++I)
-      Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
-    return Context.getObjCObjectType(Base, Protos.data(), NumProtos);
-  }
-
-  case TYPE_OBJC_OBJECT_POINTER: {
-    unsigned Idx = 0;
-    QualType Pointee = readType(*Loc.F, Record, Idx);
-    return Context.getObjCObjectPointerType(Pointee);
-  }
-
-  case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
-    unsigned Idx = 0;
-    QualType Parm = readType(*Loc.F, Record, Idx);
-    QualType Replacement = readType(*Loc.F, Record, Idx);
-    return
-      Context.getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
-                                            Replacement);
-  }
-
-  case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
-    unsigned Idx = 0;
-    QualType Parm = readType(*Loc.F, Record, Idx);
-    TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx);
-    return Context.getSubstTemplateTypeParmPackType(
-                                               cast<TemplateTypeParmType>(Parm),
-                                                     ArgPack);
-  }
-
-  case TYPE_INJECTED_CLASS_NAME: {
-    CXXRecordDecl *D = ReadDeclAs<CXXRecordDecl>(*Loc.F, Record, Idx);
-    QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
-    // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
-    // for AST reading, too much interdependencies.
-    return
-      QualType(new (Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
-  }
-
-  case TYPE_TEMPLATE_TYPE_PARM: {
-    unsigned Idx = 0;
-    unsigned Depth = Record[Idx++];
-    unsigned Index = Record[Idx++];
-    bool Pack = Record[Idx++];
-    TemplateTypeParmDecl *D
-      = ReadDeclAs<TemplateTypeParmDecl>(*Loc.F, Record, Idx);
-    return Context.getTemplateTypeParmType(Depth, Index, Pack, D);
-  }
-
-  case TYPE_DEPENDENT_NAME: {
-    unsigned Idx = 0;
-    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
-    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
-    const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);
-    QualType Canon = readType(*Loc.F, Record, Idx);
-    if (!Canon.isNull())
-      Canon = Context.getCanonicalType(Canon);
-    return Context.getDependentNameType(Keyword, NNS, Name, Canon);
-  }
-
-  case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
-    unsigned Idx = 0;
-    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
-    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
-    const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);
-    unsigned NumArgs = Record[Idx++];
-    SmallVector<TemplateArgument, 8> Args;
-    Args.reserve(NumArgs);
-    while (NumArgs--)
-      Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx));
-    return Context.getDependentTemplateSpecializationType(Keyword, NNS, Name,
-                                                      Args.size(), Args.data());
-  }
-
-  case TYPE_DEPENDENT_SIZED_ARRAY: {
-    unsigned Idx = 0;
-
-    // ArrayType
-    QualType ElementType = readType(*Loc.F, Record, Idx);
-    ArrayType::ArraySizeModifier ASM
-      = (ArrayType::ArraySizeModifier)Record[Idx++];
-    unsigned IndexTypeQuals = Record[Idx++];
-
-    // DependentSizedArrayType
-    Expr *NumElts = ReadExpr(*Loc.F);
-    SourceRange Brackets = ReadSourceRange(*Loc.F, Record, Idx);
-
-    return Context.getDependentSizedArrayType(ElementType, NumElts, ASM,
-                                               IndexTypeQuals, Brackets);
-  }
-
-  case TYPE_TEMPLATE_SPECIALIZATION: {
-    unsigned Idx = 0;
-    bool IsDependent = Record[Idx++];
-    TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
-    SmallVector<TemplateArgument, 8> Args;
-    ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);
-    QualType Underlying = readType(*Loc.F, Record, Idx);
-    QualType T;
-    if (Underlying.isNull())
-      T = Context.getCanonicalTemplateSpecializationType(Name, Args.data(),
-                                                          Args.size());
-    else
-      T = Context.getTemplateSpecializationType(Name, Args.data(),
-                                                 Args.size(), Underlying);
-    const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
-    return T;
-  }
-
-  case TYPE_ATOMIC: {
-    if (Record.size() != 1) {
-      Error("Incorrect encoding of atomic type");
-      return QualType();
-    }
-    QualType ValueType = readType(*Loc.F, Record, Idx);
-    return Context.getAtomicType(ValueType);
-  }
-  }
-  llvm_unreachable("Invalid TypeCode!");
-}
-
-class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
-  ASTReader &Reader;
-  ModuleFile &F;
-  const ASTReader::RecordData &Record;
-  unsigned &Idx;
-
-  SourceLocation ReadSourceLocation(const ASTReader::RecordData &R,
-                                    unsigned &I) {
-    return Reader.ReadSourceLocation(F, R, I);
-  }
-
-  template<typename T>
-  T *ReadDeclAs(const ASTReader::RecordData &Record, unsigned &Idx) {
-    return Reader.ReadDeclAs<T>(F, Record, Idx);
-  }
-  
-public:
-  TypeLocReader(ASTReader &Reader, ModuleFile &F,
-                const ASTReader::RecordData &Record, unsigned &Idx)
-    : Reader(Reader), F(F), Record(Record), Idx(Idx)
-  { }
-
-  // We want compile-time assurance that we've enumerated all of
-  // these, so unfortunately we have to declare them first, then
-  // define them out-of-line.
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
-  void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
-#include "clang/AST/TypeLocNodes.def"
-
-  void VisitFunctionTypeLoc(FunctionTypeLoc);
-  void VisitArrayTypeLoc(ArrayTypeLoc);
-};
-
-void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
-  // nothing to do
-}
-void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
-  TL.setBuiltinLoc(ReadSourceLocation(Record, Idx));
-  if (TL.needsExtraLocalData()) {
-    TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
-    TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
-    TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
-    TL.setModeAttr(Record[Idx++]);
-  }
-}
-void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
-  TL.setStarLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
-  TL.setCaretLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
-  TL.setAmpLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
-  TL.setAmpAmpLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
-  TL.setStarLoc(ReadSourceLocation(Record, Idx));
-  TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
-}
-void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
-  TL.setLBracketLoc(ReadSourceLocation(Record, Idx));
-  TL.setRBracketLoc(ReadSourceLocation(Record, Idx));
-  if (Record[Idx++])
-    TL.setSizeExpr(Reader.ReadExpr(F));
-  else
-    TL.setSizeExpr(0);
-}
-void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
-  VisitArrayTypeLoc(TL);
-}
-void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
-  VisitArrayTypeLoc(TL);
-}
-void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
-  VisitArrayTypeLoc(TL);
-}
-void TypeLocReader::VisitDependentSizedArrayTypeLoc(
-                                            DependentSizedArrayTypeLoc TL) {
-  VisitArrayTypeLoc(TL);
-}
-void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
-                                        DependentSizedExtVectorTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
-  TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx));
-  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
-    TL.setArg(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
-  }
-}
-void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
-  VisitFunctionTypeLoc(TL);
-}
-void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
-  VisitFunctionTypeLoc(TL);
-}
-void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
-  TL.setTypeofLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
-  TL.setTypeofLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
-}
-void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
-  TL.setKWLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
-}
-void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
-  TL.setAttrNameLoc(ReadSourceLocation(Record, Idx));
-  if (TL.hasAttrOperand()) {
-    SourceRange range;
-    range.setBegin(ReadSourceLocation(Record, Idx));
-    range.setEnd(ReadSourceLocation(Record, Idx));
-    TL.setAttrOperandParensRange(range);
-  }
-  if (TL.hasAttrExprOperand()) {
-    if (Record[Idx++])
-      TL.setAttrExprOperand(Reader.ReadExpr(F));
-    else
-      TL.setAttrExprOperand(0);
-  } else if (TL.hasAttrEnumOperand())
-    TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
-                                            SubstTemplateTypeParmTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
-                                          SubstTemplateTypeParmPackTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitTemplateSpecializationTypeLoc(
-                                           TemplateSpecializationTypeLoc TL) {
-  TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
-  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
-  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
-    TL.setArgLocInfo(i,
-        Reader.GetTemplateArgumentLocInfo(F,
-                                          TL.getTypePtr()->getArg(i).getKind(),
-                                          Record, Idx));
-}
-void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
-  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
-}
-void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
-  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
-       DependentTemplateSpecializationTypeLoc TL) {
-  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
-  TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
-  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
-  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
-    TL.setArgLocInfo(I,
-        Reader.GetTemplateArgumentLocInfo(F,
-                                          TL.getTypePtr()->getArg(I).getKind(),
-                                          Record, Idx));
-}
-void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
-  TL.setEllipsisLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
-  TL.setHasBaseTypeAsWritten(Record[Idx++]);
-  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
-  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
-    TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
-  TL.setStarLoc(ReadSourceLocation(Record, Idx));
-}
-void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
-  TL.setKWLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-}
-
-TypeSourceInfo *ASTReader::GetTypeSourceInfo(ModuleFile &F,
-                                             const RecordData &Record,
-                                             unsigned &Idx) {
-  QualType InfoTy = readType(F, Record, Idx);
-  if (InfoTy.isNull())
-    return 0;
-
-  TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
-  TypeLocReader TLR(*this, F, Record, Idx);
-  for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
-    TLR.Visit(TL);
-  return TInfo;
-}
-
-QualType ASTReader::GetType(TypeID ID) {
-  unsigned FastQuals = ID & Qualifiers::FastMask;
-  unsigned Index = ID >> Qualifiers::FastWidth;
-
-  if (Index < NUM_PREDEF_TYPE_IDS) {
-    QualType T;
-    switch ((PredefinedTypeIDs)Index) {
-    case PREDEF_TYPE_NULL_ID: return QualType();
-    case PREDEF_TYPE_VOID_ID: T = Context.VoidTy; break;
-    case PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break;
-
-    case PREDEF_TYPE_CHAR_U_ID:
-    case PREDEF_TYPE_CHAR_S_ID:
-      // FIXME: Check that the signedness of CharTy is correct!
-      T = Context.CharTy;
-      break;
-
-    case PREDEF_TYPE_UCHAR_ID:      T = Context.UnsignedCharTy;     break;
-    case PREDEF_TYPE_USHORT_ID:     T = Context.UnsignedShortTy;    break;
-    case PREDEF_TYPE_UINT_ID:       T = Context.UnsignedIntTy;      break;
-    case PREDEF_TYPE_ULONG_ID:      T = Context.UnsignedLongTy;     break;
-    case PREDEF_TYPE_ULONGLONG_ID:  T = Context.UnsignedLongLongTy; break;
-    case PREDEF_TYPE_UINT128_ID:    T = Context.UnsignedInt128Ty;   break;
-    case PREDEF_TYPE_SCHAR_ID:      T = Context.SignedCharTy;       break;
-    case PREDEF_TYPE_WCHAR_ID:      T = Context.WCharTy;            break;
-    case PREDEF_TYPE_SHORT_ID:      T = Context.ShortTy;            break;
-    case PREDEF_TYPE_INT_ID:        T = Context.IntTy;              break;
-    case PREDEF_TYPE_LONG_ID:       T = Context.LongTy;             break;
-    case PREDEF_TYPE_LONGLONG_ID:   T = Context.LongLongTy;         break;
-    case PREDEF_TYPE_INT128_ID:     T = Context.Int128Ty;           break;
-    case PREDEF_TYPE_HALF_ID:       T = Context.HalfTy;             break;
-    case PREDEF_TYPE_FLOAT_ID:      T = Context.FloatTy;            break;
-    case PREDEF_TYPE_DOUBLE_ID:     T = Context.DoubleTy;           break;
-    case PREDEF_TYPE_LONGDOUBLE_ID: T = Context.LongDoubleTy;       break;
-    case PREDEF_TYPE_OVERLOAD_ID:   T = Context.OverloadTy;         break;
-    case PREDEF_TYPE_BOUND_MEMBER:  T = Context.BoundMemberTy;      break;
-    case PREDEF_TYPE_PSEUDO_OBJECT: T = Context.PseudoObjectTy;     break;
-    case PREDEF_TYPE_DEPENDENT_ID:  T = Context.DependentTy;        break;
-    case PREDEF_TYPE_UNKNOWN_ANY:   T = Context.UnknownAnyTy;       break;
-    case PREDEF_TYPE_NULLPTR_ID:    T = Context.NullPtrTy;          break;
-    case PREDEF_TYPE_CHAR16_ID:     T = Context.Char16Ty;           break;
-    case PREDEF_TYPE_CHAR32_ID:     T = Context.Char32Ty;           break;
-    case PREDEF_TYPE_OBJC_ID:       T = Context.ObjCBuiltinIdTy;    break;
-    case PREDEF_TYPE_OBJC_CLASS:    T = Context.ObjCBuiltinClassTy; break;
-    case PREDEF_TYPE_OBJC_SEL:      T = Context.ObjCBuiltinSelTy;   break;
-    case PREDEF_TYPE_AUTO_DEDUCT:   T = Context.getAutoDeductType(); break;
-        
-    case PREDEF_TYPE_AUTO_RREF_DEDUCT: 
-      T = Context.getAutoRRefDeductType(); 
-      break;
-
-    case PREDEF_TYPE_ARC_UNBRIDGED_CAST:
-      T = Context.ARCUnbridgedCastTy;
-      break;
-
-    case PREDEF_TYPE_VA_LIST_TAG:
-      T = Context.getVaListTagType();
-      break;
-
-    case PREDEF_TYPE_BUILTIN_FN:
-      T = Context.BuiltinFnTy;
-      break;
-    }
-
-    assert(!T.isNull() && "Unknown predefined type");
-    return T.withFastQualifiers(FastQuals);
-  }
-
-  Index -= NUM_PREDEF_TYPE_IDS;
-  assert(Index < TypesLoaded.size() && "Type index out-of-range");
-  if (TypesLoaded[Index].isNull()) {
-    TypesLoaded[Index] = readTypeRecord(Index);
-    if (TypesLoaded[Index].isNull())
-      return QualType();
-
-    TypesLoaded[Index]->setFromAST();
-    if (DeserializationListener)
-      DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
-                                        TypesLoaded[Index]);
-  }
-
-  return TypesLoaded[Index].withFastQualifiers(FastQuals);
-}
-
-QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) {
-  return GetType(getGlobalTypeID(F, LocalID));
-}
-
-serialization::TypeID 
-ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const {
-  unsigned FastQuals = LocalID & Qualifiers::FastMask;
-  unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;
-  
-  if (LocalIndex < NUM_PREDEF_TYPE_IDS)
-    return LocalID;
-
-  ContinuousRangeMap<uint32_t, int, 2>::iterator I
-    = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);
-  assert(I != F.TypeRemap.end() && "Invalid index into type index remap");
-  
-  unsigned GlobalIndex = LocalIndex + I->second;
-  return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;
-}
-
-TemplateArgumentLocInfo
-ASTReader::GetTemplateArgumentLocInfo(ModuleFile &F,
-                                      TemplateArgument::ArgKind Kind,
-                                      const RecordData &Record,
-                                      unsigned &Index) {
-  switch (Kind) {
-  case TemplateArgument::Expression:
-    return ReadExpr(F);
-  case TemplateArgument::Type:
-    return GetTypeSourceInfo(F, Record, Index);
-  case TemplateArgument::Template: {
-    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 
-                                                                     Index);
-    SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
-    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
-                                   SourceLocation());
-  }
-  case TemplateArgument::TemplateExpansion: {
-    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 
-                                                                     Index);
-    SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
-    SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);
-    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, 
-                                   EllipsisLoc);
-  }
-  case TemplateArgument::Null:
-  case TemplateArgument::Integral:
-  case TemplateArgument::Declaration:
-  case TemplateArgument::NullPtr:
-  case TemplateArgument::Pack:
-    // FIXME: Is this right?
-    return TemplateArgumentLocInfo();
-  }
-  llvm_unreachable("unexpected template argument loc");
-}
-
-TemplateArgumentLoc
-ASTReader::ReadTemplateArgumentLoc(ModuleFile &F,
-                                   const RecordData &Record, unsigned &Index) {
-  TemplateArgument Arg = ReadTemplateArgument(F, Record, Index);
-
-  if (Arg.getKind() == TemplateArgument::Expression) {
-    if (Record[Index++]) // bool InfoHasSameExpr.
-      return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
-  }
-  return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(F, Arg.getKind(),
-                                                             Record, Index));
-}
-
-Decl *ASTReader::GetExternalDecl(uint32_t ID) {
-  return GetDecl(ID);
-}
-
-uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, 
-                                          unsigned &Idx){
-  if (Idx >= Record.size())
-    return 0;
-  
-  unsigned LocalID = Record[Idx++];
-  return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);
-}
-
-CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
-  RecordLocation Loc = getLocalBitOffset(Offset);
-  llvm::BitstreamCursor &Cursor = Loc.F->DeclsCursor;
-  SavedStreamPosition SavedPosition(Cursor);
-  Cursor.JumpToBit(Loc.Offset);
-  ReadingKindTracker ReadingKind(Read_Decl, *this);
-  RecordData Record;
-  unsigned Code = Cursor.ReadCode();
-  unsigned RecCode = Cursor.ReadRecord(Code, Record);
-  if (RecCode != DECL_CXX_BASE_SPECIFIERS) {
-    Error("Malformed AST file: missing C++ base specifiers");
-    return 0;
-  }
-
-  unsigned Idx = 0;
-  unsigned NumBases = Record[Idx++];
-  void *Mem = Context.Allocate(sizeof(CXXBaseSpecifier) * NumBases);
-  CXXBaseSpecifier *Bases = new (Mem) CXXBaseSpecifier [NumBases];
-  for (unsigned I = 0; I != NumBases; ++I)
-    Bases[I] = ReadCXXBaseSpecifier(*Loc.F, Record, Idx);
-  return Bases;
-}
-
-serialization::DeclID 
-ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
-  if (LocalID < NUM_PREDEF_DECL_IDS)
-    return LocalID;
-
-  ContinuousRangeMap<uint32_t, int, 2>::iterator I
-    = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);
-  assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");
-  
-  return LocalID + I->second;
-}
-
-bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
-                                   ModuleFile &M) const {
-  GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID);
-  assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
-  return &M == I->second;
-}
-
-ModuleFile *ASTReader::getOwningModuleFile(Decl *D) {
-  if (!D->isFromASTFile())
-    return 0;
-  GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
-  assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
-  return I->second;
-}
-
-SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
-  if (ID < NUM_PREDEF_DECL_IDS)
-    return SourceLocation();
-  
-  unsigned Index = ID - NUM_PREDEF_DECL_IDS;
-
-  if (Index > DeclsLoaded.size()) {
-    Error("declaration ID out-of-range for AST file");
-    return SourceLocation();
-  }
-  
-  if (Decl *D = DeclsLoaded[Index])
-    return D->getLocation();
-
-  unsigned RawLocation = 0;
-  RecordLocation Rec = DeclCursorForID(ID, RawLocation);
-  return ReadSourceLocation(*Rec.F, RawLocation);
-}
-
-Decl *ASTReader::GetDecl(DeclID ID) {
-  if (ID < NUM_PREDEF_DECL_IDS) {    
-    switch ((PredefinedDeclIDs)ID) {
-    case PREDEF_DECL_NULL_ID:
-      return 0;
-        
-    case PREDEF_DECL_TRANSLATION_UNIT_ID:
-      return Context.getTranslationUnitDecl();
-        
-    case PREDEF_DECL_OBJC_ID_ID:
-      return Context.getObjCIdDecl();
-
-    case PREDEF_DECL_OBJC_SEL_ID:
-      return Context.getObjCSelDecl();
-
-    case PREDEF_DECL_OBJC_CLASS_ID:
-      return Context.getObjCClassDecl();
-        
-    case PREDEF_DECL_OBJC_PROTOCOL_ID:
-      return Context.getObjCProtocolDecl();
-        
-    case PREDEF_DECL_INT_128_ID:
-      return Context.getInt128Decl();
-
-    case PREDEF_DECL_UNSIGNED_INT_128_ID:
-      return Context.getUInt128Decl();
-        
-    case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
-      return Context.getObjCInstanceTypeDecl();
-
-    case PREDEF_DECL_BUILTIN_VA_LIST_ID:
-      return Context.getBuiltinVaListDecl();
-    }
-  }
-  
-  unsigned Index = ID - NUM_PREDEF_DECL_IDS;
-
-  if (Index >= DeclsLoaded.size()) {
-    assert(0 && "declaration ID out-of-range for AST file");
-    Error("declaration ID out-of-range for AST file");
-    return 0;
-  }
-  
-  if (!DeclsLoaded[Index]) {
-    ReadDeclRecord(ID);
-    if (DeserializationListener)
-      DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
-  }
-
-  return DeclsLoaded[Index];
-}
-
-DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, 
-                                                  DeclID GlobalID) {
-  if (GlobalID < NUM_PREDEF_DECL_IDS)
-    return GlobalID;
-  
-  GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID);
-  assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
-  ModuleFile *Owner = I->second;
-
-  llvm::DenseMap<ModuleFile *, serialization::DeclID>::iterator Pos
-    = M.GlobalToLocalDeclIDs.find(Owner);
-  if (Pos == M.GlobalToLocalDeclIDs.end())
-    return 0;
-      
-  return GlobalID - Owner->BaseDeclID + Pos->second;
-}
-
-serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, 
-                                            const RecordData &Record,
-                                            unsigned &Idx) {
-  if (Idx >= Record.size()) {
-    Error("Corrupted AST file");
-    return 0;
-  }
-  
-  return getGlobalDeclID(F, Record[Idx++]);
-}
-
-/// \brief Resolve the offset of a statement into a statement.
-///
-/// This operation will read a new statement from the external
-/// source each time it is called, and is meant to be used via a
-/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
-Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
-  // Switch case IDs are per Decl.
-  ClearSwitchCaseIDs();
-
-  // Offset here is a global offset across the entire chain.
-  RecordLocation Loc = getLocalBitOffset(Offset);
-  Loc.F->DeclsCursor.JumpToBit(Loc.Offset);
-  return ReadStmtFromStream(*Loc.F);
-}
-
-namespace {
-  class FindExternalLexicalDeclsVisitor {
-    ASTReader &Reader;
-    const DeclContext *DC;
-    bool (*isKindWeWant)(Decl::Kind);
-    
-    SmallVectorImpl<Decl*> &Decls;
-    bool PredefsVisited[NUM_PREDEF_DECL_IDS];
-
-  public:
-    FindExternalLexicalDeclsVisitor(ASTReader &Reader, const DeclContext *DC,
-                                    bool (*isKindWeWant)(Decl::Kind),
-                                    SmallVectorImpl<Decl*> &Decls)
-      : Reader(Reader), DC(DC), isKindWeWant(isKindWeWant), Decls(Decls) 
-    {
-      for (unsigned I = 0; I != NUM_PREDEF_DECL_IDS; ++I)
-        PredefsVisited[I] = false;
-    }
-
-    static bool visit(ModuleFile &M, bool Preorder, void *UserData) {
-      if (Preorder)
-        return false;
-
-      FindExternalLexicalDeclsVisitor *This
-        = static_cast<FindExternalLexicalDeclsVisitor *>(UserData);
-
-      ModuleFile::DeclContextInfosMap::iterator Info
-        = M.DeclContextInfos.find(This->DC);
-      if (Info == M.DeclContextInfos.end() || !Info->second.LexicalDecls)
-        return false;
-
-      // Load all of the declaration IDs
-      for (const KindDeclIDPair *ID = Info->second.LexicalDecls,
-                               *IDE = ID + Info->second.NumLexicalDecls; 
-           ID != IDE; ++ID) {
-        if (This->isKindWeWant && !This->isKindWeWant((Decl::Kind)ID->first))
-          continue;
-
-        // Don't add predefined declarations to the lexical context more
-        // than once.
-        if (ID->second < NUM_PREDEF_DECL_IDS) {
-          if (This->PredefsVisited[ID->second])
-            continue;
-
-          This->PredefsVisited[ID->second] = true;
-        }
-
-        if (Decl *D = This->Reader.GetLocalDecl(M, ID->second)) {
-          if (!This->DC->isDeclInLexicalTraversal(D))
-            This->Decls.push_back(D);
-        }
-      }
-
-      return false;
-    }
-  };
-}
-
-ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
-                                         bool (*isKindWeWant)(Decl::Kind),
-                                         SmallVectorImpl<Decl*> &Decls) {
-  // There might be lexical decls in multiple modules, for the TU at
-  // least. Walk all of the modules in the order they were loaded.
-  FindExternalLexicalDeclsVisitor Visitor(*this, DC, isKindWeWant, Decls);
-  ModuleMgr.visitDepthFirst(&FindExternalLexicalDeclsVisitor::visit, &Visitor);
-  ++NumLexicalDeclContextsRead;
-  return ELR_Success;
-}
-
-namespace {
-
-class DeclIDComp {
-  ASTReader &Reader;
-  ModuleFile &Mod;
-
-public:
-  DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {}
-
-  bool operator()(LocalDeclID L, LocalDeclID R) const {
-    SourceLocation LHS = getLocation(L);
-    SourceLocation RHS = getLocation(R);
-    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
-  }
-
-  bool operator()(SourceLocation LHS, LocalDeclID R) const {
-    SourceLocation RHS = getLocation(R);
-    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
-  }
-
-  bool operator()(LocalDeclID L, SourceLocation RHS) const {
-    SourceLocation LHS = getLocation(L);
-    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
-  }
-
-  SourceLocation getLocation(LocalDeclID ID) const {
-    return Reader.getSourceManager().getFileLoc(
-            Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID)));
-  }
-};
-
-}
-
-void ASTReader::FindFileRegionDecls(FileID File,
-                                    unsigned Offset, unsigned Length,
-                                    SmallVectorImpl<Decl *> &Decls) {
-  SourceManager &SM = getSourceManager();
-
-  llvm::DenseMap<FileID, FileDeclsInfo>::iterator I = FileDeclIDs.find(File);
-  if (I == FileDeclIDs.end())
-    return;
-
-  FileDeclsInfo &DInfo = I->second;
-  if (DInfo.Decls.empty())
-    return;
-
-  SourceLocation
-    BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset);
-  SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length);
-
-  DeclIDComp DIDComp(*this, *DInfo.Mod);
-  ArrayRef<serialization::LocalDeclID>::iterator
-    BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
-                               BeginLoc, DIDComp);
-  if (BeginIt != DInfo.Decls.begin())
-    --BeginIt;
-
-  // If we are pointing at a top-level decl inside an objc container, we need
-  // to backtrack until we find it otherwise we will fail to report that the
-  // region overlaps with an objc container.
-  while (BeginIt != DInfo.Decls.begin() &&
-         GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt))
-             ->isTopLevelDeclInObjCContainer())
-    --BeginIt;
-
-  ArrayRef<serialization::LocalDeclID>::iterator
-    EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
-                             EndLoc, DIDComp);
-  if (EndIt != DInfo.Decls.end())
-    ++EndIt;
-  
-  for (ArrayRef<serialization::LocalDeclID>::iterator
-         DIt = BeginIt; DIt != EndIt; ++DIt)
-    Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
-}
-
-namespace {
-  /// \brief ModuleFile visitor used to perform name lookup into a
-  /// declaration context.
-  class DeclContextNameLookupVisitor {
-    ASTReader &Reader;
-    llvm::SmallVectorImpl<const DeclContext *> &Contexts;
-    DeclarationName Name;
-    SmallVectorImpl<NamedDecl *> &Decls;
-
-  public:
-    DeclContextNameLookupVisitor(ASTReader &Reader, 
-                                 SmallVectorImpl<const DeclContext *> &Contexts, 
-                                 DeclarationName Name,
-                                 SmallVectorImpl<NamedDecl *> &Decls)
-      : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls) { }
-
-    static bool visit(ModuleFile &M, void *UserData) {
-      DeclContextNameLookupVisitor *This
-        = static_cast<DeclContextNameLookupVisitor *>(UserData);
-
-      // Check whether we have any visible declaration information for
-      // this context in this module.
-      ModuleFile::DeclContextInfosMap::iterator Info;
-      bool FoundInfo = false;
-      for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) {
-        Info = M.DeclContextInfos.find(This->Contexts[I]);
-        if (Info != M.DeclContextInfos.end() && 
-            Info->second.NameLookupTableData) {
-          FoundInfo = true;
-          break;
-        }
-      }
-
-      if (!FoundInfo)
-        return false;
-      
-      // Look for this name within this module.
-      ASTDeclContextNameLookupTable *LookupTable =
-        Info->second.NameLookupTableData;
-      ASTDeclContextNameLookupTable::iterator Pos
-        = LookupTable->find(This->Name);
-      if (Pos == LookupTable->end())
-        return false;
-
-      bool FoundAnything = false;
-      ASTDeclContextNameLookupTrait::data_type Data = *Pos;
-      for (; Data.first != Data.second; ++Data.first) {
-        NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);
-        if (!ND)
-          continue;
-
-        if (ND->getDeclName() != This->Name) {
-          // A name might be null because the decl's redeclarable part is
-          // currently read before reading its name. The lookup is triggered by
-          // building that decl (likely indirectly), and so it is later in the
-          // sense of "already existing" and can be ignored here.
-          continue;
-        }
-      
-        // Record this declaration.
-        FoundAnything = true;
-        This->Decls.push_back(ND);
-      }
-
-      return FoundAnything;
-    }
-  };
-}
-
-DeclContext::lookup_result
-ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
-                                          DeclarationName Name) {
-  assert(DC->hasExternalVisibleStorage() &&
-         "DeclContext has no visible decls in storage");
-  if (!Name)
-    return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
-                                      DeclContext::lookup_iterator(0));
-
-  SmallVector<NamedDecl *, 64> Decls;
-  
-  // Compute the declaration contexts we need to look into. Multiple such
-  // declaration contexts occur when two declaration contexts from disjoint
-  // modules get merged, e.g., when two namespaces with the same name are 
-  // independently defined in separate modules.
-  SmallVector<const DeclContext *, 2> Contexts;
-  Contexts.push_back(DC);
-  
-  if (DC->isNamespace()) {
-    MergedDeclsMap::iterator Merged
-      = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
-    if (Merged != MergedDecls.end()) {
-      for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
-        Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
-    }
-  }
-  
-  DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls);
-  ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
-  ++NumVisibleDeclContextsRead;
-  SetExternalVisibleDeclsForName(DC, Name, Decls);
-  return const_cast<DeclContext*>(DC)->lookup(Name);
-}
-
-namespace {
-  /// \brief ModuleFile visitor used to retrieve all visible names in a
-  /// declaration context.
-  class DeclContextAllNamesVisitor {
-    ASTReader &Reader;
-    llvm::SmallVectorImpl<const DeclContext *> &Contexts;
-    llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls;
-
-  public:
-    DeclContextAllNamesVisitor(ASTReader &Reader,
-                               SmallVectorImpl<const DeclContext *> &Contexts,
-                               llvm::DenseMap<DeclarationName,
-                                           SmallVector<NamedDecl *, 8> > &Decls)
-      : Reader(Reader), Contexts(Contexts), Decls(Decls) { }
-
-    static bool visit(ModuleFile &M, void *UserData) {
-      DeclContextAllNamesVisitor *This
-        = static_cast<DeclContextAllNamesVisitor *>(UserData);
-
-      // Check whether we have any visible declaration information for
-      // this context in this module.
-      ModuleFile::DeclContextInfosMap::iterator Info;
-      bool FoundInfo = false;
-      for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) {
-        Info = M.DeclContextInfos.find(This->Contexts[I]);
-        if (Info != M.DeclContextInfos.end() &&
-            Info->second.NameLookupTableData) {
-          FoundInfo = true;
-          break;
-        }
-      }
-
-      if (!FoundInfo)
-        return false;
-
-      ASTDeclContextNameLookupTable *LookupTable =
-        Info->second.NameLookupTableData;
-      bool FoundAnything = false;
-      for (ASTDeclContextNameLookupTable::data_iterator
-	     I = LookupTable->data_begin(), E = LookupTable->data_end();
-	   I != E; ++I) {
-        ASTDeclContextNameLookupTrait::data_type Data = *I;
-        for (; Data.first != Data.second; ++Data.first) {
-          NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M,
-                                                                 *Data.first);
-          if (!ND)
-            continue;
-
-          // Record this declaration.
-          FoundAnything = true;
-          This->Decls[ND->getDeclName()].push_back(ND);
-        }
-      }
-
-      return FoundAnything;
-    }
-  };
-}
-
-void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
-  if (!DC->hasExternalVisibleStorage())
-    return;
-  llvm::DenseMap<DeclarationName, llvm::SmallVector<NamedDecl*, 8> > Decls;
-
-  // Compute the declaration contexts we need to look into. Multiple such
-  // declaration contexts occur when two declaration contexts from disjoint
-  // modules get merged, e.g., when two namespaces with the same name are
-  // independently defined in separate modules.
-  SmallVector<const DeclContext *, 2> Contexts;
-  Contexts.push_back(DC);
-
-  if (DC->isNamespace()) {
-    MergedDeclsMap::iterator Merged
-      = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
-    if (Merged != MergedDecls.end()) {
-      for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
-        Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
-    }
-  }
-
-  DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls);
-  ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor);
-  ++NumVisibleDeclContextsRead;
-
-  for (llvm::DenseMap<DeclarationName,
-                      llvm::SmallVector<NamedDecl*, 8> >::iterator
-         I = Decls.begin(), E = Decls.end(); I != E; ++I) {
-    SetExternalVisibleDeclsForName(DC, I->first, I->second);
-  }
-  const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false);
-}
-
-/// \brief Under non-PCH compilation the consumer receives the objc methods
-/// before receiving the implementation, and codegen depends on this.
-/// We simulate this by deserializing and passing to consumer the methods of the
-/// implementation before passing the deserialized implementation decl.
-static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
-                                       ASTConsumer *Consumer) {
-  assert(ImplD && Consumer);
-
-  for (ObjCImplDecl::method_iterator
-         I = ImplD->meth_begin(), E = ImplD->meth_end(); I != E; ++I)
-    Consumer->HandleInterestingDecl(DeclGroupRef(*I));
-
-  Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
-}
-
-void ASTReader::PassInterestingDeclsToConsumer() {
-  assert(Consumer);
-  while (!InterestingDecls.empty()) {
-    Decl *D = InterestingDecls.front();
-    InterestingDecls.pop_front();
-
-    PassInterestingDeclToConsumer(D);
-  }
-}
-
-void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
-  if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
-    PassObjCImplDeclToConsumer(ImplD, Consumer);
-  else
-    Consumer->HandleInterestingDecl(DeclGroupRef(D));
-}
-
-void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
-  this->Consumer = Consumer;
-
-  if (!Consumer)
-    return;
-
-  for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
-    // Force deserialization of this decl, which will cause it to be queued for
-    // passing to the consumer.
-    GetDecl(ExternalDefinitions[I]);
-  }
-  ExternalDefinitions.clear();
-
-  PassInterestingDeclsToConsumer();
-}
-
-void ASTReader::PrintStats() {
-  std::fprintf(stderr, "*** AST File Statistics:\n");
-
-  unsigned NumTypesLoaded
-    = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
-                                      QualType());
-  unsigned NumDeclsLoaded
-    = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
-                                      (Decl *)0);
-  unsigned NumIdentifiersLoaded
-    = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
-                                            IdentifiersLoaded.end(),
-                                            (IdentifierInfo *)0);
-  unsigned NumMacrosLoaded
-    = MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
-                                       MacrosLoaded.end(),
-                                       (MacroInfo *)0);
-  unsigned NumSelectorsLoaded
-    = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
-                                          SelectorsLoaded.end(),
-                                          Selector());
-
-  if (unsigned TotalNumSLocEntries = getTotalNumSLocs())
-    std::fprintf(stderr, "  %u/%u source location entries read (%f%%)\n",
-                 NumSLocEntriesRead, TotalNumSLocEntries,
-                 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
-  if (!TypesLoaded.empty())
-    std::fprintf(stderr, "  %u/%u types read (%f%%)\n",
-                 NumTypesLoaded, (unsigned)TypesLoaded.size(),
-                 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
-  if (!DeclsLoaded.empty())
-    std::fprintf(stderr, "  %u/%u declarations read (%f%%)\n",
-                 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
-                 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
-  if (!IdentifiersLoaded.empty())
-    std::fprintf(stderr, "  %u/%u identifiers read (%f%%)\n",
-                 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
-                 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
-  if (!MacrosLoaded.empty())
-    std::fprintf(stderr, "  %u/%u macros read (%f%%)\n",
-                 NumMacrosLoaded, (unsigned)MacrosLoaded.size(),
-                 ((float)NumMacrosLoaded/MacrosLoaded.size() * 100));
-  if (!SelectorsLoaded.empty())
-    std::fprintf(stderr, "  %u/%u selectors read (%f%%)\n",
-                 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
-                 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
-  if (TotalNumStatements)
-    std::fprintf(stderr, "  %u/%u statements read (%f%%)\n",
-                 NumStatementsRead, TotalNumStatements,
-                 ((float)NumStatementsRead/TotalNumStatements * 100));
-  if (TotalNumMacros)
-    std::fprintf(stderr, "  %u/%u macros read (%f%%)\n",
-                 NumMacrosRead, TotalNumMacros,
-                 ((float)NumMacrosRead/TotalNumMacros * 100));
-  if (TotalLexicalDeclContexts)
-    std::fprintf(stderr, "  %u/%u lexical declcontexts read (%f%%)\n",
-                 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
-                 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
-                  * 100));
-  if (TotalVisibleDeclContexts)
-    std::fprintf(stderr, "  %u/%u visible declcontexts read (%f%%)\n",
-                 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
-                 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
-                  * 100));
-  if (TotalNumMethodPoolEntries) {
-    std::fprintf(stderr, "  %u/%u method pool entries read (%f%%)\n",
-                 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
-                 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
-                  * 100));
-    std::fprintf(stderr, "  %u method pool misses\n", NumMethodPoolMisses);
-  }
-  std::fprintf(stderr, "\n");
-  dump();
-  std::fprintf(stderr, "\n");
-}
-
-template<typename Key, typename ModuleFile, unsigned InitialCapacity>
-static void 
-dumpModuleIDMap(StringRef Name,
-                const ContinuousRangeMap<Key, ModuleFile *, 
-                                         InitialCapacity> &Map) {
-  if (Map.begin() == Map.end())
-    return;
-  
-  typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType;
-  llvm::errs() << Name << ":\n";
-  for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); 
-       I != IEnd; ++I) {
-    llvm::errs() << "  " << I->first << " -> " << I->second->FileName
-      << "\n";
-  }
-}
-
-void ASTReader::dump() {
-  llvm::errs() << "*** PCH/ModuleFile Remappings:\n";
-  dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);
-  dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);
-  dumpModuleIDMap("Global type map", GlobalTypeMap);
-  dumpModuleIDMap("Global declaration map", GlobalDeclMap);
-  dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
-  dumpModuleIDMap("Global macro map", GlobalMacroMap);
-  dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
-  dumpModuleIDMap("Global selector map", GlobalSelectorMap);
-  dumpModuleIDMap("Global preprocessed entity map", 
-                  GlobalPreprocessedEntityMap);
-  
-  llvm::errs() << "\n*** PCH/Modules Loaded:";
-  for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(), 
-                                       MEnd = ModuleMgr.end();
-       M != MEnd; ++M)
-    (*M)->dump();
-}
-
-/// Return the amount of memory used by memory buffers, breaking down
-/// by heap-backed versus mmap'ed memory.
-void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
-  for (ModuleConstIterator I = ModuleMgr.begin(),
-      E = ModuleMgr.end(); I != E; ++I) {
-    if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
-      size_t bytes = buf->getBufferSize();
-      switch (buf->getBufferKind()) {
-        case llvm::MemoryBuffer::MemoryBuffer_Malloc:
-          sizes.malloc_bytes += bytes;
-          break;
-        case llvm::MemoryBuffer::MemoryBuffer_MMap:
-          sizes.mmap_bytes += bytes;
-          break;
-      }
-    }
-  }
-}
-
-void ASTReader::InitializeSema(Sema &S) {
-  SemaObj = &S;
-  S.addExternalSource(this);
-
-  // Makes sure any declarations that were deserialized "too early"
-  // still get added to the identifier's declaration chains.
-  for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
-    SemaObj->pushExternalDeclIntoScope(PreloadedDecls[I], 
-                                       PreloadedDecls[I]->getDeclName());
-  }
-  PreloadedDecls.clear();
-
-  // Load the offsets of the declarations that Sema references.
-  // They will be lazily deserialized when needed.
-  if (!SemaDeclRefs.empty()) {
-    assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
-    if (!SemaObj->StdNamespace)
-      SemaObj->StdNamespace = SemaDeclRefs[0];
-    if (!SemaObj->StdBadAlloc)
-      SemaObj->StdBadAlloc = SemaDeclRefs[1];
-  }
-
-  if (!FPPragmaOptions.empty()) {
-    assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
-    SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];
-  }
-
-  if (!OpenCLExtensions.empty()) {
-    unsigned I = 0;
-#define OPENCLEXT(nm)  SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++];
-#include "clang/Basic/OpenCLExtensions.def"
-
-    assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS");
-  }
-}
-
-IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
-  // Note that we are loading an identifier.
-  Deserializing AnIdentifier(this);
-  
-  IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart),
-                                  /*PriorGeneration=*/0);
-  ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
-  IdentifierInfo *II = Visitor.getIdentifierInfo();
-  markIdentifierUpToDate(II);
-  return II;
-}
-
-namespace clang {
-  /// \brief An identifier-lookup iterator that enumerates all of the
-  /// identifiers stored within a set of AST files.
-  class ASTIdentifierIterator : public IdentifierIterator {
-    /// \brief The AST reader whose identifiers are being enumerated.
-    const ASTReader &Reader;
-
-    /// \brief The current index into the chain of AST files stored in
-    /// the AST reader.
-    unsigned Index;
-
-    /// \brief The current position within the identifier lookup table
-    /// of the current AST file.
-    ASTIdentifierLookupTable::key_iterator Current;
-
-    /// \brief The end position within the identifier lookup table of
-    /// the current AST file.
-    ASTIdentifierLookupTable::key_iterator End;
-
-  public:
-    explicit ASTIdentifierIterator(const ASTReader &Reader);
-
-    virtual StringRef Next();
-  };
-}
-
-ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader)
-  : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) {
-  ASTIdentifierLookupTable *IdTable
-    = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable;
-  Current = IdTable->key_begin();
-  End = IdTable->key_end();
-}
-
-StringRef ASTIdentifierIterator::Next() {
-  while (Current == End) {
-    // If we have exhausted all of our AST files, we're done.
-    if (Index == 0)
-      return StringRef();
-
-    --Index;
-    ASTIdentifierLookupTable *IdTable
-      = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].
-        IdentifierLookupTable;
-    Current = IdTable->key_begin();
-    End = IdTable->key_end();
-  }
-
-  // We have any identifiers remaining in the current AST file; return
-  // the next one.
-  std::pair<const char*, unsigned> Key = *Current;
-  ++Current;
-  return StringRef(Key.first, Key.second);
-}
-
-IdentifierIterator *ASTReader::getIdentifiers() const {
-  return new ASTIdentifierIterator(*this);
-}
-
-namespace clang { namespace serialization {
-  class ReadMethodPoolVisitor {
-    ASTReader &Reader;
-    Selector Sel;
-    unsigned PriorGeneration;
-    llvm::SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
-    llvm::SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
-
-  public:
-    ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel, 
-                          unsigned PriorGeneration)
-      : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) { }
-    
-    static bool visit(ModuleFile &M, void *UserData) {
-      ReadMethodPoolVisitor *This
-        = static_cast<ReadMethodPoolVisitor *>(UserData);
-      
-      if (!M.SelectorLookupTable)
-        return false;
-      
-      // If we've already searched this module file, skip it now.
-      if (M.Generation <= This->PriorGeneration)
-        return true;
-
-      ASTSelectorLookupTable *PoolTable
-        = (ASTSelectorLookupTable*)M.SelectorLookupTable;
-      ASTSelectorLookupTable::iterator Pos = PoolTable->find(This->Sel);
-      if (Pos == PoolTable->end())
-        return false;
-      
-      ++This->Reader.NumSelectorsRead;
-      // FIXME: Not quite happy with the statistics here. We probably should
-      // disable this tracking when called via LoadSelector.
-      // Also, should entries without methods count as misses?
-      ++This->Reader.NumMethodPoolEntriesRead;
-      ASTSelectorLookupTrait::data_type Data = *Pos;
-      if (This->Reader.DeserializationListener)
-        This->Reader.DeserializationListener->SelectorRead(Data.ID, 
-                                                           This->Sel);
-      
-      This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
-      This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
-      return true;
-    }
-    
-    /// \brief Retrieve the instance methods found by this visitor.
-    ArrayRef<ObjCMethodDecl *> getInstanceMethods() const { 
-      return InstanceMethods; 
-    }
-
-    /// \brief Retrieve the instance methods found by this visitor.
-    ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { 
-      return FactoryMethods;
-    }
-  };
-} } // end namespace clang::serialization
-
-/// \brief Add the given set of methods to the method list.
-static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,
-                             ObjCMethodList &List) {
-  for (unsigned I = 0, N = Methods.size(); I != N; ++I) {
-    S.addMethodToGlobalList(&List, Methods[I]);
-  }
-}
-                             
-void ASTReader::ReadMethodPool(Selector Sel) {
-  // Get the selector generation and update it to the current generation.
-  unsigned &Generation = SelectorGeneration[Sel];
-  unsigned PriorGeneration = Generation;
-  Generation = CurrentGeneration;
-  
-  // Search for methods defined with this selector.
-  ReadMethodPoolVisitor Visitor(*this, Sel, PriorGeneration);
-  ModuleMgr.visit(&ReadMethodPoolVisitor::visit, &Visitor);
-  
-  if (Visitor.getInstanceMethods().empty() &&
-      Visitor.getFactoryMethods().empty()) {
-    ++NumMethodPoolMisses;
-    return;
-  }
-  
-  if (!getSema())
-    return;
-  
-  Sema &S = *getSema();
-  Sema::GlobalMethodPool::iterator Pos
-    = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first;
-  
-  addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);
-  addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);
-}
-
-void ASTReader::ReadKnownNamespaces(
-                          SmallVectorImpl<NamespaceDecl *> &Namespaces) {
-  Namespaces.clear();
-  
-  for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {
-    if (NamespaceDecl *Namespace 
-                = dyn_cast_or_null<NamespaceDecl>(GetDecl(KnownNamespaces[I])))
-      Namespaces.push_back(Namespace);
-  }
-}
-
-void ASTReader::ReadTentativeDefinitions(
-                  SmallVectorImpl<VarDecl *> &TentativeDefs) {
-  for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
-    VarDecl *Var = dyn_cast_or_null<VarDecl>(GetDecl(TentativeDefinitions[I]));
-    if (Var)
-      TentativeDefs.push_back(Var);
-  }
-  TentativeDefinitions.clear();
-}
-
-void ASTReader::ReadUnusedFileScopedDecls(
-                               SmallVectorImpl<const DeclaratorDecl *> &Decls) {
-  for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
-    DeclaratorDecl *D
-      = dyn_cast_or_null<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
-    if (D)
-      Decls.push_back(D);
-  }
-  UnusedFileScopedDecls.clear();
-}
-
-void ASTReader::ReadDelegatingConstructors(
-                                 SmallVectorImpl<CXXConstructorDecl *> &Decls) {
-  for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) {
-    CXXConstructorDecl *D
-      = dyn_cast_or_null<CXXConstructorDecl>(GetDecl(DelegatingCtorDecls[I]));
-    if (D)
-      Decls.push_back(D);
-  }
-  DelegatingCtorDecls.clear();
-}
-
-void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {
-  for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I) {
-    TypedefNameDecl *D
-      = dyn_cast_or_null<TypedefNameDecl>(GetDecl(ExtVectorDecls[I]));
-    if (D)
-      Decls.push_back(D);
-  }
-  ExtVectorDecls.clear();
-}
-
-void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {
-  for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {
-    CXXRecordDecl *D
-      = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I]));
-    if (D)
-      Decls.push_back(D);
-  }
-  DynamicClasses.clear();
-}
-
-void 
-ASTReader::ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl *> &Decls) {
-  for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
-    NamedDecl *D 
-      = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
-    if (D)
-      Decls.push_back(D);
-  }
-  LocallyScopedExternalDecls.clear();
-}
-
-void ASTReader::ReadReferencedSelectors(
-       SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
-  if (ReferencedSelectorsData.empty())
-    return;
-  
-  // If there are @selector references added them to its pool. This is for
-  // implementation of -Wselector.
-  unsigned int DataSize = ReferencedSelectorsData.size()-1;
-  unsigned I = 0;
-  while (I < DataSize) {
-    Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
-    SourceLocation SelLoc
-      = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
-    Sels.push_back(std::make_pair(Sel, SelLoc));
-  }
-  ReferencedSelectorsData.clear();
-}
-
-void ASTReader::ReadWeakUndeclaredIdentifiers(
-       SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) {
-  if (WeakUndeclaredIdentifiers.empty())
-    return;
-
-  for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) {
-    IdentifierInfo *WeakId 
-      = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
-    IdentifierInfo *AliasId 
-      = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
-    SourceLocation Loc
-      = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]);
-    bool Used = WeakUndeclaredIdentifiers[I++];
-    WeakInfo WI(AliasId, Loc);
-    WI.setUsed(Used);
-    WeakIDs.push_back(std::make_pair(WeakId, WI));
-  }
-  WeakUndeclaredIdentifiers.clear();
-}
-
-void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
-  for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) {
-    ExternalVTableUse VT;
-    VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
-    VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]);
-    VT.DefinitionRequired = VTableUses[Idx++];
-    VTables.push_back(VT);
-  }
-  
-  VTableUses.clear();
-}
-
-void ASTReader::ReadPendingInstantiations(
-       SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) {
-  for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
-    ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
-    SourceLocation Loc
-      = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
-
-    Pending.push_back(std::make_pair(D, Loc));
-  }  
-  PendingInstantiations.clear();
-}
-
-void ASTReader::LoadSelector(Selector Sel) {
-  // It would be complicated to avoid reading the methods anyway. So don't.
-  ReadMethodPool(Sel);
-}
-
-void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {
-  assert(ID && "Non-zero identifier ID required");
-  assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
-  IdentifiersLoaded[ID - 1] = II;
-  if (DeserializationListener)
-    DeserializationListener->IdentifierRead(ID, II);
-}
-
-/// \brief Set the globally-visible declarations associated with the given
-/// identifier.
-///
-/// If the AST reader is currently in a state where the given declaration IDs
-/// cannot safely be resolved, they are queued until it is safe to resolve
-/// them.
-///
-/// \param II an IdentifierInfo that refers to one or more globally-visible
-/// declarations.
-///
-/// \param DeclIDs the set of declaration IDs with the name @p II that are
-/// visible at global scope.
-///
-/// \param Nonrecursive should be true to indicate that the caller knows that
-/// this call is non-recursive, and therefore the globally-visible declarations
-/// will not be placed onto the pending queue.
-void
-ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
-                              const SmallVectorImpl<uint32_t> &DeclIDs,
-                                   bool Nonrecursive) {
-  if (NumCurrentElementsDeserializing && !Nonrecursive) {
-    PendingIdentifierInfos.push_back(PendingIdentifierInfo());
-    PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
-    PII.II = II;
-    PII.DeclIDs.append(DeclIDs.begin(), DeclIDs.end());
-    return;
-  }
-
-  for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
-    NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
-    if (SemaObj) {
-      // Introduce this declaration into the translation-unit scope
-      // and add it to the declaration chain for this identifier, so
-      // that (unqualified) name lookup will find it.
-      SemaObj->pushExternalDeclIntoScope(D, II);
-    } else {
-      // Queue this declaration so that it will be added to the
-      // translation unit scope and identifier's declaration chain
-      // once a Sema object is known.
-      PreloadedDecls.push_back(D);
-    }
-  }
-}
-
-IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
-  if (ID == 0)
-    return 0;
-
-  if (IdentifiersLoaded.empty()) {
-    Error("no identifier table in AST file");
-    return 0;
-  }
-
-  ID -= 1;
-  if (!IdentifiersLoaded[ID]) {
-    GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1);
-    assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map");
-    ModuleFile *M = I->second;
-    unsigned Index = ID - M->BaseIdentifierID;
-    const char *Str = M->IdentifierTableData + M->IdentifierOffsets[Index];
-
-    // All of the strings in the AST file are preceded by a 16-bit length.
-    // Extract that 16-bit length to avoid having to execute strlen().
-    // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
-    //  unsigned integers.  This is important to avoid integer overflow when
-    //  we cast them to 'unsigned'.
-    const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
-    unsigned StrLen = (((unsigned) StrLenPtr[0])
-                       | (((unsigned) StrLenPtr[1]) << 8)) - 1;
-    IdentifiersLoaded[ID]
-      = &PP.getIdentifierTable().get(StringRef(Str, StrLen));
-    if (DeserializationListener)
-      DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
-  }
-
-  return IdentifiersLoaded[ID];
-}
-
-IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) {
-  return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID));
-}
-
-IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
-  if (LocalID < NUM_PREDEF_IDENT_IDS)
-    return LocalID;
-  
-  ContinuousRangeMap<uint32_t, int, 2>::iterator I
-    = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);
-  assert(I != M.IdentifierRemap.end() 
-         && "Invalid index into identifier index remap");
-  
-  return LocalID + I->second;
-}
-
-MacroInfo *ASTReader::getMacro(MacroID ID, MacroInfo *Hint) {
-  if (ID == 0)
-    return 0;
-
-  if (MacrosLoaded.empty()) {
-    Error("no macro table in AST file");
-    return 0;
-  }
-
-  ID -= NUM_PREDEF_MACRO_IDS;
-  if (!MacrosLoaded[ID]) {
-    GlobalMacroMapType::iterator I
-      = GlobalMacroMap.find(ID + NUM_PREDEF_MACRO_IDS);
-    assert(I != GlobalMacroMap.end() && "Corrupted global macro map");
-    ModuleFile *M = I->second;
-    unsigned Index = ID - M->BaseMacroID;
-    ReadMacroRecord(*M, M->MacroOffsets[Index], Hint);
-  }
-
-  return MacrosLoaded[ID];
-}
-
-MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {
-  if (LocalID < NUM_PREDEF_MACRO_IDS)
-    return LocalID;
-
-  ContinuousRangeMap<uint32_t, int, 2>::iterator I
-    = M.MacroRemap.find(LocalID - NUM_PREDEF_MACRO_IDS);
-  assert(I != M.MacroRemap.end() && "Invalid index into macro index remap");
-
-  return LocalID + I->second;
-}
-
-serialization::SubmoduleID
-ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
-  if (LocalID < NUM_PREDEF_SUBMODULE_IDS)
-    return LocalID;
-  
-  ContinuousRangeMap<uint32_t, int, 2>::iterator I
-    = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);
-  assert(I != M.SubmoduleRemap.end() 
-         && "Invalid index into submodule index remap");
-  
-  return LocalID + I->second;
-}
-
-Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {
-  if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {
-    assert(GlobalID == 0 && "Unhandled global submodule ID");
-    return 0;
-  }
-  
-  if (GlobalID > SubmodulesLoaded.size()) {
-    Error("submodule ID out of range in AST file");
-    return 0;
-  }
-  
-  return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
-}
-                               
-Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {
-  return DecodeSelector(getGlobalSelectorID(M, LocalID));
-}
-
-Selector ASTReader::DecodeSelector(serialization::SelectorID ID) {
-  if (ID == 0)
-    return Selector();
-
-  if (ID > SelectorsLoaded.size()) {
-    Error("selector ID out of range in AST file");
-    return Selector();
-  }
-
-  if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
-    // Load this selector from the selector table.
-    GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);
-    assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");
-    ModuleFile &M = *I->second;
-    ASTSelectorLookupTrait Trait(*this, M);
-    unsigned Idx = ID - M.BaseSelectorID - NUM_PREDEF_SELECTOR_IDS;
-    SelectorsLoaded[ID - 1] =
-      Trait.ReadKey(M.SelectorLookupTableData + M.SelectorOffsets[Idx], 0);
-    if (DeserializationListener)
-      DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
-  }
-
-  return SelectorsLoaded[ID - 1];
-}
-
-Selector ASTReader::GetExternalSelector(serialization::SelectorID ID) {
-  return DecodeSelector(ID);
-}
-
-uint32_t ASTReader::GetNumExternalSelectors() {
-  // ID 0 (the null selector) is considered an external selector.
-  return getTotalNumSelectors() + 1;
-}
-
-serialization::SelectorID
-ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const {
-  if (LocalID < NUM_PREDEF_SELECTOR_IDS)
-    return LocalID;
-  
-  ContinuousRangeMap<uint32_t, int, 2>::iterator I
-    = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);
-  assert(I != M.SelectorRemap.end() 
-         && "Invalid index into selector index remap");
-  
-  return LocalID + I->second;
-}
-
-DeclarationName
-ASTReader::ReadDeclarationName(ModuleFile &F, 
-                               const RecordData &Record, unsigned &Idx) {
-  DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
-  switch (Kind) {
-  case DeclarationName::Identifier:
-    return DeclarationName(GetIdentifierInfo(F, Record, Idx));
-
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-    return DeclarationName(ReadSelector(F, Record, Idx));
-
-  case DeclarationName::CXXConstructorName:
-    return Context.DeclarationNames.getCXXConstructorName(
-                          Context.getCanonicalType(readType(F, Record, Idx)));
-
-  case DeclarationName::CXXDestructorName:
-    return Context.DeclarationNames.getCXXDestructorName(
-                          Context.getCanonicalType(readType(F, Record, Idx)));
-
-  case DeclarationName::CXXConversionFunctionName:
-    return Context.DeclarationNames.getCXXConversionFunctionName(
-                          Context.getCanonicalType(readType(F, Record, Idx)));
-
-  case DeclarationName::CXXOperatorName:
-    return Context.DeclarationNames.getCXXOperatorName(
-                                       (OverloadedOperatorKind)Record[Idx++]);
-
-  case DeclarationName::CXXLiteralOperatorName:
-    return Context.DeclarationNames.getCXXLiteralOperatorName(
-                                       GetIdentifierInfo(F, Record, Idx));
-
-  case DeclarationName::CXXUsingDirective:
-    return DeclarationName::getUsingDirectiveName();
-  }
-
-  llvm_unreachable("Invalid NameKind!");
-}
-
-void ASTReader::ReadDeclarationNameLoc(ModuleFile &F,
-                                       DeclarationNameLoc &DNLoc,
-                                       DeclarationName Name,
-                                      const RecordData &Record, unsigned &Idx) {
-  switch (Name.getNameKind()) {
-  case DeclarationName::CXXConstructorName:
-  case DeclarationName::CXXDestructorName:
-  case DeclarationName::CXXConversionFunctionName:
-    DNLoc.NamedType.TInfo = GetTypeSourceInfo(F, Record, Idx);
-    break;
-
-  case DeclarationName::CXXOperatorName:
-    DNLoc.CXXOperatorName.BeginOpNameLoc
-        = ReadSourceLocation(F, Record, Idx).getRawEncoding();
-    DNLoc.CXXOperatorName.EndOpNameLoc
-        = ReadSourceLocation(F, Record, Idx).getRawEncoding();
-    break;
-
-  case DeclarationName::CXXLiteralOperatorName:
-    DNLoc.CXXLiteralOperatorName.OpNameLoc
-        = ReadSourceLocation(F, Record, Idx).getRawEncoding();
-    break;
-
-  case DeclarationName::Identifier:
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-  case DeclarationName::CXXUsingDirective:
-    break;
-  }
-}
-
-void ASTReader::ReadDeclarationNameInfo(ModuleFile &F,
-                                        DeclarationNameInfo &NameInfo,
-                                      const RecordData &Record, unsigned &Idx) {
-  NameInfo.setName(ReadDeclarationName(F, Record, Idx));
-  NameInfo.setLoc(ReadSourceLocation(F, Record, Idx));
-  DeclarationNameLoc DNLoc;
-  ReadDeclarationNameLoc(F, DNLoc, NameInfo.getName(), Record, Idx);
-  NameInfo.setInfo(DNLoc);
-}
-
-void ASTReader::ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info,
-                                  const RecordData &Record, unsigned &Idx) {
-  Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
-  unsigned NumTPLists = Record[Idx++];
-  Info.NumTemplParamLists = NumTPLists;
-  if (NumTPLists) {
-    Info.TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];
-    for (unsigned i=0; i != NumTPLists; ++i)
-      Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx);
-  }
-}
-
-TemplateName
-ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, 
-                            unsigned &Idx) {
-  TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
-  switch (Kind) {
-  case TemplateName::Template:
-      return TemplateName(ReadDeclAs<TemplateDecl>(F, Record, Idx));
-
-  case TemplateName::OverloadedTemplate: {
-    unsigned size = Record[Idx++];
-    UnresolvedSet<8> Decls;
-    while (size--)
-      Decls.addDecl(ReadDeclAs<NamedDecl>(F, Record, Idx));
-
-    return Context.getOverloadedTemplateName(Decls.begin(), Decls.end());
-  }
-
-  case TemplateName::QualifiedTemplate: {
-    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
-    bool hasTemplKeyword = Record[Idx++];
-    TemplateDecl *Template = ReadDeclAs<TemplateDecl>(F, Record, Idx);
-    return Context.getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
-  }
-
-  case TemplateName::DependentTemplate: {
-    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
-    if (Record[Idx++])  // isIdentifier
-      return Context.getDependentTemplateName(NNS,
-                                               GetIdentifierInfo(F, Record, 
-                                                                 Idx));
-    return Context.getDependentTemplateName(NNS,
-                                         (OverloadedOperatorKind)Record[Idx++]);
-  }
-
-  case TemplateName::SubstTemplateTemplateParm: {
-    TemplateTemplateParmDecl *param
-      = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
-    if (!param) return TemplateName();
-    TemplateName replacement = ReadTemplateName(F, Record, Idx);
-    return Context.getSubstTemplateTemplateParm(param, replacement);
-  }
-      
-  case TemplateName::SubstTemplateTemplateParmPack: {
-    TemplateTemplateParmDecl *Param 
-      = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
-    if (!Param)
-      return TemplateName();
-    
-    TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx);
-    if (ArgPack.getKind() != TemplateArgument::Pack)
-      return TemplateName();
-    
-    return Context.getSubstTemplateTemplateParmPack(Param, ArgPack);
-  }
-  }
-
-  llvm_unreachable("Unhandled template name kind!");
-}
-
-TemplateArgument
-ASTReader::ReadTemplateArgument(ModuleFile &F,
-                                const RecordData &Record, unsigned &Idx) {
-  TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++];
-  switch (Kind) {
-  case TemplateArgument::Null:
-    return TemplateArgument();
-  case TemplateArgument::Type:
-    return TemplateArgument(readType(F, Record, Idx));
-  case TemplateArgument::Declaration: {
-    ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx);
-    bool ForReferenceParam = Record[Idx++];
-    return TemplateArgument(D, ForReferenceParam);
-  }
-  case TemplateArgument::NullPtr:
-    return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true);
-  case TemplateArgument::Integral: {
-    llvm::APSInt Value = ReadAPSInt(Record, Idx);
-    QualType T = readType(F, Record, Idx);
-    return TemplateArgument(Context, Value, T);
-  }
-  case TemplateArgument::Template: 
-    return TemplateArgument(ReadTemplateName(F, Record, Idx));
-  case TemplateArgument::TemplateExpansion: {
-    TemplateName Name = ReadTemplateName(F, Record, Idx);
-    llvm::Optional<unsigned> NumTemplateExpansions;
-    if (unsigned NumExpansions = Record[Idx++])
-      NumTemplateExpansions = NumExpansions - 1;
-    return TemplateArgument(Name, NumTemplateExpansions);
-  }
-  case TemplateArgument::Expression:
-    return TemplateArgument(ReadExpr(F));
-  case TemplateArgument::Pack: {
-    unsigned NumArgs = Record[Idx++];
-    TemplateArgument *Args = new (Context) TemplateArgument[NumArgs];
-    for (unsigned I = 0; I != NumArgs; ++I)
-      Args[I] = ReadTemplateArgument(F, Record, Idx);
-    return TemplateArgument(Args, NumArgs);
-  }
-  }
-
-  llvm_unreachable("Unhandled template argument kind!");
-}
-
-TemplateParameterList *
-ASTReader::ReadTemplateParameterList(ModuleFile &F,
-                                     const RecordData &Record, unsigned &Idx) {
-  SourceLocation TemplateLoc = ReadSourceLocation(F, Record, Idx);
-  SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Idx);
-  SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Idx);
-
-  unsigned NumParams = Record[Idx++];
-  SmallVector<NamedDecl *, 16> Params;
-  Params.reserve(NumParams);
-  while (NumParams--)
-    Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));
-
-  TemplateParameterList* TemplateParams =
-    TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
-                                  Params.data(), Params.size(), RAngleLoc);
-  return TemplateParams;
-}
-
-void
-ASTReader::
-ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs,
-                         ModuleFile &F, const RecordData &Record,
-                         unsigned &Idx) {
-  unsigned NumTemplateArgs = Record[Idx++];
-  TemplArgs.reserve(NumTemplateArgs);
-  while (NumTemplateArgs--)
-    TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx));
-}
-
-/// \brief Read a UnresolvedSet structure.
-void ASTReader::ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set,
-                                  const RecordData &Record, unsigned &Idx) {
-  unsigned NumDecls = Record[Idx++];
-  Set.reserve(Context, NumDecls);
-  while (NumDecls--) {
-    NamedDecl *D = ReadDeclAs<NamedDecl>(F, Record, Idx);
-    AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
-    Set.addDecl(Context, D, AS);
-  }
-}
-
-CXXBaseSpecifier
-ASTReader::ReadCXXBaseSpecifier(ModuleFile &F,
-                                const RecordData &Record, unsigned &Idx) {
-  bool isVirtual = static_cast<bool>(Record[Idx++]);
-  bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
-  AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
-  bool inheritConstructors = static_cast<bool>(Record[Idx++]);
-  TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx);
-  SourceRange Range = ReadSourceRange(F, Record, Idx);
-  SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx);
-  CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo, 
-                          EllipsisLoc);
-  Result.setInheritConstructors(inheritConstructors);
-  return Result;
-}
-
-std::pair<CXXCtorInitializer **, unsigned>
-ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
-                                   unsigned &Idx) {
-  CXXCtorInitializer **CtorInitializers = 0;
-  unsigned NumInitializers = Record[Idx++];
-  if (NumInitializers) {
-    CtorInitializers
-        = new (Context) CXXCtorInitializer*[NumInitializers];
-    for (unsigned i=0; i != NumInitializers; ++i) {
-      TypeSourceInfo *TInfo = 0;
-      bool IsBaseVirtual = false;
-      FieldDecl *Member = 0;
-      IndirectFieldDecl *IndirectMember = 0;
-
-      CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
-      switch (Type) {
-      case CTOR_INITIALIZER_BASE:
-        TInfo = GetTypeSourceInfo(F, Record, Idx);
-        IsBaseVirtual = Record[Idx++];
-        break;
-          
-      case CTOR_INITIALIZER_DELEGATING:
-        TInfo = GetTypeSourceInfo(F, Record, Idx);
-        break;
-
-       case CTOR_INITIALIZER_MEMBER:
-        Member = ReadDeclAs<FieldDecl>(F, Record, Idx);
-        break;
-
-       case CTOR_INITIALIZER_INDIRECT_MEMBER:
-        IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx);
-        break;
-      }
-
-      SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx);
-      Expr *Init = ReadExpr(F);
-      SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);
-      SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
-      bool IsWritten = Record[Idx++];
-      unsigned SourceOrderOrNumArrayIndices;
-      SmallVector<VarDecl *, 8> Indices;
-      if (IsWritten) {
-        SourceOrderOrNumArrayIndices = Record[Idx++];
-      } else {
-        SourceOrderOrNumArrayIndices = Record[Idx++];
-        Indices.reserve(SourceOrderOrNumArrayIndices);
-        for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
-          Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx));
-      }
-
-      CXXCtorInitializer *BOMInit;
-      if (Type == CTOR_INITIALIZER_BASE) {
-        BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, IsBaseVirtual,
-                                             LParenLoc, Init, RParenLoc,
-                                             MemberOrEllipsisLoc);
-      } else if (Type == CTOR_INITIALIZER_DELEGATING) {
-        BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, LParenLoc,
-                                                   Init, RParenLoc);
-      } else if (IsWritten) {
-        if (Member)
-          BOMInit = new (Context) CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc,
-                                               LParenLoc, Init, RParenLoc);
-        else 
-          BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember,
-                                               MemberOrEllipsisLoc, LParenLoc,
-                                               Init, RParenLoc);
-      } else {
-        BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc,
-                                             LParenLoc, Init, RParenLoc,
-                                             Indices.data(), Indices.size());
-      }
-
-      if (IsWritten)
-        BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices);
-      CtorInitializers[i] = BOMInit;
-    }
-  }
-
-  return std::make_pair(CtorInitializers, NumInitializers);
-}
-
-NestedNameSpecifier *
-ASTReader::ReadNestedNameSpecifier(ModuleFile &F,
-                                   const RecordData &Record, unsigned &Idx) {
-  unsigned N = Record[Idx++];
-  NestedNameSpecifier *NNS = 0, *Prev = 0;
-  for (unsigned I = 0; I != N; ++I) {
-    NestedNameSpecifier::SpecifierKind Kind
-      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
-    switch (Kind) {
-    case NestedNameSpecifier::Identifier: {
-      IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
-      NNS = NestedNameSpecifier::Create(Context, Prev, II);
-      break;
-    }
-
-    case NestedNameSpecifier::Namespace: {
-      NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
-      NNS = NestedNameSpecifier::Create(Context, Prev, NS);
-      break;
-    }
-
-    case NestedNameSpecifier::NamespaceAlias: {
-      NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
-      NNS = NestedNameSpecifier::Create(Context, Prev, Alias);
-      break;
-    }
-
-    case NestedNameSpecifier::TypeSpec:
-    case NestedNameSpecifier::TypeSpecWithTemplate: {
-      const Type *T = readType(F, Record, Idx).getTypePtrOrNull();
-      if (!T)
-        return 0;
-      
-      bool Template = Record[Idx++];
-      NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);
-      break;
-    }
-
-    case NestedNameSpecifier::Global: {
-      NNS = NestedNameSpecifier::GlobalSpecifier(Context);
-      // No associated value, and there can't be a prefix.
-      break;
-    }
-    }
-    Prev = NNS;
-  }
-  return NNS;
-}
-
-NestedNameSpecifierLoc
-ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, 
-                                      unsigned &Idx) {
-  unsigned N = Record[Idx++];
-  NestedNameSpecifierLocBuilder Builder;
-  for (unsigned I = 0; I != N; ++I) {
-    NestedNameSpecifier::SpecifierKind Kind
-      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
-    switch (Kind) {
-    case NestedNameSpecifier::Identifier: {
-      IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);      
-      SourceRange Range = ReadSourceRange(F, Record, Idx);
-      Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());
-      break;
-    }
-
-    case NestedNameSpecifier::Namespace: {
-      NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
-      SourceRange Range = ReadSourceRange(F, Record, Idx);
-      Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());
-      break;
-    }
-
-    case NestedNameSpecifier::NamespaceAlias: {
-      NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
-      SourceRange Range = ReadSourceRange(F, Record, Idx);
-      Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());
-      break;
-    }
-
-    case NestedNameSpecifier::TypeSpec:
-    case NestedNameSpecifier::TypeSpecWithTemplate: {
-      bool Template = Record[Idx++];
-      TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
-      if (!T)
-        return NestedNameSpecifierLoc();
-      SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
-
-      // FIXME: 'template' keyword location not saved anywhere, so we fake it.
-      Builder.Extend(Context, 
-                     Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),
-                     T->getTypeLoc(), ColonColonLoc);
-      break;
-    }
-
-    case NestedNameSpecifier::Global: {
-      SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
-      Builder.MakeGlobal(Context, ColonColonLoc);
-      break;
-    }
-    }
-  }
-  
-  return Builder.getWithLocInContext(Context);
-}
-
-SourceRange
-ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record,
-                           unsigned &Idx) {
-  SourceLocation beg = ReadSourceLocation(F, Record, Idx);
-  SourceLocation end = ReadSourceLocation(F, Record, Idx);
-  return SourceRange(beg, end);
-}
-
-/// \brief Read an integral value
-llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
-  unsigned BitWidth = Record[Idx++];
-  unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
-  llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
-  Idx += NumWords;
-  return Result;
-}
-
-/// \brief Read a signed integral value
-llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
-  bool isUnsigned = Record[Idx++];
-  return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
-}
-
-/// \brief Read a floating-point value
-llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
-  return llvm::APFloat(ReadAPInt(Record, Idx));
-}
-
-// \brief Read a string
-std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
-  unsigned Len = Record[Idx++];
-  std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
-  Idx += Len;
-  return Result;
-}
-
-VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, 
-                                         unsigned &Idx) {
-  unsigned Major = Record[Idx++];
-  unsigned Minor = Record[Idx++];
-  unsigned Subminor = Record[Idx++];
-  if (Minor == 0)
-    return VersionTuple(Major);
-  if (Subminor == 0)
-    return VersionTuple(Major, Minor - 1);
-  return VersionTuple(Major, Minor - 1, Subminor - 1);
-}
-
-CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, 
-                                          const RecordData &Record,
-                                          unsigned &Idx) {
-  CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx);
-  return CXXTemporary::Create(Context, Decl);
-}
-
-DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
-  return Diag(SourceLocation(), DiagID);
-}
-
-DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
-  return Diags.Report(Loc, DiagID);
-}
-
-/// \brief Retrieve the identifier table associated with the
-/// preprocessor.
-IdentifierTable &ASTReader::getIdentifierTable() {
-  return PP.getIdentifierTable();
-}
-
-/// \brief Record that the given ID maps to the given switch-case
-/// statement.
-void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
-  assert((*CurrSwitchCaseStmts)[ID] == 0 &&
-         "Already have a SwitchCase with this ID");
-  (*CurrSwitchCaseStmts)[ID] = SC;
-}
-
-/// \brief Retrieve the switch-case statement with the given ID.
-SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
-  assert((*CurrSwitchCaseStmts)[ID] != 0 && "No SwitchCase with this ID");
-  return (*CurrSwitchCaseStmts)[ID];
-}
-
-void ASTReader::ClearSwitchCaseIDs() {
-  CurrSwitchCaseStmts->clear();
-}
-
-void ASTReader::ReadComments() {
-  std::vector<RawComment *> Comments;
-  for (SmallVectorImpl<std::pair<llvm::BitstreamCursor,
-                                 serialization::ModuleFile *> >::iterator
-       I = CommentsCursors.begin(),
-       E = CommentsCursors.end();
-       I != E; ++I) {
-    llvm::BitstreamCursor &Cursor = I->first;
-    serialization::ModuleFile &F = *I->second;
-    SavedStreamPosition SavedPosition(Cursor);
-
-    RecordData Record;
-    while (true) {
-      unsigned Code = Cursor.ReadCode();
-      if (Code == llvm::bitc::END_BLOCK)
-        break;
-
-      if (Code == llvm::bitc::ENTER_SUBBLOCK) {
-        // No known subblocks, always skip them.
-        Cursor.ReadSubBlockID();
-        if (Cursor.SkipBlock()) {
-          Error("malformed block record in AST file");
-          return;
-        }
-        continue;
-      }
-
-      if (Code == llvm::bitc::DEFINE_ABBREV) {
-        Cursor.ReadAbbrevRecord();
-        continue;
-      }
-
-      // Read a record.
-      Record.clear();
-      switch ((CommentRecordTypes) Cursor.ReadRecord(Code, Record)) {
-      case COMMENTS_RAW_COMMENT: {
-        unsigned Idx = 0;
-        SourceRange SR = ReadSourceRange(F, Record, Idx);
-        RawComment::CommentKind Kind =
-            (RawComment::CommentKind) Record[Idx++];
-        bool IsTrailingComment = Record[Idx++];
-        bool IsAlmostTrailingComment = Record[Idx++];
-        Comments.push_back(new (Context) RawComment(SR, Kind,
-                                                    IsTrailingComment,
-                                                    IsAlmostTrailingComment));
-        break;
-      }
-      }
-    }
-  }
-  Context.Comments.addCommentsToFront(Comments);
-}
-
-void ASTReader::finishPendingActions() {
-  while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() ||
-         !PendingMacroIDs.empty()) {
-    // If any identifiers with corresponding top-level declarations have
-    // been loaded, load those declarations now.
-    while (!PendingIdentifierInfos.empty()) {
-      SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
-                              PendingIdentifierInfos.front().DeclIDs, true);
-      PendingIdentifierInfos.pop_front();
-    }
-  
-    // Load pending declaration chains.
-    for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
-      loadPendingDeclChain(PendingDeclChains[I]);
-      PendingDeclChainsKnown.erase(PendingDeclChains[I]);
-    }
-    PendingDeclChains.clear();
-
-    // Load any pending macro definitions.
-    for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) {
-      // FIXME: std::move here
-      SmallVector<MacroID, 2> GlobalIDs = PendingMacroIDs.begin()[I].second;
-      MacroInfo *Hint = 0;
-      for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx !=  NumIDs;
-           ++IDIdx) {
-        Hint = getMacro(GlobalIDs[IDIdx], Hint);
-      }
-    }
-    PendingMacroIDs.clear();
-  }
-  
-  // If we deserialized any C++ or Objective-C class definitions, any
-  // Objective-C protocol definitions, or any redeclarable templates, make sure
-  // that all redeclarations point to the definitions. Note that this can only 
-  // happen now, after the redeclaration chains have been fully wired.
-  for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
-                                           DEnd = PendingDefinitions.end();
-       D != DEnd; ++D) {
-    if (TagDecl *TD = dyn_cast<TagDecl>(*D)) {
-      if (const TagType *TagT = dyn_cast<TagType>(TD->TypeForDecl)) {
-        // Make sure that the TagType points at the definition.
-        const_cast<TagType*>(TagT)->decl = TD;
-      }
-      
-      if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {
-        for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),
-                                         REnd = RD->redecls_end();
-             R != REnd; ++R)
-          cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;
-        
-      }
-
-      continue;
-    }
-    
-    if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
-      // Make sure that the ObjCInterfaceType points at the definition.
-      const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))
-        ->Decl = ID;
-      
-      for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
-                                           REnd = ID->redecls_end();
-           R != REnd; ++R)
-        R->Data = ID->Data;
-      
-      continue;
-    }
-    
-    if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(*D)) {
-      for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
-                                          REnd = PD->redecls_end();
-           R != REnd; ++R)
-        R->Data = PD->Data;
-      
-      continue;
-    }
-    
-    RedeclarableTemplateDecl *RTD
-      = cast<RedeclarableTemplateDecl>(*D)->getCanonicalDecl();
-    for (RedeclarableTemplateDecl::redecl_iterator R = RTD->redecls_begin(),
-                                                REnd = RTD->redecls_end();
-         R != REnd; ++R)
-      R->Common = RTD->Common;
-  }
-  PendingDefinitions.clear();
-
-  // Load the bodies of any functions or methods we've encountered. We do
-  // this now (delayed) so that we can be sure that the declaration chains
-  // have been fully wired up.
-  for (PendingBodiesMap::iterator PB = PendingBodies.begin(),
-                               PBEnd = PendingBodies.end();
-       PB != PBEnd; ++PB) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
-      // FIXME: Check for =delete/=default?
-      // FIXME: Complain about ODR violations here?
-      if (!getContext().getLangOpts().Modules || !FD->hasBody())
-        FD->setLazyBody(PB->second);
-      continue;
-    }
-
-    ObjCMethodDecl *MD = cast<ObjCMethodDecl>(PB->first);
-    if (!getContext().getLangOpts().Modules || !MD->hasBody())
-      MD->setLazyBody(PB->second);
-  }
-  PendingBodies.clear();
-}
-
-void ASTReader::FinishedDeserializing() {
-  assert(NumCurrentElementsDeserializing &&
-         "FinishedDeserializing not paired with StartedDeserializing");
-  if (NumCurrentElementsDeserializing == 1) {
-    // We decrease NumCurrentElementsDeserializing only after pending actions
-    // are finished, to avoid recursively re-calling finishPendingActions().
-    finishPendingActions();
-  }
-  --NumCurrentElementsDeserializing;
-
-  if (NumCurrentElementsDeserializing == 0 &&
-      Consumer && !PassingDeclsToConsumer) {
-    // Guard variable to avoid recursively redoing the process of passing
-    // decls to consumer.
-    SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
-                                                     true);
-
-    while (!InterestingDecls.empty()) {
-      // We are not in recursive loading, so it's safe to pass the "interesting"
-      // decls to the consumer.
-      Decl *D = InterestingDecls.front();
-      InterestingDecls.pop_front();
-      PassInterestingDeclToConsumer(D);
-    }
-  }
-}
-
-ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
-                     StringRef isysroot, bool DisableValidation,
-                     bool AllowASTWithCompilerErrors)
-  : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
-    SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
-    Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
-    Consumer(0), ModuleMgr(PP.getFileManager()),
-    isysroot(isysroot), DisableValidation(DisableValidation),
-    AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), 
-    CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),
-    NumSLocEntriesRead(0), TotalNumSLocEntries(0), 
-    NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), 
-    TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0), 
-    NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0), 
-    NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), 
-    NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
-    TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
-    PassingDeclsToConsumer(false),
-    NumCXXBaseSpecifiersLoaded(0)
-{
-  SourceMgr.setExternalSLocEntrySource(this);
-}
-
-ASTReader::~ASTReader() {
-  for (DeclContextVisibleUpdatesPending::iterator
-           I = PendingVisibleUpdates.begin(),
-           E = PendingVisibleUpdates.end();
-       I != E; ++I) {
-    for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
-                                             F = I->second.end();
-         J != F; ++J)
-      delete J->first;
-  }
-}
+//===--- ASTReader.cpp - AST File Reader ------------------------*- C++ -*-===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+//  This file defines the ASTReader class, which reads AST files.

+//

+//===----------------------------------------------------------------------===//

+

+#include "clang/Serialization/ASTReader.h"

+#include "ASTCommon.h"

+#include "ASTReaderInternals.h"

+#include "clang/AST/ASTConsumer.h"

+#include "clang/AST/ASTContext.h"

+#include "clang/AST/DeclTemplate.h"

+#include "clang/AST/Expr.h"

+#include "clang/AST/ExprCXX.h"

+#include "clang/AST/NestedNameSpecifier.h"

+#include "clang/AST/Type.h"

+#include "clang/AST/TypeLocVisitor.h"

+#include "clang/Basic/FileManager.h"

+#include "clang/Basic/FileSystemStatCache.h"

+#include "clang/Basic/OnDiskHashTable.h"

+#include "clang/Basic/SourceManager.h"

+#include "clang/Basic/SourceManagerInternals.h"

+#include "clang/Basic/TargetInfo.h"

+#include "clang/Basic/TargetOptions.h"

+#include "clang/Basic/Version.h"

+#include "clang/Basic/VersionTuple.h"

+#include "clang/Lex/HeaderSearch.h"

+#include "clang/Lex/HeaderSearchOptions.h"

+#include "clang/Lex/MacroInfo.h"

+#include "clang/Lex/PreprocessingRecord.h"

+#include "clang/Lex/Preprocessor.h"

+#include "clang/Lex/PreprocessorOptions.h"

+#include "clang/Sema/Scope.h"

+#include "clang/Sema/Sema.h"

+#include "clang/Serialization/ASTDeserializationListener.h"

+#include "clang/Serialization/ModuleManager.h"

+#include "clang/Serialization/SerializationDiagnostic.h"

+#include "llvm/ADT/StringExtras.h"

+#include "llvm/Bitcode/BitstreamReader.h"

+#include "llvm/Support/ErrorHandling.h"

+#include "llvm/Support/FileSystem.h"

+#include "llvm/Support/MemoryBuffer.h"

+#include "llvm/Support/Path.h"

+#include "llvm/Support/SaveAndRestore.h"

+#include "llvm/Support/system_error.h"

+#include <algorithm>

+#include <cstdio>

+#include <iterator>

+

+using namespace clang;

+using namespace clang::serialization;

+using namespace clang::serialization::reader;

+

+//===----------------------------------------------------------------------===//

+// PCH validator implementation

+//===----------------------------------------------------------------------===//

+

+ASTReaderListener::~ASTReaderListener() {}

+

+/// \brief Compare the given set of language options against an existing set of

+/// language options.

+///

+/// \param Diags If non-NULL, diagnostics will be emitted via this engine.

+///

+/// \returns true if the languagae options mis-match, false otherwise.

+static bool checkLanguageOptions(const LangOptions &LangOpts,

+                                 const LangOptions &ExistingLangOpts,

+                                 DiagnosticsEngine *Diags) {

+#define LANGOPT(Name, Bits, Default, Description)                 \

+  if (ExistingLangOpts.Name != LangOpts.Name) {                   \

+    if (Diags)                                                    \

+      Diags->Report(diag::err_pch_langopt_mismatch)               \

+        << Description << LangOpts.Name << ExistingLangOpts.Name; \

+    return true;                                                  \

+  }

+

+#define VALUE_LANGOPT(Name, Bits, Default, Description)   \

+  if (ExistingLangOpts.Name != LangOpts.Name) {           \

+    if (Diags)                                            \

+      Diags->Report(diag::err_pch_langopt_value_mismatch) \

+        << Description;                                   \

+    return true;                                          \

+  }

+

+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)   \

+  if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) {  \

+    if (Diags)                                                 \

+      Diags->Report(diag::err_pch_langopt_value_mismatch)      \

+        << Description;                                        \

+    return true;                                               \

+  }

+

+#define BENIGN_LANGOPT(Name, Bits, Default, Description)

+#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)

+#include "clang/Basic/LangOptions.def"

+

+  if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {

+    if (Diags)

+      Diags->Report(diag::err_pch_langopt_value_mismatch)

+      << "target Objective-C runtime";

+    return true;

+  }

+

+  return false;

+}

+

+/// \brief Compare the given set of target options against an existing set of

+/// target options.

+///

+/// \param Diags If non-NULL, diagnostics will be emitted via this engine.

+///

+/// \returns true if the target options mis-match, false otherwise.

+static bool checkTargetOptions(const TargetOptions &TargetOpts,

+                               const TargetOptions &ExistingTargetOpts,

+                               DiagnosticsEngine *Diags) {

+#define CHECK_TARGET_OPT(Field, Name)                             \

+  if (TargetOpts.Field != ExistingTargetOpts.Field) {             \

+    if (Diags)                                                    \

+      Diags->Report(diag::err_pch_targetopt_mismatch)             \

+        << Name << TargetOpts.Field << ExistingTargetOpts.Field;  \

+    return true;                                                  \

+  }

+

+  CHECK_TARGET_OPT(Triple, "target");

+  CHECK_TARGET_OPT(CPU, "target CPU");

+  CHECK_TARGET_OPT(ABI, "target ABI");

+  CHECK_TARGET_OPT(CXXABI, "target C++ ABI");

+  CHECK_TARGET_OPT(LinkerVersion, "target linker version");

+#undef CHECK_TARGET_OPT

+

+  // Compare feature sets.

+  SmallVector<StringRef, 4> ExistingFeatures(

+                                             ExistingTargetOpts.FeaturesAsWritten.begin(),

+                                             ExistingTargetOpts.FeaturesAsWritten.end());

+  SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(),

+                                         TargetOpts.FeaturesAsWritten.end());

+  std::sort(ExistingFeatures.begin(), ExistingFeatures.end());

+  std::sort(ReadFeatures.begin(), ReadFeatures.end());

+

+  unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size();

+  unsigned ReadIdx = 0, ReadN = ReadFeatures.size();

+  while (ExistingIdx < ExistingN && ReadIdx < ReadN) {

+    if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) {

+      ++ExistingIdx;

+      ++ReadIdx;

+      continue;

+    }

+

+    if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) {

+      if (Diags)

+        Diags->Report(diag::err_pch_targetopt_feature_mismatch)

+          << false << ReadFeatures[ReadIdx];

+      return true;

+    }

+

+    if (Diags)

+      Diags->Report(diag::err_pch_targetopt_feature_mismatch)

+        << true << ExistingFeatures[ExistingIdx];

+    return true;

+  }

+

+  if (ExistingIdx < ExistingN) {

+    if (Diags)

+      Diags->Report(diag::err_pch_targetopt_feature_mismatch)

+        << true << ExistingFeatures[ExistingIdx];

+    return true;

+  }

+

+  if (ReadIdx < ReadN) {

+    if (Diags)

+      Diags->Report(diag::err_pch_targetopt_feature_mismatch)

+        << false << ReadFeatures[ReadIdx];

+    return true;

+  }

+

+  return false;

+}

+

+bool

+PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts,

+                                  bool Complain) {

+  const LangOptions &ExistingLangOpts = PP.getLangOpts();

+  return checkLanguageOptions(LangOpts, ExistingLangOpts,

+                              Complain? &Reader.Diags : 0);

+}

+

+bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,

+                                     bool Complain) {

+  const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();

+  return checkTargetOptions(TargetOpts, ExistingTargetOpts,

+                            Complain? &Reader.Diags : 0);

+}

+

+namespace {

+  typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >

+    MacroDefinitionsMap;

+}

+

+/// \brief Collect the macro definitions provided by the given preprocessor

+/// options.

+static void collectMacroDefinitions(const PreprocessorOptions &PPOpts,

+                                    MacroDefinitionsMap &Macros,

+                                    SmallVectorImpl<StringRef> *MacroNames = 0){

+  for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {

+    StringRef Macro = PPOpts.Macros[I].first;

+    bool IsUndef = PPOpts.Macros[I].second;

+

+    std::pair<StringRef, StringRef> MacroPair = Macro.split('=');

+    StringRef MacroName = MacroPair.first;

+    StringRef MacroBody = MacroPair.second;

+

+    // For an #undef'd macro, we only care about the name.

+    if (IsUndef) {

+      if (MacroNames && !Macros.count(MacroName))

+        MacroNames->push_back(MacroName);

+

+      Macros[MacroName] = std::make_pair("", true);

+      continue;

+    }

+

+    // For a #define'd macro, figure out the actual definition.

+    if (MacroName.size() == Macro.size())

+      MacroBody = "1";

+    else {

+      // Note: GCC drops anything following an end-of-line character.

+      StringRef::size_type End = MacroBody.find_first_of("\n\r");

+      MacroBody = MacroBody.substr(0, End);

+    }

+

+    if (MacroNames && !Macros.count(MacroName))

+      MacroNames->push_back(MacroName);

+    Macros[MacroName] = std::make_pair(MacroBody, false);

+  }

+}

+         

+/// \brief Check the preprocessor options deserialized from the control block

+/// against the preprocessor options in an existing preprocessor.

+///

+/// \param Diags If non-null, produce diagnostics for any mismatches incurred.

+static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,

+                                     const PreprocessorOptions &ExistingPPOpts,

+                                     DiagnosticsEngine *Diags,

+                                     FileManager &FileMgr,

+                                     std::string &SuggestedPredefines) {

+  // Check macro definitions.

+  MacroDefinitionsMap ASTFileMacros;

+  collectMacroDefinitions(PPOpts, ASTFileMacros);

+  MacroDefinitionsMap ExistingMacros;

+  SmallVector<StringRef, 4> ExistingMacroNames;

+  collectMacroDefinitions(ExistingPPOpts, ExistingMacros, &ExistingMacroNames);

+

+  for (unsigned I = 0, N = ExistingMacroNames.size(); I != N; ++I) {

+    // Dig out the macro definition in the existing preprocessor options.

+    StringRef MacroName = ExistingMacroNames[I];

+    std::pair<StringRef, bool> Existing = ExistingMacros[MacroName];

+

+    // Check whether we know anything about this macro name or not.

+    llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known

+      = ASTFileMacros.find(MacroName);

+    if (Known == ASTFileMacros.end()) {

+      // FIXME: Check whether this identifier was referenced anywhere in the

+      // AST file. If so, we should reject the AST file. Unfortunately, this

+      // information isn't in the control block. What shall we do about it?

+

+      if (Existing.second) {

+        SuggestedPredefines += "#undef ";

+        SuggestedPredefines += MacroName.str();

+        SuggestedPredefines += '\n';

+      } else {

+        SuggestedPredefines += "#define ";

+        SuggestedPredefines += MacroName.str();

+        SuggestedPredefines += ' ';

+        SuggestedPredefines += Existing.first.str();

+        SuggestedPredefines += '\n';

+      }

+      continue;

+    }

+

+    // If the macro was defined in one but undef'd in the other, we have a

+    // conflict.

+    if (Existing.second != Known->second.second) {

+      if (Diags) {

+        Diags->Report(diag::err_pch_macro_def_undef)

+          << MacroName << Known->second.second;

+      }

+      return true;

+    }

+

+    // If the macro was #undef'd in both, or if the macro bodies are identical,

+    // it's fine.

+    if (Existing.second || Existing.first == Known->second.first)

+      continue;

+

+    // The macro bodies differ; complain.

+    if (Diags) {

+      Diags->Report(diag::err_pch_macro_def_conflict)

+        << MacroName << Known->second.first << Existing.first;

+    }

+    return true;

+  }

+

+  // Check whether we're using predefines.

+  if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines) {

+    if (Diags) {

+      Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines;

+    }

+    return true;

+  }

+

+  // Compute the #include and #include_macros lines we need.

+  for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) {

+    StringRef File = ExistingPPOpts.Includes[I];

+    if (File == ExistingPPOpts.ImplicitPCHInclude)

+      continue;

+

+    if (std::find(PPOpts.Includes.begin(), PPOpts.Includes.end(), File)

+          != PPOpts.Includes.end())

+      continue;

+

+    SuggestedPredefines += "#include \"";

+    SuggestedPredefines +=

+      HeaderSearch::NormalizeDashIncludePath(File, FileMgr);

+    SuggestedPredefines += "\"\n";

+  }

+

+  for (unsigned I = 0, N = ExistingPPOpts.MacroIncludes.size(); I != N; ++I) {

+    StringRef File = ExistingPPOpts.MacroIncludes[I];

+    if (std::find(PPOpts.MacroIncludes.begin(), PPOpts.MacroIncludes.end(),

+                  File)

+        != PPOpts.MacroIncludes.end())

+      continue;

+

+    SuggestedPredefines += "#__include_macros \"";

+    SuggestedPredefines +=

+      HeaderSearch::NormalizeDashIncludePath(File, FileMgr);

+    SuggestedPredefines += "\"\n##\n";

+  }

+

+  return false;

+}

+

+bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,

+                                           bool Complain,

+                                           std::string &SuggestedPredefines) {

+  const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts();

+

+  return checkPreprocessorOptions(PPOpts, ExistingPPOpts,

+                                  Complain? &Reader.Diags : 0,

+                                  PP.getFileManager(),

+                                  SuggestedPredefines);

+}

+

+void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,

+                                      unsigned ID) {

+  PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID);

+  ++NumHeaderInfos;

+}

+

+void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) {

+  PP.setCounterValue(Value);

+}

+

+//===----------------------------------------------------------------------===//

+// AST reader implementation

+//===----------------------------------------------------------------------===//

+

+void

+ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {

+  DeserializationListener = Listener;

+}

+

+

+

+unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {

+  return serialization::ComputeHash(Sel);

+}

+

+

+std::pair<unsigned, unsigned>

+ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {

+  using namespace clang::io;

+  unsigned KeyLen = ReadUnalignedLE16(d);

+  unsigned DataLen = ReadUnalignedLE16(d);

+  return std::make_pair(KeyLen, DataLen);

+}

+

+ASTSelectorLookupTrait::internal_key_type 

+ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {

+  using namespace clang::io;

+  SelectorTable &SelTable = Reader.getContext().Selectors;

+  unsigned N = ReadUnalignedLE16(d);

+  IdentifierInfo *FirstII

+    = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));

+  if (N == 0)

+    return SelTable.getNullarySelector(FirstII);

+  else if (N == 1)

+    return SelTable.getUnarySelector(FirstII);

+

+  SmallVector<IdentifierInfo *, 16> Args;

+  Args.push_back(FirstII);

+  for (unsigned I = 1; I != N; ++I)

+    Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)));

+

+  return SelTable.getSelector(N, Args.data());

+}

+

+ASTSelectorLookupTrait::data_type 

+ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, 

+                                 unsigned DataLen) {

+  using namespace clang::io;

+

+  data_type Result;

+

+  Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));

+  unsigned NumInstanceMethods = ReadUnalignedLE16(d);

+  unsigned NumFactoryMethods = ReadUnalignedLE16(d);

+

+  // Load instance methods

+  for (unsigned I = 0; I != NumInstanceMethods; ++I) {

+    if (ObjCMethodDecl *Method

+          = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))

+      Result.Instance.push_back(Method);

+  }

+

+  // Load factory methods

+  for (unsigned I = 0; I != NumFactoryMethods; ++I) {

+    if (ObjCMethodDecl *Method

+          = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))

+      Result.Factory.push_back(Method);

+  }

+

+  return Result;

+}

+

+unsigned ASTIdentifierLookupTrait::ComputeHash(const internal_key_type& a) {

+  return llvm::HashString(StringRef(a.first, a.second));

+}

+

+std::pair<unsigned, unsigned>

+ASTIdentifierLookupTrait::ReadKeyDataLength(const unsigned char*& d) {

+  using namespace clang::io;

+  unsigned DataLen = ReadUnalignedLE16(d);

+  unsigned KeyLen = ReadUnalignedLE16(d);

+  return std::make_pair(KeyLen, DataLen);

+}

+

+std::pair<const char*, unsigned>

+ASTIdentifierLookupTrait::ReadKey(const unsigned char* d, unsigned n) {

+  assert(n >= 2 && d[n-1] == '\0');

+  return std::make_pair((const char*) d, n-1);

+}

+

+IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,

+                                                   const unsigned char* d,

+                                                   unsigned DataLen) {

+  using namespace clang::io;

+  unsigned RawID = ReadUnalignedLE32(d);

+  bool IsInteresting = RawID & 0x01;

+

+  // Wipe out the "is interesting" bit.

+  RawID = RawID >> 1;

+

+  IdentID ID = Reader.getGlobalIdentifierID(F, RawID);

+  if (!IsInteresting) {

+    // For uninteresting identifiers, just build the IdentifierInfo

+    // and associate it with the persistent ID.

+    IdentifierInfo *II = KnownII;

+    if (!II) {

+      II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));

+      KnownII = II;

+    }

+    Reader.SetIdentifierInfo(ID, II);

+    II->setIsFromAST();

+    Reader.markIdentifierUpToDate(II);    

+    return II;

+  }

+

+  unsigned ObjCOrBuiltinID = ReadUnalignedLE16(d);

+  unsigned Bits = ReadUnalignedLE16(d);

+  bool CPlusPlusOperatorKeyword = Bits & 0x01;

+  Bits >>= 1;

+  bool HasRevertedTokenIDToIdentifier = Bits & 0x01;

+  Bits >>= 1;

+  bool Poisoned = Bits & 0x01;

+  Bits >>= 1;

+  bool ExtensionToken = Bits & 0x01;

+  Bits >>= 1;

+  bool hadMacroDefinition = Bits & 0x01;

+  Bits >>= 1;

+

+  assert(Bits == 0 && "Extra bits in the identifier?");

+  DataLen -= 8;

+

+  // Build the IdentifierInfo itself and link the identifier ID with

+  // the new IdentifierInfo.

+  IdentifierInfo *II = KnownII;

+  if (!II) {

+    II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));

+    KnownII = II;

+  }

+  Reader.markIdentifierUpToDate(II);

+  II->setIsFromAST();

+

+  // Set or check the various bits in the IdentifierInfo structure.

+  // Token IDs are read-only.

+  if (HasRevertedTokenIDToIdentifier)

+    II->RevertTokenIDToIdentifier();

+  II->setObjCOrBuiltinID(ObjCOrBuiltinID);

+  assert(II->isExtensionToken() == ExtensionToken &&

+         "Incorrect extension token flag");

+  (void)ExtensionToken;

+  if (Poisoned)

+    II->setIsPoisoned(true);

+  assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&

+         "Incorrect C++ operator keyword flag");

+  (void)CPlusPlusOperatorKeyword;

+

+  // If this identifier is a macro, deserialize the macro

+  // definition.

+  if (hadMacroDefinition) {

+    SmallVector<MacroID, 4> MacroIDs;

+    while (uint32_t LocalID = ReadUnalignedLE32(d)) {

+      MacroIDs.push_back(Reader.getGlobalMacroID(F, LocalID));

+      DataLen -= 4;

+    }

+    DataLen -= 4;

+    Reader.setIdentifierIsMacro(II, MacroIDs);

+  }

+

+  Reader.SetIdentifierInfo(ID, II);

+

+  // Read all of the declarations visible at global scope with this

+  // name.

+  if (DataLen > 0) {

+    SmallVector<uint32_t, 4> DeclIDs;

+    for (; DataLen > 0; DataLen -= 4)

+      DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));

+    Reader.SetGloballyVisibleDecls(II, DeclIDs);

+  }

+

+  return II;

+}

+

+unsigned 

+ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {

+  llvm::FoldingSetNodeID ID;

+  ID.AddInteger(Key.Kind);

+

+  switch (Key.Kind) {

+  case DeclarationName::Identifier:

+  case DeclarationName::CXXLiteralOperatorName:

+    ID.AddString(((IdentifierInfo*)Key.Data)->getName());

+    break;

+  case DeclarationName::ObjCZeroArgSelector:

+  case DeclarationName::ObjCOneArgSelector:

+  case DeclarationName::ObjCMultiArgSelector:

+    ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));

+    break;

+  case DeclarationName::CXXOperatorName:

+    ID.AddInteger((OverloadedOperatorKind)Key.Data);

+    break;

+  case DeclarationName::CXXConstructorName:

+  case DeclarationName::CXXDestructorName:

+  case DeclarationName::CXXConversionFunctionName:

+  case DeclarationName::CXXUsingDirective:

+    break;

+  }

+

+  return ID.ComputeHash();

+}

+

+ASTDeclContextNameLookupTrait::internal_key_type 

+ASTDeclContextNameLookupTrait::GetInternalKey(

+                                          const external_key_type& Name) const {

+  DeclNameKey Key;

+  Key.Kind = Name.getNameKind();

+  switch (Name.getNameKind()) {

+  case DeclarationName::Identifier:

+    Key.Data = (uint64_t)Name.getAsIdentifierInfo();

+    break;

+  case DeclarationName::ObjCZeroArgSelector:

+  case DeclarationName::ObjCOneArgSelector:

+  case DeclarationName::ObjCMultiArgSelector:

+    Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();

+    break;

+  case DeclarationName::CXXOperatorName:

+    Key.Data = Name.getCXXOverloadedOperator();

+    break;

+  case DeclarationName::CXXLiteralOperatorName:

+    Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();

+    break;

+  case DeclarationName::CXXConstructorName:

+  case DeclarationName::CXXDestructorName:

+  case DeclarationName::CXXConversionFunctionName:

+  case DeclarationName::CXXUsingDirective:

+    Key.Data = 0;

+    break;

+  }

+

+  return Key;

+}

+

+std::pair<unsigned, unsigned>

+ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {

+  using namespace clang::io;

+  unsigned KeyLen = ReadUnalignedLE16(d);

+  unsigned DataLen = ReadUnalignedLE16(d);

+  return std::make_pair(KeyLen, DataLen);

+}

+

+ASTDeclContextNameLookupTrait::internal_key_type 

+ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) {

+  using namespace clang::io;

+

+  DeclNameKey Key;

+  Key.Kind = (DeclarationName::NameKind)*d++;

+  switch (Key.Kind) {

+  case DeclarationName::Identifier:

+    Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));

+    break;

+  case DeclarationName::ObjCZeroArgSelector:

+  case DeclarationName::ObjCOneArgSelector:

+  case DeclarationName::ObjCMultiArgSelector:

+    Key.Data =

+       (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d))

+                   .getAsOpaquePtr();

+    break;

+  case DeclarationName::CXXOperatorName:

+    Key.Data = *d++; // OverloadedOperatorKind

+    break;

+  case DeclarationName::CXXLiteralOperatorName:

+    Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));

+    break;

+  case DeclarationName::CXXConstructorName:

+  case DeclarationName::CXXDestructorName:

+  case DeclarationName::CXXConversionFunctionName:

+  case DeclarationName::CXXUsingDirective:

+    Key.Data = 0;

+    break;

+  }

+

+  return Key;

+}

+

+ASTDeclContextNameLookupTrait::data_type 

+ASTDeclContextNameLookupTrait::ReadData(internal_key_type, 

+                                        const unsigned char* d,

+                                        unsigned DataLen) {

+  using namespace clang::io;

+  unsigned NumDecls = ReadUnalignedLE16(d);

+  LE32DeclID *Start = (LE32DeclID *)d;

+  return std::make_pair(Start, Start + NumDecls);

+}

+

+bool ASTReader::ReadDeclContextStorage(ModuleFile &M,

+                                       llvm::BitstreamCursor &Cursor,

+                                   const std::pair<uint64_t, uint64_t> &Offsets,

+                                       DeclContextInfo &Info) {

+  SavedStreamPosition SavedPosition(Cursor);

+  // First the lexical decls.

+  if (Offsets.first != 0) {

+    Cursor.JumpToBit(Offsets.first);

+

+    RecordData Record;

+    const char *Blob;

+    unsigned BlobLen;

+    unsigned Code = Cursor.ReadCode();

+    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);

+    if (RecCode != DECL_CONTEXT_LEXICAL) {

+      Error("Expected lexical block");

+      return true;

+    }

+

+    Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob);

+    Info.NumLexicalDecls = BlobLen / sizeof(KindDeclIDPair);

+  }

+

+  // Now the lookup table.

+  if (Offsets.second != 0) {

+    Cursor.JumpToBit(Offsets.second);

+

+    RecordData Record;

+    const char *Blob;

+    unsigned BlobLen;

+    unsigned Code = Cursor.ReadCode();

+    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);

+    if (RecCode != DECL_CONTEXT_VISIBLE) {

+      Error("Expected visible lookup table block");

+      return true;

+    }

+    Info.NameLookupTableData

+      = ASTDeclContextNameLookupTable::Create(

+                    (const unsigned char *)Blob + Record[0],

+                    (const unsigned char *)Blob,

+                    ASTDeclContextNameLookupTrait(*this, M));

+  }

+

+  return false;

+}

+

+void ASTReader::Error(StringRef Msg) {

+  Error(diag::err_fe_pch_malformed, Msg);

+}

+

+void ASTReader::Error(unsigned DiagID,

+                      StringRef Arg1, StringRef Arg2) {

+  if (Diags.isDiagnosticInFlight())

+    Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);

+  else

+    Diag(DiagID) << Arg1 << Arg2;

+}

+

+//===----------------------------------------------------------------------===//

+// Source Manager Deserialization

+//===----------------------------------------------------------------------===//

+

+/// \brief Read the line table in the source manager block.

+/// \returns true if there was an error.

+bool ASTReader::ParseLineTable(ModuleFile &F,

+                               SmallVectorImpl<uint64_t> &Record) {

+  unsigned Idx = 0;

+  LineTableInfo &LineTable = SourceMgr.getLineTable();

+

+  // Parse the file names

+  std::map<int, int> FileIDs;

+  for (int I = 0, N = Record[Idx++]; I != N; ++I) {

+    // Extract the file name

+    unsigned FilenameLen = Record[Idx++];

+    std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);

+    Idx += FilenameLen;

+    MaybeAddSystemRootToFilename(F, Filename);

+    FileIDs[I] = LineTable.getLineTableFilenameID(Filename);

+  }

+

+  // Parse the line entries

+  std::vector<LineEntry> Entries;

+  while (Idx < Record.size()) {

+    int FID = Record[Idx++];

+    assert(FID >= 0 && "Serialized line entries for non-local file.");

+    // Remap FileID from 1-based old view.

+    FID += F.SLocEntryBaseID - 1;

+

+    // Extract the line entries

+    unsigned NumEntries = Record[Idx++];

+    assert(NumEntries && "Numentries is 00000");

+    Entries.clear();

+    Entries.reserve(NumEntries);

+    for (unsigned I = 0; I != NumEntries; ++I) {

+      unsigned FileOffset = Record[Idx++];

+      unsigned LineNo = Record[Idx++];

+      int FilenameID = FileIDs[Record[Idx++]];

+      SrcMgr::CharacteristicKind FileKind

+        = (SrcMgr::CharacteristicKind)Record[Idx++];

+      unsigned IncludeOffset = Record[Idx++];

+      Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,

+                                       FileKind, IncludeOffset));

+    }

+    LineTable.AddEntry(FileID::get(FID), Entries);

+  }

+

+  return false;

+}

+

+/// \brief Read a source manager block

+bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {

+  using namespace SrcMgr;

+

+  llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;

+

+  // Set the source-location entry cursor to the current position in

+  // the stream. This cursor will be used to read the contents of the

+  // source manager block initially, and then lazily read

+  // source-location entries as needed.

+  SLocEntryCursor = F.Stream;

+

+  // The stream itself is going to skip over the source manager block.

+  if (F.Stream.SkipBlock()) {

+    Error("malformed block record in AST file");

+    return true;

+  }

+

+  // Enter the source manager block.

+  if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {

+    Error("malformed source manager block record in AST file");

+    return true;

+  }

+

+  RecordData Record;

+  while (true) {

+    unsigned Code = SLocEntryCursor.ReadCode();

+    if (Code == llvm::bitc::END_BLOCK) {

+      if (SLocEntryCursor.ReadBlockEnd()) {

+        Error("error at end of Source Manager block in AST file");

+        return true;

+      }

+      return false;

+    }

+

+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+      // No known subblocks, always skip them.

+      SLocEntryCursor.ReadSubBlockID();

+      if (SLocEntryCursor.SkipBlock()) {

+        Error("malformed block record in AST file");

+        return true;

+      }

+      continue;

+    }

+

+    if (Code == llvm::bitc::DEFINE_ABBREV) {

+      SLocEntryCursor.ReadAbbrevRecord();

+      continue;

+    }

+

+    // Read a record.

+    const char *BlobStart;

+    unsigned BlobLen;

+    Record.clear();

+    switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {

+    default:  // Default behavior: ignore.

+      break;

+

+    case SM_SLOC_FILE_ENTRY:

+    case SM_SLOC_BUFFER_ENTRY:

+    case SM_SLOC_EXPANSION_ENTRY:

+      // Once we hit one of the source location entries, we're done.

+      return false;

+    }

+  }

+}

+

+/// \brief If a header file is not found at the path that we expect it to be

+/// and the PCH file was moved from its original location, try to resolve the

+/// file by assuming that header+PCH were moved together and the header is in

+/// the same place relative to the PCH.

+static std::string

+resolveFileRelativeToOriginalDir(const std::string &Filename,

+                                 const std::string &OriginalDir,

+                                 const std::string &CurrDir) {

+  assert(OriginalDir != CurrDir &&

+         "No point trying to resolve the file if the PCH dir didn't change");

+  using namespace llvm::sys;

+  SmallString<128> filePath(Filename);

+  fs::make_absolute(filePath);

+  assert(path::is_absolute(OriginalDir));

+  SmallString<128> currPCHPath(CurrDir);

+

+  path::const_iterator fileDirI = path::begin(path::parent_path(filePath)),

+                       fileDirE = path::end(path::parent_path(filePath));

+  path::const_iterator origDirI = path::begin(OriginalDir),

+                       origDirE = path::end(OriginalDir);

+  // Skip the common path components from filePath and OriginalDir.

+  while (fileDirI != fileDirE && origDirI != origDirE &&

+         *fileDirI == *origDirI) {

+    ++fileDirI;

+    ++origDirI;

+  }

+  for (; origDirI != origDirE; ++origDirI)

+    path::append(currPCHPath, "..");

+  path::append(currPCHPath, fileDirI, fileDirE);

+  path::append(currPCHPath, path::filename(Filename));

+  return currPCHPath.str();

+}

+

+bool ASTReader::ReadSLocEntry(int ID) {

+  if (ID == 0)

+    return false;

+

+  if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {

+    Error("source location entry ID out-of-range for AST file");

+    return true;

+  }

+

+  ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second;

+  F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);

+  llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;

+  unsigned BaseOffset = F->SLocEntryBaseOffset;

+

+  ++NumSLocEntriesRead;

+  unsigned Code = SLocEntryCursor.ReadCode();

+  if (Code == llvm::bitc::END_BLOCK ||

+      Code == llvm::bitc::ENTER_SUBBLOCK ||

+      Code == llvm::bitc::DEFINE_ABBREV) {

+    Error("incorrectly-formatted source location entry in AST file");

+    return true;

+  }

+

+  RecordData Record;

+  const char *BlobStart;

+  unsigned BlobLen;

+  switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {

+  default:

+    Error("incorrectly-formatted source location entry in AST file");

+    return true;

+

+  case SM_SLOC_FILE_ENTRY: {

+    // We will detect whether a file changed and return 'Failure' for it, but

+    // we will also try to fail gracefully by setting up the SLocEntry.

+    unsigned InputID = Record[4];

+    InputFile IF = getInputFile(*F, InputID);

+    const FileEntry *File = IF.getPointer();

+    bool OverriddenBuffer = IF.getInt();

+

+    if (!IF.getPointer())

+      return true;

+

+    SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);

+    if (IncludeLoc.isInvalid() && F->Kind != MK_MainFile) {

+      // This is the module's main file.

+      IncludeLoc = getImportLocation(F);

+    }

+    SrcMgr::CharacteristicKind

+      FileCharacter = (SrcMgr::CharacteristicKind)Record[2];

+    FileID FID = SourceMgr.createFileID(File, IncludeLoc, FileCharacter,

+                                        ID, BaseOffset + Record[0]);

+    SrcMgr::FileInfo &FileInfo =

+          const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());

+    FileInfo.NumCreatedFIDs = Record[5];

+    if (Record[3])

+      FileInfo.setHasLineDirectives();

+

+    const DeclID *FirstDecl = F->FileSortedDecls + Record[6];

+    unsigned NumFileDecls = Record[7];

+    if (NumFileDecls) {

+      assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");

+      FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl,

+                                                             NumFileDecls));

+    }

+    

+    const SrcMgr::ContentCache *ContentCache

+      = SourceMgr.getOrCreateContentCache(File,

+                              /*isSystemFile=*/FileCharacter != SrcMgr::C_User);

+    if (OverriddenBuffer && !ContentCache->BufferOverridden &&

+        ContentCache->ContentsEntry == ContentCache->OrigEntry) {

+      unsigned Code = SLocEntryCursor.ReadCode();

+      Record.clear();

+      unsigned RecCode

+        = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);

+      

+      if (RecCode != SM_SLOC_BUFFER_BLOB) {

+        Error("AST record has invalid code");

+        return true;

+      }

+      

+      llvm::MemoryBuffer *Buffer

+        = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),

+                                           File->getName());

+      SourceMgr.overrideFileContents(File, Buffer);

+    }

+

+    break;

+  }

+

+  case SM_SLOC_BUFFER_ENTRY: {

+    const char *Name = BlobStart;

+    unsigned Offset = Record[0];

+    SrcMgr::CharacteristicKind

+      FileCharacter = (SrcMgr::CharacteristicKind)Record[2];

+    SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);

+    if (IncludeLoc.isInvalid() && F->Kind == MK_Module) {

+      IncludeLoc = getImportLocation(F);

+    }

+    unsigned Code = SLocEntryCursor.ReadCode();

+    Record.clear();

+    unsigned RecCode

+      = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);

+

+    if (RecCode != SM_SLOC_BUFFER_BLOB) {

+      Error("AST record has invalid code");

+      return true;

+    }

+

+    llvm::MemoryBuffer *Buffer

+      = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),

+                                         Name);

+    SourceMgr.createFileIDForMemBuffer(Buffer, FileCharacter, ID,

+                                       BaseOffset + Offset, IncludeLoc);

+    break;

+  }

+

+  case SM_SLOC_EXPANSION_ENTRY: {

+    SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1]);

+    SourceMgr.createExpansionLoc(SpellingLoc,

+                                     ReadSourceLocation(*F, Record[2]),

+                                     ReadSourceLocation(*F, Record[3]),

+                                     Record[4],

+                                     ID,

+                                     BaseOffset + Record[0]);

+    break;

+  }

+  }

+

+  return false;

+}

+

+std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {

+  if (ID == 0)

+    return std::make_pair(SourceLocation(), "");

+

+  if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {

+    Error("source location entry ID out-of-range for AST file");

+    return std::make_pair(SourceLocation(), "");

+  }

+

+  // Find which module file this entry lands in.

+  ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second;

+  if (M->Kind != MK_Module)

+    return std::make_pair(SourceLocation(), "");

+

+  // FIXME: Can we map this down to a particular submodule? That would be

+  // ideal.

+  return std::make_pair(M->ImportLoc, llvm::sys::path::stem(M->FileName));

+}

+

+/// \brief Find the location where the module F is imported.

+SourceLocation ASTReader::getImportLocation(ModuleFile *F) {

+  if (F->ImportLoc.isValid())

+    return F->ImportLoc;

+  

+  // Otherwise we have a PCH. It's considered to be "imported" at the first

+  // location of its includer.

+  if (F->ImportedBy.empty() || !F->ImportedBy[0]) {

+    // Main file is the importer. We assume that it is the first entry in the

+    // entry table. We can't ask the manager, because at the time of PCH loading

+    // the main file entry doesn't exist yet.

+    // The very first entry is the invalid instantiation loc, which takes up

+    // offsets 0 and 1.

+    return SourceLocation::getFromRawEncoding(2U);

+  }

+  //return F->Loaders[0]->FirstLoc;

+  return F->ImportedBy[0]->FirstLoc;

+}

+

+/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the

+/// specified cursor.  Read the abbreviations that are at the top of the block

+/// and then leave the cursor pointing into the block.

+bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,

+                                 unsigned BlockID) {

+  if (Cursor.EnterSubBlock(BlockID)) {

+    Error("malformed block record in AST file");

+    return Failure;

+  }

+

+  while (true) {

+    uint64_t Offset = Cursor.GetCurrentBitNo();

+    unsigned Code = Cursor.ReadCode();

+

+    // We expect all abbrevs to be at the start of the block.

+    if (Code != llvm::bitc::DEFINE_ABBREV) {

+      Cursor.JumpToBit(Offset);

+      return false;

+    }

+    Cursor.ReadAbbrevRecord();

+  }

+}

+

+void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset,

+                                MacroInfo *Hint) {

+  llvm::BitstreamCursor &Stream = F.MacroCursor;

+

+  // Keep track of where we are in the stream, then jump back there

+  // after reading this macro.

+  SavedStreamPosition SavedPosition(Stream);

+

+  Stream.JumpToBit(Offset);

+  RecordData Record;

+  SmallVector<IdentifierInfo*, 16> MacroArgs;

+  MacroInfo *Macro = 0;

+

+  // RAII object to add the loaded macro information once we're done

+  // adding tokens.

+  struct AddLoadedMacroInfoRAII {

+    Preprocessor &PP;

+    MacroInfo *Hint;

+    MacroInfo *MI;

+    IdentifierInfo *II;

+

+    AddLoadedMacroInfoRAII(Preprocessor &PP, MacroInfo *Hint)

+      : PP(PP), Hint(Hint), MI(), II() { }

+    ~AddLoadedMacroInfoRAII( ) {

+      if (MI) {

+        // Finally, install the macro.

+        PP.addLoadedMacroInfo(II, MI, Hint);

+      }

+    }

+  } AddLoadedMacroInfo(PP, Hint);

+

+  while (true) {

+    unsigned Code = Stream.ReadCode();

+    switch (Code) {

+    case llvm::bitc::END_BLOCK:

+      return;

+

+    case llvm::bitc::ENTER_SUBBLOCK:

+      // No known subblocks, always skip them.

+      Stream.ReadSubBlockID();

+      if (Stream.SkipBlock()) {

+        Error("malformed block record in AST file");

+        return;

+      }

+      continue;

+

+    case llvm::bitc::DEFINE_ABBREV:

+      Stream.ReadAbbrevRecord();

+      continue;

+    default: break;

+    }

+

+    // Read a record.

+    const char *BlobStart = 0;

+    unsigned BlobLen = 0;

+    Record.clear();

+    PreprocessorRecordTypes RecType =

+      (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record, BlobStart,

+                                                 BlobLen);

+    switch (RecType) {

+    case PP_MACRO_OBJECT_LIKE:

+    case PP_MACRO_FUNCTION_LIKE: {

+      // If we already have a macro, that means that we've hit the end

+      // of the definition of the macro we were looking for. We're

+      // done.

+      if (Macro)

+        return;

+

+      IdentifierInfo *II = getLocalIdentifier(F, Record[0]);

+      if (II == 0) {

+        Error("macro must have a name in AST file");

+        return;

+      }

+

+      unsigned GlobalID = getGlobalMacroID(F, Record[1]);

+

+      // If this macro has already been loaded, don't do so again.

+      if (MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS])

+        return;

+

+      SubmoduleID GlobalSubmoduleID = getGlobalSubmoduleID(F, Record[2]);

+      unsigned NextIndex = 3;

+      SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);

+      MacroInfo *MI = PP.AllocateMacroInfo(Loc);

+

+      // Record this macro.

+      MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS] = MI;

+

+      SourceLocation UndefLoc = ReadSourceLocation(F, Record, NextIndex);

+      if (UndefLoc.isValid())

+        MI->setUndefLoc(UndefLoc);

+

+      MI->setIsUsed(Record[NextIndex++]);

+      MI->setIsFromAST();

+

+      bool IsPublic = Record[NextIndex++];

+      MI->setVisibility(IsPublic, ReadSourceLocation(F, Record, NextIndex));

+

+      if (RecType == PP_MACRO_FUNCTION_LIKE) {

+        // Decode function-like macro info.

+        bool isC99VarArgs = Record[NextIndex++];

+        bool isGNUVarArgs = Record[NextIndex++];

+        bool hasCommaPasting = Record[NextIndex++];

+        MacroArgs.clear();

+        unsigned NumArgs = Record[NextIndex++];

+        for (unsigned i = 0; i != NumArgs; ++i)

+          MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++]));

+

+        // Install function-like macro info.

+        MI->setIsFunctionLike();

+        if (isC99VarArgs) MI->setIsC99Varargs();

+        if (isGNUVarArgs) MI->setIsGNUVarargs();

+        if (hasCommaPasting) MI->setHasCommaPasting();

+        MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),

+                            PP.getPreprocessorAllocator());

+      }

+

+      if (DeserializationListener)

+        DeserializationListener->MacroRead(GlobalID, MI);

+

+      // If an update record marked this as undefined, do so now.

+      // FIXME: Only if the submodule this update came from is visible?

+      MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID);

+      if (Update != MacroUpdates.end()) {

+        if (MI->getUndefLoc().isInvalid()) {

+          for (unsigned I = 0, N = Update->second.size(); I != N; ++I) {

+            bool Hidden = false;

+            if (unsigned SubmoduleID = Update->second[I].first) {

+              if (Module *Owner = getSubmodule(SubmoduleID)) {

+                if (Owner->NameVisibility == Module::Hidden) {

+                  // Note that this #undef is hidden.

+                  Hidden = true;

+

+                  // Record this hiding for later.

+                  HiddenNamesMap[Owner].push_back(

+                    HiddenName(II, MI, Update->second[I].second.UndefLoc));

+                }

+              }

+            }

+

+            if (!Hidden) {

+              MI->setUndefLoc(Update->second[I].second.UndefLoc);

+              if (PPMutationListener *Listener = PP.getPPMutationListener())

+                Listener->UndefinedMacro(MI);

+              break;

+            }

+          }

+        }

+        MacroUpdates.erase(Update);

+      }

+

+      // Determine whether this macro definition is visible.

+      bool Hidden = !MI->isPublic();

+      if (!Hidden && GlobalSubmoduleID) {

+        if (Module *Owner = getSubmodule(GlobalSubmoduleID)) {

+          if (Owner->NameVisibility == Module::Hidden) {

+            // The owning module is not visible, and this macro definition

+            // should not be, either.

+            Hidden = true;

+

+            // Note that this macro definition was hidden because its owning

+            // module is not yet visible.

+            HiddenNamesMap[Owner].push_back(HiddenName(II, MI));

+          }

+        }

+      }

+      MI->setHidden(Hidden);

+

+      // Make sure we install the macro once we're done.

+      AddLoadedMacroInfo.MI = MI;

+      AddLoadedMacroInfo.II = II;

+

+      // Remember that we saw this macro last so that we add the tokens that

+      // form its body to it.

+      Macro = MI;

+

+      if (NextIndex + 1 == Record.size() && PP.getPreprocessingRecord() &&

+          Record[NextIndex]) {

+        // We have a macro definition. Register the association

+        PreprocessedEntityID

+            GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]);

+        PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();

+        PPRec.RegisterMacroDefinition(Macro,

+                            PPRec.getPPEntityID(GlobalID-1, /*isLoaded=*/true));

+      }

+

+      ++NumMacrosRead;

+      break;

+    }

+

+    case PP_TOKEN: {

+      // If we see a TOKEN before a PP_MACRO_*, then the file is

+      // erroneous, just pretend we didn't see this.

+      if (Macro == 0) break;

+

+      Token Tok;

+      Tok.startToken();

+      Tok.setLocation(ReadSourceLocation(F, Record[0]));

+      Tok.setLength(Record[1]);

+      if (IdentifierInfo *II = getLocalIdentifier(F, Record[2]))

+        Tok.setIdentifierInfo(II);

+      Tok.setKind((tok::TokenKind)Record[3]);

+      Tok.setFlag((Token::TokenFlags)Record[4]);

+      Macro->AddTokenToBody(Tok);

+      break;

+    }

+    }

+  }

+}

+

+PreprocessedEntityID 

+ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const {

+  ContinuousRangeMap<uint32_t, int, 2>::const_iterator 

+    I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);

+  assert(I != M.PreprocessedEntityRemap.end() 

+         && "Invalid index into preprocessed entity index remap");

+  

+  return LocalID + I->second;

+}

+

+unsigned HeaderFileInfoTrait::ComputeHash(const char *path) {

+  return llvm::HashString(llvm::sys::path::filename(path));

+}

+    

+HeaderFileInfoTrait::internal_key_type 

+HeaderFileInfoTrait::GetInternalKey(const char *path) { return path; }

+    

+bool HeaderFileInfoTrait::EqualKey(internal_key_type a, internal_key_type b) {

+  if (strcmp(a, b) == 0)

+    return true;

+  

+  if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b))

+    return false;

+

+  // Determine whether the actual files are equivalent.

+  bool Result = false;

+  if (llvm::sys::fs::equivalent(a, b, Result))

+    return false;

+  

+  return Result;

+}

+    

+std::pair<unsigned, unsigned>

+HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {

+  unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);

+  unsigned DataLen = (unsigned) *d++;

+  return std::make_pair(KeyLen + 1, DataLen);

+}

+    

+HeaderFileInfoTrait::data_type 

+HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d,

+                              unsigned DataLen) {

+  const unsigned char *End = d + DataLen;

+  using namespace clang::io;

+  HeaderFileInfo HFI;

+  unsigned Flags = *d++;

+  HFI.isImport = (Flags >> 5) & 0x01;

+  HFI.isPragmaOnce = (Flags >> 4) & 0x01;

+  HFI.DirInfo = (Flags >> 2) & 0x03;

+  HFI.Resolved = (Flags >> 1) & 0x01;

+  HFI.IndexHeaderMapHeader = Flags & 0x01;

+  HFI.NumIncludes = ReadUnalignedLE16(d);

+  HFI.ControllingMacroID = Reader.getGlobalIdentifierID(M, 

+                                                        ReadUnalignedLE32(d));

+  if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) {

+    // The framework offset is 1 greater than the actual offset, 

+    // since 0 is used as an indicator for "no framework name".

+    StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);

+    HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);

+  }

+  

+  assert(End == d && "Wrong data length in HeaderFileInfo deserialization");

+  (void)End;

+        

+  // This HeaderFileInfo was externally loaded.

+  HFI.External = true;

+  return HFI;

+}

+

+void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ArrayRef<MacroID> IDs){

+  II->setHadMacroDefinition(true);

+  assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");

+  PendingMacroIDs[II].append(IDs.begin(), IDs.end());

+}

+

+void ASTReader::ReadDefinedMacros() {

+  // Note that we are loading defined macros.

+  Deserializing Macros(this);

+

+  for (ModuleReverseIterator I = ModuleMgr.rbegin(),

+      E = ModuleMgr.rend(); I != E; ++I) {

+    llvm::BitstreamCursor &MacroCursor = (*I)->MacroCursor;

+

+    // If there was no preprocessor block, skip this file.

+    if (!MacroCursor.getBitStreamReader())

+      continue;

+

+    llvm::BitstreamCursor Cursor = MacroCursor;

+    Cursor.JumpToBit((*I)->MacroStartOffset);

+

+    RecordData Record;

+    while (true) {

+      unsigned Code = Cursor.ReadCode();

+      if (Code == llvm::bitc::END_BLOCK)

+        break;

+

+      if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+        // No known subblocks, always skip them.

+        Cursor.ReadSubBlockID();

+        if (Cursor.SkipBlock()) {

+          Error("malformed block record in AST file");

+          return;

+        }

+        continue;

+      }

+

+      if (Code == llvm::bitc::DEFINE_ABBREV) {

+        Cursor.ReadAbbrevRecord();

+        continue;

+      }

+

+      // Read a record.

+      const char *BlobStart;

+      unsigned BlobLen;

+      Record.clear();

+      switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {

+      default:  // Default behavior: ignore.

+        break;

+

+      case PP_MACRO_OBJECT_LIKE:

+      case PP_MACRO_FUNCTION_LIKE:

+        getLocalIdentifier(**I, Record[0]);

+        break;

+

+      case PP_TOKEN:

+        // Ignore tokens.

+        break;

+      }

+    }

+  }

+}

+

+namespace {

+  /// \brief Visitor class used to look up identifirs in an AST file.

+  class IdentifierLookupVisitor {

+    StringRef Name;

+    unsigned PriorGeneration;

+    IdentifierInfo *Found;

+  public:

+    IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration) 

+      : Name(Name), PriorGeneration(PriorGeneration), Found() { }

+    

+    static bool visit(ModuleFile &M, void *UserData) {

+      IdentifierLookupVisitor *This

+        = static_cast<IdentifierLookupVisitor *>(UserData);

+      

+      // If we've already searched this module file, skip it now.

+      if (M.Generation <= This->PriorGeneration)

+        return true;

+      

+      ASTIdentifierLookupTable *IdTable

+        = (ASTIdentifierLookupTable *)M.IdentifierLookupTable;

+      if (!IdTable)

+        return false;

+      

+      ASTIdentifierLookupTrait Trait(IdTable->getInfoObj().getReader(),

+                                     M, This->Found);

+                                     

+      std::pair<const char*, unsigned> Key(This->Name.begin(), 

+                                           This->Name.size());

+      ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Trait);

+      if (Pos == IdTable->end())

+        return false;

+      

+      // Dereferencing the iterator has the effect of building the

+      // IdentifierInfo node and populating it with the various

+      // declarations it needs.

+      This->Found = *Pos;

+      return true;

+    }

+    

+    // \brief Retrieve the identifier info found within the module

+    // files.

+    IdentifierInfo *getIdentifierInfo() const { return Found; }

+  };

+}

+

+void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {

+  // Note that we are loading an identifier.

+  Deserializing AnIdentifier(this);

+

+  unsigned PriorGeneration = 0;

+  if (getContext().getLangOpts().Modules)

+    PriorGeneration = IdentifierGeneration[&II];

+  

+  IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration);

+  ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);

+  markIdentifierUpToDate(&II);

+}

+

+void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {

+  if (!II)

+    return;

+  

+  II->setOutOfDate(false);

+

+  // Update the generation for this identifier.

+  if (getContext().getLangOpts().Modules)

+    IdentifierGeneration[II] = CurrentGeneration;

+}

+

+llvm::PointerIntPair<const FileEntry *, 1, bool> 

+ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {

+  // If this ID is bogus, just return an empty input file.

+  if (ID == 0 || ID > F.InputFilesLoaded.size())

+    return InputFile();

+

+  // If we've already loaded this input file, return it.

+  if (F.InputFilesLoaded[ID-1].getPointer())

+    return F.InputFilesLoaded[ID-1];

+

+  // Go find this input file.

+  llvm::BitstreamCursor &Cursor = F.InputFilesCursor;

+  SavedStreamPosition SavedPosition(Cursor);

+  Cursor.JumpToBit(F.InputFileOffsets[ID-1]);

+  

+  unsigned Code = Cursor.ReadCode();

+  RecordData Record;

+  const char *BlobStart = 0;

+  unsigned BlobLen = 0;

+  switch ((InputFileRecordTypes)Cursor.ReadRecord(Code, Record,

+                                                  &BlobStart, &BlobLen)) {

+  case INPUT_FILE: {

+    unsigned StoredID = Record[0];

+    assert(ID == StoredID && "Bogus stored ID or offset");

+    (void)StoredID;

+    off_t StoredSize = (off_t)Record[1];

+    time_t StoredTime = (time_t)Record[2];

+    bool Overridden = (bool)Record[3];

+    

+    // Get the file entry for this input file.

+    StringRef OrigFilename(BlobStart, BlobLen);

+    std::string Filename = OrigFilename;

+    MaybeAddSystemRootToFilename(F, Filename);

+    const FileEntry *File 

+      = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)

+                  : FileMgr.getFile(Filename, /*OpenFile=*/false);

+    

+    // If we didn't find the file, resolve it relative to the

+    // original directory from which this AST file was created.

+    if (File == 0 && !F.OriginalDir.empty() && !CurrentDir.empty() &&

+        F.OriginalDir != CurrentDir) {

+      std::string Resolved = resolveFileRelativeToOriginalDir(Filename,

+                                                              F.OriginalDir,

+                                                              CurrentDir);

+      if (!Resolved.empty())

+        File = FileMgr.getFile(Resolved);

+    }

+    

+    // For an overridden file, create a virtual file with the stored

+    // size/timestamp.

+    if (Overridden && File == 0) {

+      File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);

+    }

+    

+    if (File == 0) {

+      if (Complain) {

+        std::string ErrorStr = "could not find file '";

+        ErrorStr += Filename;

+        ErrorStr += "' referenced by AST file";

+        Error(ErrorStr.c_str());

+      }

+      return InputFile();

+    }

+    

+    // Note that we've loaded this input file.

+    F.InputFilesLoaded[ID-1] = InputFile(File, Overridden);

+    

+    // Check if there was a request to override the contents of the file

+    // that was part of the precompiled header. Overridding such a file

+    // can lead to problems when lexing using the source locations from the

+    // PCH.

+    SourceManager &SM = getSourceManager();

+    if (!Overridden && SM.isFileOverridden(File)) {

+      Error(diag::err_fe_pch_file_overridden, Filename);

+      // After emitting the diagnostic, recover by disabling the override so

+      // that the original file will be used.

+      SM.disableFileContentsOverride(File);

+      // The FileEntry is a virtual file entry with the size of the contents

+      // that would override the original contents. Set it to the original's

+      // size/time.

+      FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),

+                              StoredSize, StoredTime);

+    }

+

+    // For an overridden file, there is nothing to validate.

+    if (Overridden)

+      return InputFile(File, Overridden);

+

+    if ((StoredSize != File->getSize()

+#if !defined(LLVM_ON_WIN32)

+         // In our regression testing, the Windows file system seems to

+         // have inconsistent modification times that sometimes

+         // erroneously trigger this error-handling path.

+         || StoredTime != File->getModificationTime()

+#endif

+         )) {

+      if (Complain)

+        Error(diag::err_fe_pch_file_modified, Filename);

+      

+      return InputFile();

+    }

+

+    return InputFile(File, Overridden);

+  }

+  }

+

+  return InputFile();

+}

+

+const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {

+  ModuleFile &M = ModuleMgr.getPrimaryModule();

+  std::string Filename = filenameStrRef;

+  MaybeAddSystemRootToFilename(M, Filename);

+  const FileEntry *File = FileMgr.getFile(Filename);

+  if (File == 0 && !M.OriginalDir.empty() && !CurrentDir.empty() &&

+      M.OriginalDir != CurrentDir) {

+    std::string resolved = resolveFileRelativeToOriginalDir(Filename,

+                                                            M.OriginalDir,

+                                                            CurrentDir);

+    if (!resolved.empty())

+      File = FileMgr.getFile(resolved);

+  }

+

+  return File;

+}

+

+/// \brief If we are loading a relocatable PCH file, and the filename is

+/// not an absolute path, add the system root to the beginning of the file

+/// name.

+void ASTReader::MaybeAddSystemRootToFilename(ModuleFile &M,

+                                             std::string &Filename) {

+  // If this is not a relocatable PCH file, there's nothing to do.

+  if (!M.RelocatablePCH)

+    return;

+

+  if (Filename.empty() || llvm::sys::path::is_absolute(Filename))

+    return;

+

+  if (isysroot.empty()) {

+    // If no system root was given, default to '/'

+    Filename.insert(Filename.begin(), '/');

+    return;

+  }

+

+  unsigned Length = isysroot.size();

+  if (isysroot[Length - 1] != '/')

+    Filename.insert(Filename.begin(), '/');

+

+  Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end());

+}

+

+ASTReader::ASTReadResult

+ASTReader::ReadControlBlock(ModuleFile &F,

+                            llvm::SmallVectorImpl<ImportedModule> &Loaded,

+                            unsigned ClientLoadCapabilities) {

+  llvm::BitstreamCursor &Stream = F.Stream;

+

+  if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {

+    Error("malformed block record in AST file");

+    return Failure;

+  }

+

+  // Read all of the records and blocks in the control block.

+  RecordData Record;

+  while (!Stream.AtEndOfStream()) {

+    unsigned Code = Stream.ReadCode();

+    if (Code == llvm::bitc::END_BLOCK) {

+      if (Stream.ReadBlockEnd()) {

+        Error("error at end of control block in AST file");

+        return Failure;

+      }

+

+      // Validate all of the input files.

+      if (!DisableValidation) {

+        bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;

+        for (unsigned I = 0, N = Record[0]; I < N; ++I)

+          if (!getInputFile(F, I+1, Complain).getPointer())

+            return OutOfDate;

+      }

+

+      return Success;

+    }

+

+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+      switch (Stream.ReadSubBlockID()) {

+      case INPUT_FILES_BLOCK_ID:

+        F.InputFilesCursor = Stream;

+        if (Stream.SkipBlock() || // Skip with the main cursor

+            // Read the abbreviations

+            ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) {

+          Error("malformed block record in AST file");

+          return Failure;

+        }

+        continue;

+        

+      default:

+        if (!Stream.SkipBlock())

+          continue;

+        break;

+      }

+

+      Error("malformed block record in AST file");

+      return Failure;

+    }

+

+    if (Code == llvm::bitc::DEFINE_ABBREV) {

+      Stream.ReadAbbrevRecord();

+      continue;

+    }

+

+    // Read and process a record.

+    Record.clear();

+    const char *BlobStart = 0;

+    unsigned BlobLen = 0;

+    switch ((ControlRecordTypes)Stream.ReadRecord(Code, Record,

+                                                  &BlobStart, &BlobLen)) {

+    case METADATA: {

+      if (Record[0] != VERSION_MAJOR && !DisableValidation) {

+        if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)

+          Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old

+                                        : diag::warn_pch_version_too_new);

+        return VersionMismatch;

+      }

+

+      bool hasErrors = Record[5];

+      if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {

+        Diag(diag::err_pch_with_compiler_errors);

+        return HadErrors;

+      }

+

+      F.RelocatablePCH = Record[4];

+

+      const std::string &CurBranch = getClangFullRepositoryVersion();

+      StringRef ASTBranch(BlobStart, BlobLen);

+      if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {

+        if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)

+          Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;

+        return VersionMismatch;

+      }

+      break;

+    }

+

+    case IMPORTS: {

+      // Load each of the imported PCH files. 

+      unsigned Idx = 0, N = Record.size();

+      while (Idx < N) {

+        // Read information about the AST file.

+        ModuleKind ImportedKind = (ModuleKind)Record[Idx++];

+        // The import location will be the local one for now; we will adjust

+        // all import locations of module imports after the global source

+        // location info are setup.

+        SourceLocation ImportLoc =

+            SourceLocation::getFromRawEncoding(Record[Idx++]);

+        unsigned Length = Record[Idx++];

+        SmallString<128> ImportedFile(Record.begin() + Idx,

+                                      Record.begin() + Idx + Length);

+        Idx += Length;

+

+        // Load the AST file.

+        switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded,

+                           ClientLoadCapabilities)) {

+        case Failure: return Failure;

+          // If we have to ignore the dependency, we'll have to ignore this too.

+        case OutOfDate: return OutOfDate;

+        case VersionMismatch: return VersionMismatch;

+        case ConfigurationMismatch: return ConfigurationMismatch;

+        case HadErrors: return HadErrors;

+        case Success: break;

+        }

+      }

+      break;

+    }

+

+    case LANGUAGE_OPTIONS: {

+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;

+      if (Listener && &F == *ModuleMgr.begin() &&

+          ParseLanguageOptions(Record, Complain, *Listener) &&

+          !DisableValidation)

+        return ConfigurationMismatch;

+      break;

+    }

+

+    case TARGET_OPTIONS: {

+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;

+      if (Listener && &F == *ModuleMgr.begin() &&

+          ParseTargetOptions(Record, Complain, *Listener) &&

+          !DisableValidation)

+        return ConfigurationMismatch;

+      break;

+    }

+

+    case DIAGNOSTIC_OPTIONS: {

+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;

+      if (Listener && &F == *ModuleMgr.begin() &&

+          ParseDiagnosticOptions(Record, Complain, *Listener) &&

+          !DisableValidation)

+        return ConfigurationMismatch;

+      break;

+    }

+

+    case FILE_SYSTEM_OPTIONS: {

+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;

+      if (Listener && &F == *ModuleMgr.begin() &&

+          ParseFileSystemOptions(Record, Complain, *Listener) &&

+          !DisableValidation)

+        return ConfigurationMismatch;

+      break;

+    }

+

+    case HEADER_SEARCH_OPTIONS: {

+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;

+      if (Listener && &F == *ModuleMgr.begin() &&

+          ParseHeaderSearchOptions(Record, Complain, *Listener) &&

+          !DisableValidation)

+        return ConfigurationMismatch;

+      break;

+    }

+

+    case PREPROCESSOR_OPTIONS: {

+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;

+      if (Listener && &F == *ModuleMgr.begin() &&

+          ParsePreprocessorOptions(Record, Complain, *Listener,

+                                   SuggestedPredefines) &&

+          !DisableValidation)

+        return ConfigurationMismatch;

+      break;

+    }

+

+    case ORIGINAL_FILE:

+      F.OriginalSourceFileID = FileID::get(Record[0]);

+      F.ActualOriginalSourceFileName.assign(BlobStart, BlobLen);

+      F.OriginalSourceFileName = F.ActualOriginalSourceFileName;

+      MaybeAddSystemRootToFilename(F, F.OriginalSourceFileName);

+      break;

+

+    case ORIGINAL_FILE_ID:

+      F.OriginalSourceFileID = FileID::get(Record[0]);

+      break;

+

+    case ORIGINAL_PCH_DIR:

+      F.OriginalDir.assign(BlobStart, BlobLen);

+      break;

+

+    case INPUT_FILE_OFFSETS:

+      F.InputFileOffsets = (const uint32_t *)BlobStart;

+      F.InputFilesLoaded.resize(Record[0]);

+      break;

+    }

+  }

+

+  Error("premature end of bitstream in AST file");

+  return Failure;

+}

+

+bool ASTReader::ReadASTBlock(ModuleFile &F) {

+  llvm::BitstreamCursor &Stream = F.Stream;

+

+  if (Stream.EnterSubBlock(AST_BLOCK_ID)) {

+    Error("malformed block record in AST file");

+    return true;

+  }

+

+  // Read all of the records and blocks for the AST file.

+  RecordData Record;

+  while (!Stream.AtEndOfStream()) {

+    unsigned Code = Stream.ReadCode();

+    if (Code == llvm::bitc::END_BLOCK) {

+      if (Stream.ReadBlockEnd()) {

+        Error("error at end of module block in AST file");

+        return true;

+      }

+

+      DeclContext *DC = Context.getTranslationUnitDecl();

+      if (!DC->hasExternalVisibleStorage() && DC->hasExternalLexicalStorage())

+        DC->setMustBuildLookupTable();

+

+      return false;

+    }

+

+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+      switch (Stream.ReadSubBlockID()) {

+      case DECLTYPES_BLOCK_ID:

+        // We lazily load the decls block, but we want to set up the

+        // DeclsCursor cursor to point into it.  Clone our current bitcode

+        // cursor to it, enter the block and read the abbrevs in that block.

+        // With the main cursor, we just skip over it.

+        F.DeclsCursor = Stream;

+        if (Stream.SkipBlock() ||  // Skip with the main cursor.

+            // Read the abbrevs.

+            ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {

+          Error("malformed block record in AST file");

+          return true;

+        }

+        break;

+

+      case DECL_UPDATES_BLOCK_ID:

+        if (Stream.SkipBlock()) {

+          Error("malformed block record in AST file");

+          return true;

+        }

+        break;

+

+      case PREPROCESSOR_BLOCK_ID:

+        F.MacroCursor = Stream;

+        if (!PP.getExternalSource())

+          PP.setExternalSource(this);

+

+        if (Stream.SkipBlock() ||

+            ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {

+          Error("malformed block record in AST file");

+          return true;

+        }

+        F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();

+        break;

+

+      case PREPROCESSOR_DETAIL_BLOCK_ID:

+        F.PreprocessorDetailCursor = Stream;

+        if (Stream.SkipBlock() ||

+            ReadBlockAbbrevs(F.PreprocessorDetailCursor, 

+                             PREPROCESSOR_DETAIL_BLOCK_ID)) {

+          Error("malformed preprocessor detail record in AST file");

+          return true;

+        }

+        F.PreprocessorDetailStartOffset

+          = F.PreprocessorDetailCursor.GetCurrentBitNo();

+          

+        if (!PP.getPreprocessingRecord())

+          PP.createPreprocessingRecord();

+        if (!PP.getPreprocessingRecord()->getExternalSource())

+          PP.getPreprocessingRecord()->SetExternalSource(*this);

+        break;

+        

+      case SOURCE_MANAGER_BLOCK_ID:

+        if (ReadSourceManagerBlock(F))

+          return true;

+        break;

+

+      case SUBMODULE_BLOCK_ID:

+        if (ReadSubmoduleBlock(F))

+          return true;

+        break;

+

+      case COMMENTS_BLOCK_ID: {

+        llvm::BitstreamCursor C = Stream;

+        if (Stream.SkipBlock() ||

+            ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {

+          Error("malformed comments block in AST file");

+          return true;

+        }

+        CommentsCursors.push_back(std::make_pair(C, &F));

+        break;

+      }

+

+      default:

+        if (!Stream.SkipBlock())

+          break;

+        Error("malformed block record in AST file");

+        return true;

+      }

+      continue;

+    }

+

+    if (Code == llvm::bitc::DEFINE_ABBREV) {

+      Stream.ReadAbbrevRecord();

+      continue;

+    }

+

+    // Read and process a record.

+    Record.clear();

+    const char *BlobStart = 0;

+    unsigned BlobLen = 0;

+    switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record,

+                                              &BlobStart, &BlobLen)) {

+    default:  // Default behavior: ignore.

+      break;

+

+    case TYPE_OFFSET: {

+      if (F.LocalNumTypes != 0) {

+        Error("duplicate TYPE_OFFSET record in AST file");

+        return true;

+      }

+      F.TypeOffsets = (const uint32_t *)BlobStart;

+      F.LocalNumTypes = Record[0];

+      unsigned LocalBaseTypeIndex = Record[1];

+      F.BaseTypeIndex = getTotalNumTypes();

+        

+      if (F.LocalNumTypes > 0) {

+        // Introduce the global -> local mapping for types within this module.

+        GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));

+        

+        // Introduce the local -> global mapping for types within this module.

+        F.TypeRemap.insertOrReplace(

+          std::make_pair(LocalBaseTypeIndex, 

+                         F.BaseTypeIndex - LocalBaseTypeIndex));

+        

+        TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);

+      }

+      break;

+    }

+        

+    case DECL_OFFSET: {

+      if (F.LocalNumDecls != 0) {

+        Error("duplicate DECL_OFFSET record in AST file");

+        return true;

+      }

+      F.DeclOffsets = (const DeclOffset *)BlobStart;

+      F.LocalNumDecls = Record[0];

+      unsigned LocalBaseDeclID = Record[1];

+      F.BaseDeclID = getTotalNumDecls();

+        

+      if (F.LocalNumDecls > 0) {

+        // Introduce the global -> local mapping for declarations within this 

+        // module.

+        GlobalDeclMap.insert(

+          std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));

+        

+        // Introduce the local -> global mapping for declarations within this

+        // module.

+        F.DeclRemap.insertOrReplace(

+          std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID));

+        

+        // Introduce the global -> local mapping for declarations within this

+        // module.

+        F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID;

+        

+        DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);

+      }

+      break;

+    }

+        

+    case TU_UPDATE_LEXICAL: {

+      DeclContext *TU = Context.getTranslationUnitDecl();

+      DeclContextInfo &Info = F.DeclContextInfos[TU];

+      Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair *>(BlobStart);

+      Info.NumLexicalDecls 

+        = static_cast<unsigned int>(BlobLen / sizeof(KindDeclIDPair));

+      TU->setHasExternalLexicalStorage(true);

+      break;

+    }

+

+    case UPDATE_VISIBLE: {

+      unsigned Idx = 0;

+      serialization::DeclID ID = ReadDeclID(F, Record, Idx);

+      ASTDeclContextNameLookupTable *Table =

+        ASTDeclContextNameLookupTable::Create(

+                        (const unsigned char *)BlobStart + Record[Idx++],

+                        (const unsigned char *)BlobStart,

+                        ASTDeclContextNameLookupTrait(*this, F));

+      if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?

+        DeclContext *TU = Context.getTranslationUnitDecl();

+        F.DeclContextInfos[TU].NameLookupTableData = Table;

+        TU->setHasExternalVisibleStorage(true);

+      } else

+        PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));

+      break;

+    }

+

+    case IDENTIFIER_TABLE:

+      F.IdentifierTableData = BlobStart;

+      if (Record[0]) {

+        F.IdentifierLookupTable

+          = ASTIdentifierLookupTable::Create(

+                       (const unsigned char *)F.IdentifierTableData + Record[0],

+                       (const unsigned char *)F.IdentifierTableData,

+                       ASTIdentifierLookupTrait(*this, F));

+        

+        PP.getIdentifierTable().setExternalIdentifierLookup(this);

+      }

+      break;

+

+    case IDENTIFIER_OFFSET: {

+      if (F.LocalNumIdentifiers != 0) {

+        Error("duplicate IDENTIFIER_OFFSET record in AST file");

+        return true;

+      }

+      F.IdentifierOffsets = (const uint32_t *)BlobStart;

+      F.LocalNumIdentifiers = Record[0];

+      unsigned LocalBaseIdentifierID = Record[1];

+      F.BaseIdentifierID = getTotalNumIdentifiers();

+        

+      if (F.LocalNumIdentifiers > 0) {

+        // Introduce the global -> local mapping for identifiers within this

+        // module.

+        GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, 

+                                                  &F));

+        

+        // Introduce the local -> global mapping for identifiers within this

+        // module.

+        F.IdentifierRemap.insertOrReplace(

+          std::make_pair(LocalBaseIdentifierID,

+                         F.BaseIdentifierID - LocalBaseIdentifierID));

+        

+        IdentifiersLoaded.resize(IdentifiersLoaded.size() 

+                                 + F.LocalNumIdentifiers);

+      }

+      break;

+    }

+

+    case EXTERNAL_DEFINITIONS:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case SPECIAL_TYPES:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        SpecialTypes.push_back(getGlobalTypeID(F, Record[I]));

+      break;

+

+    case STATISTICS:

+      TotalNumStatements += Record[0];

+      TotalNumMacros += Record[1];

+      TotalLexicalDeclContexts += Record[2];

+      TotalVisibleDeclContexts += Record[3];

+      break;

+

+    case UNUSED_FILESCOPED_DECLS:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case DELEGATING_CTORS:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case WEAK_UNDECLARED_IDENTIFIERS:

+      if (Record.size() % 4 != 0) {

+        Error("invalid weak identifiers record");

+        return true;

+      }

+        

+      // FIXME: Ignore weak undeclared identifiers from non-original PCH 

+      // files. This isn't the way to do it :)

+      WeakUndeclaredIdentifiers.clear();

+        

+      // Translate the weak, undeclared identifiers into global IDs.

+      for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) {

+        WeakUndeclaredIdentifiers.push_back(

+          getGlobalIdentifierID(F, Record[I++]));

+        WeakUndeclaredIdentifiers.push_back(

+          getGlobalIdentifierID(F, Record[I++]));

+        WeakUndeclaredIdentifiers.push_back(

+          ReadSourceLocation(F, Record, I).getRawEncoding());

+        WeakUndeclaredIdentifiers.push_back(Record[I++]);

+      }

+      break;

+

+    case LOCALLY_SCOPED_EXTERNAL_DECLS:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        LocallyScopedExternalDecls.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case SELECTOR_OFFSETS: {

+      F.SelectorOffsets = (const uint32_t *)BlobStart;

+      F.LocalNumSelectors = Record[0];

+      unsigned LocalBaseSelectorID = Record[1];

+      F.BaseSelectorID = getTotalNumSelectors();

+        

+      if (F.LocalNumSelectors > 0) {

+        // Introduce the global -> local mapping for selectors within this 

+        // module.

+        GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F));

+        

+        // Introduce the local -> global mapping for selectors within this 

+        // module.

+        F.SelectorRemap.insertOrReplace(

+          std::make_pair(LocalBaseSelectorID,

+                         F.BaseSelectorID - LocalBaseSelectorID));

+

+        SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);        

+      }

+      break;

+    }

+        

+    case METHOD_POOL:

+      F.SelectorLookupTableData = (const unsigned char *)BlobStart;

+      if (Record[0])

+        F.SelectorLookupTable

+          = ASTSelectorLookupTable::Create(

+                        F.SelectorLookupTableData + Record[0],

+                        F.SelectorLookupTableData,

+                        ASTSelectorLookupTrait(*this, F));

+      TotalNumMethodPoolEntries += Record[1];

+      break;

+

+    case REFERENCED_SELECTOR_POOL:

+      if (!Record.empty()) {

+        for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {

+          ReferencedSelectorsData.push_back(getGlobalSelectorID(F, 

+                                                                Record[Idx++]));

+          ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx).

+                                              getRawEncoding());

+        }

+      }

+      break;

+

+    case PP_COUNTER_VALUE:

+      if (!Record.empty() && Listener)

+        Listener->ReadCounter(F, Record[0]);

+      break;

+      

+    case FILE_SORTED_DECLS:

+      F.FileSortedDecls = (const DeclID *)BlobStart;

+      F.NumFileSortedDecls = Record[0];

+      break;

+

+    case SOURCE_LOCATION_OFFSETS: {

+      F.SLocEntryOffsets = (const uint32_t *)BlobStart;

+      F.LocalNumSLocEntries = Record[0];

+      unsigned SLocSpaceSize = Record[1];

+      llvm::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =

+          SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,

+                                              SLocSpaceSize);

+      // Make our entry in the range map. BaseID is negative and growing, so

+      // we invert it. Because we invert it, though, we need the other end of

+      // the range.

+      unsigned RangeStart =

+          unsigned(-F.SLocEntryBaseID) - F.LocalNumSLocEntries + 1;

+      GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F));

+      F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset);

+

+      // SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing.

+      assert((F.SLocEntryBaseOffset & (1U << 31U)) == 0);

+      GlobalSLocOffsetMap.insert(

+          std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset

+                           - SLocSpaceSize,&F));

+

+      // Initialize the remapping table.

+      // Invalid stays invalid.

+      F.SLocRemap.insert(std::make_pair(0U, 0));

+      // This module. Base was 2 when being compiled.

+      F.SLocRemap.insert(std::make_pair(2U,

+                                  static_cast<int>(F.SLocEntryBaseOffset - 2)));

+      

+      TotalNumSLocEntries += F.LocalNumSLocEntries;

+      break;

+    }

+

+    case MODULE_OFFSET_MAP: {

+      // Additional remapping information.

+      const unsigned char *Data = (const unsigned char*)BlobStart;

+      const unsigned char *DataEnd = Data + BlobLen;

+      

+      // Continuous range maps we may be updating in our module.

+      ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder 

+        IdentifierRemap(F.IdentifierRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder

+        MacroRemap(F.MacroRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder

+        PreprocessedEntityRemap(F.PreprocessedEntityRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder 

+        SubmoduleRemap(F.SubmoduleRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder 

+        SelectorRemap(F.SelectorRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap);

+      ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap);

+

+      while(Data < DataEnd) {

+        uint16_t Len = io::ReadUnalignedLE16(Data);

+        StringRef Name = StringRef((const char*)Data, Len);

+        Data += Len;

+        ModuleFile *OM = ModuleMgr.lookup(Name);

+        if (!OM) {

+          Error("SourceLocation remap refers to unknown module");

+          return true;

+        }

+

+        uint32_t SLocOffset = io::ReadUnalignedLE32(Data);

+        uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data);

+        uint32_t MacroIDOffset = io::ReadUnalignedLE32(Data);

+        uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data);

+        uint32_t SubmoduleIDOffset = io::ReadUnalignedLE32(Data);

+        uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data);

+        uint32_t DeclIDOffset = io::ReadUnalignedLE32(Data);

+        uint32_t TypeIndexOffset = io::ReadUnalignedLE32(Data);

+        

+        // Source location offset is mapped to OM->SLocEntryBaseOffset.

+        SLocRemap.insert(std::make_pair(SLocOffset,

+          static_cast<int>(OM->SLocEntryBaseOffset - SLocOffset)));

+        IdentifierRemap.insert(

+          std::make_pair(IdentifierIDOffset, 

+                         OM->BaseIdentifierID - IdentifierIDOffset));

+        MacroRemap.insert(std::make_pair(MacroIDOffset,

+                                         OM->BaseMacroID - MacroIDOffset));

+        PreprocessedEntityRemap.insert(

+          std::make_pair(PreprocessedEntityIDOffset, 

+            OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset));

+        SubmoduleRemap.insert(std::make_pair(SubmoduleIDOffset, 

+                                      OM->BaseSubmoduleID - SubmoduleIDOffset));

+        SelectorRemap.insert(std::make_pair(SelectorIDOffset, 

+                               OM->BaseSelectorID - SelectorIDOffset));

+        DeclRemap.insert(std::make_pair(DeclIDOffset, 

+                                        OM->BaseDeclID - DeclIDOffset));

+        

+        TypeRemap.insert(std::make_pair(TypeIndexOffset, 

+                                    OM->BaseTypeIndex - TypeIndexOffset));

+

+        // Global -> local mappings.

+        F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;

+      }

+      break;

+    }

+

+    case SOURCE_MANAGER_LINE_TABLE:

+      if (ParseLineTable(F, Record))

+        return true;

+      break;

+

+    case SOURCE_LOCATION_PRELOADS: {

+      // Need to transform from the local view (1-based IDs) to the global view,

+      // which is based off F.SLocEntryBaseID.

+      if (!F.PreloadSLocEntries.empty()) {

+        Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");

+        return true;

+      }

+      

+      F.PreloadSLocEntries.swap(Record);

+      break;

+    }

+

+    case EXT_VECTOR_DECLS:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case VTABLE_USES:

+      if (Record.size() % 3 != 0) {

+        Error("Invalid VTABLE_USES record");

+        return true;

+      }

+        

+      // Later tables overwrite earlier ones.

+      // FIXME: Modules will have some trouble with this. This is clearly not

+      // the right way to do this.

+      VTableUses.clear();

+        

+      for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {

+        VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));

+        VTableUses.push_back(

+          ReadSourceLocation(F, Record, Idx).getRawEncoding());

+        VTableUses.push_back(Record[Idx++]);

+      }

+      break;

+

+    case DYNAMIC_CLASSES:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        DynamicClasses.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case PENDING_IMPLICIT_INSTANTIATIONS:

+      if (PendingInstantiations.size() % 2 != 0) {

+        Error("Invalid existing PendingInstantiations");

+        return true;

+      }

+

+      if (Record.size() % 2 != 0) {

+        Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");

+        return true;

+      }

+

+      for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {

+        PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));

+        PendingInstantiations.push_back(

+          ReadSourceLocation(F, Record, I).getRawEncoding());

+      }

+      break;

+

+    case SEMA_DECL_REFS:

+      // Later tables overwrite earlier ones.

+      // FIXME: Modules will have some trouble with this.

+      SemaDeclRefs.clear();

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case PPD_ENTITIES_OFFSETS: {

+      F.PreprocessedEntityOffsets = (const PPEntityOffset *)BlobStart;

+      assert(BlobLen % sizeof(PPEntityOffset) == 0);

+      F.NumPreprocessedEntities = BlobLen / sizeof(PPEntityOffset);

+

+      unsigned LocalBasePreprocessedEntityID = Record[0];

+      

+      unsigned StartingID;

+      if (!PP.getPreprocessingRecord())

+        PP.createPreprocessingRecord();

+      if (!PP.getPreprocessingRecord()->getExternalSource())

+        PP.getPreprocessingRecord()->SetExternalSource(*this);

+      StartingID 

+        = PP.getPreprocessingRecord()

+            ->allocateLoadedEntities(F.NumPreprocessedEntities);

+      F.BasePreprocessedEntityID = StartingID;

+

+      if (F.NumPreprocessedEntities > 0) {

+        // Introduce the global -> local mapping for preprocessed entities in

+        // this module.

+        GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));

+       

+        // Introduce the local -> global mapping for preprocessed entities in

+        // this module.

+        F.PreprocessedEntityRemap.insertOrReplace(

+          std::make_pair(LocalBasePreprocessedEntityID,

+            F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID));

+      }

+

+      break;

+    }

+        

+    case DECL_UPDATE_OFFSETS: {

+      if (Record.size() % 2 != 0) {

+        Error("invalid DECL_UPDATE_OFFSETS block in AST file");

+        return true;

+      }

+      for (unsigned I = 0, N = Record.size(); I != N; I += 2)

+        DeclUpdateOffsets[getGlobalDeclID(F, Record[I])]

+          .push_back(std::make_pair(&F, Record[I+1]));

+      break;

+    }

+

+    case DECL_REPLACEMENTS: {

+      if (Record.size() % 3 != 0) {

+        Error("invalid DECL_REPLACEMENTS block in AST file");

+        return true;

+      }

+      for (unsigned I = 0, N = Record.size(); I != N; I += 3)

+        ReplacedDecls[getGlobalDeclID(F, Record[I])]

+          = ReplacedDeclInfo(&F, Record[I+1], Record[I+2]);

+      break;

+    }

+

+    case OBJC_CATEGORIES_MAP: {

+      if (F.LocalNumObjCCategoriesInMap != 0) {

+        Error("duplicate OBJC_CATEGORIES_MAP record in AST file");

+        return true;

+      }

+      

+      F.LocalNumObjCCategoriesInMap = Record[0];

+      F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)BlobStart;

+      break;

+    }

+        

+    case OBJC_CATEGORIES:

+      F.ObjCCategories.swap(Record);

+      break;

+        

+    case CXX_BASE_SPECIFIER_OFFSETS: {

+      if (F.LocalNumCXXBaseSpecifiers != 0) {

+        Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file");

+        return true;

+      }

+      

+      F.LocalNumCXXBaseSpecifiers = Record[0];

+      F.CXXBaseSpecifiersOffsets = (const uint32_t *)BlobStart;

+      NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers;

+      break;

+    }

+

+    case DIAG_PRAGMA_MAPPINGS:

+      if (F.PragmaDiagMappings.empty())

+        F.PragmaDiagMappings.swap(Record);

+      else

+        F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),

+                                    Record.begin(), Record.end());

+      break;

+        

+    case CUDA_SPECIAL_DECL_REFS:

+      // Later tables overwrite earlier ones.

+      // FIXME: Modules will have trouble with this.

+      CUDASpecialDeclRefs.clear();

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+

+    case HEADER_SEARCH_TABLE: {

+      F.HeaderFileInfoTableData = BlobStart;

+      F.LocalNumHeaderFileInfos = Record[1];

+      F.HeaderFileFrameworkStrings = BlobStart + Record[2];

+      if (Record[0]) {

+        F.HeaderFileInfoTable

+          = HeaderFileInfoLookupTable::Create(

+                   (const unsigned char *)F.HeaderFileInfoTableData + Record[0],

+                   (const unsigned char *)F.HeaderFileInfoTableData,

+                   HeaderFileInfoTrait(*this, F, 

+                                       &PP.getHeaderSearchInfo(),

+                                       BlobStart + Record[2]));

+        

+        PP.getHeaderSearchInfo().SetExternalSource(this);

+        if (!PP.getHeaderSearchInfo().getExternalLookup())

+          PP.getHeaderSearchInfo().SetExternalLookup(this);

+      }

+      break;

+    }

+        

+    case FP_PRAGMA_OPTIONS:

+      // Later tables overwrite earlier ones.

+      FPPragmaOptions.swap(Record);

+      break;

+

+    case OPENCL_EXTENSIONS:

+      // Later tables overwrite earlier ones.

+      OpenCLExtensions.swap(Record);

+      break;

+

+    case TENTATIVE_DEFINITIONS:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+        

+    case KNOWN_NAMESPACES:

+      for (unsigned I = 0, N = Record.size(); I != N; ++I)

+        KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));

+      break;

+        

+    case IMPORTED_MODULES: {

+      if (F.Kind != MK_Module) {

+        // If we aren't loading a module (which has its own exports), make

+        // all of the imported modules visible.

+        // FIXME: Deal with macros-only imports.

+        for (unsigned I = 0, N = Record.size(); I != N; ++I) {

+          if (unsigned GlobalID = getGlobalSubmoduleID(F, Record[I]))

+            ImportedModules.push_back(GlobalID);

+        }

+      }

+      break;

+    }

+

+    case LOCAL_REDECLARATIONS: {

+      F.RedeclarationChains.swap(Record);

+      break;

+    }

+        

+    case LOCAL_REDECLARATIONS_MAP: {

+      if (F.LocalNumRedeclarationsInMap != 0) {

+        Error("duplicate LOCAL_REDECLARATIONS_MAP record in AST file");

+        return true;

+      }

+      

+      F.LocalNumRedeclarationsInMap = Record[0];

+      F.RedeclarationsMap = (const LocalRedeclarationsInfo *)BlobStart;

+      break;

+    }

+        

+    case MERGED_DECLARATIONS: {

+      for (unsigned Idx = 0; Idx < Record.size(); /* increment in loop */) {

+        GlobalDeclID CanonID = getGlobalDeclID(F, Record[Idx++]);

+        SmallVectorImpl<GlobalDeclID> &Decls = StoredMergedDecls[CanonID];

+        for (unsigned N = Record[Idx++]; N > 0; --N)

+          Decls.push_back(getGlobalDeclID(F, Record[Idx++]));

+      }

+      break;

+    }

+

+    case MACRO_OFFSET: {

+      if (F.LocalNumMacros != 0) {

+        Error("duplicate MACRO_OFFSET record in AST file");

+        return true;

+      }

+      F.MacroOffsets = (const uint32_t *)BlobStart;

+      F.LocalNumMacros = Record[0];

+      unsigned LocalBaseMacroID = Record[1];

+      F.BaseMacroID = getTotalNumMacros();

+

+      if (F.LocalNumMacros > 0) {

+        // Introduce the global -> local mapping for macros within this module.

+        GlobalMacroMap.insert(std::make_pair(getTotalNumMacros() + 1, &F));

+

+        // Introduce the local -> global mapping for macros within this module.

+        F.MacroRemap.insertOrReplace(

+          std::make_pair(LocalBaseMacroID,

+                         F.BaseMacroID - LocalBaseMacroID));

+

+        MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros);

+      }

+      break;

+    }

+

+    case MACRO_UPDATES: {

+      for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {

+        MacroID ID = getGlobalMacroID(F, Record[I++]);

+        if (I == N)

+          break;

+

+        SourceLocation UndefLoc = ReadSourceLocation(F, Record, I);

+        SubmoduleID SubmoduleID = getGlobalSubmoduleID(F, Record[I++]);;

+        MacroUpdate Update;

+        Update.UndefLoc = UndefLoc;

+        MacroUpdates[ID].push_back(std::make_pair(SubmoduleID, Update));

+      }

+      break;

+    }

+    }

+  }

+  Error("premature end of bitstream in AST file");

+  return true;

+}

+

+void ASTReader::makeNamesVisible(const HiddenNames &Names) {

+  for (unsigned I = 0, N = Names.size(); I != N; ++I) {

+    switch (Names[I].getKind()) {

+    case HiddenName::Declaration:

+      Names[I].getDecl()->Hidden = false;

+      break;

+

+    case HiddenName::MacroVisibility: {

+      std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro();

+      Macro.second->setHidden(!Macro.second->isPublic());

+      if (Macro.second->isDefined()) {

+        PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);

+      }

+      break;

+    }

+

+    case HiddenName::MacroUndef: {

+      std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro();

+      if (Macro.second->isDefined()) {

+        Macro.second->setUndefLoc(Names[I].getMacroUndefLoc());

+        if (PPMutationListener *Listener = PP.getPPMutationListener())

+          Listener->UndefinedMacro(Macro.second);

+        PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);

+      }

+      break;

+    }

+    }

+  }

+}

+

+void ASTReader::makeModuleVisible(Module *Mod, 

+                                  Module::NameVisibilityKind NameVisibility) {

+  llvm::SmallPtrSet<Module *, 4> Visited;

+  llvm::SmallVector<Module *, 4> Stack;

+  Stack.push_back(Mod);  

+  while (!Stack.empty()) {

+    Mod = Stack.back();

+    Stack.pop_back();

+

+    if (NameVisibility <= Mod->NameVisibility) {

+      // This module already has this level of visibility (or greater), so 

+      // there is nothing more to do.

+      continue;

+    }

+    

+    if (!Mod->isAvailable()) {

+      // Modules that aren't available cannot be made visible.

+      continue;

+    }

+

+    // Update the module's name visibility.

+    Mod->NameVisibility = NameVisibility;

+    

+    // If we've already deserialized any names from this module,

+    // mark them as visible.

+    HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod);

+    if (Hidden != HiddenNamesMap.end()) {

+      makeNamesVisible(Hidden->second);

+      HiddenNamesMap.erase(Hidden);

+    }

+    

+    // Push any non-explicit submodules onto the stack to be marked as

+    // visible.

+    for (Module::submodule_iterator Sub = Mod->submodule_begin(),

+                                 SubEnd = Mod->submodule_end();

+         Sub != SubEnd; ++Sub) {

+      if (!(*Sub)->IsExplicit && Visited.insert(*Sub))

+        Stack.push_back(*Sub);

+    }

+    

+    // Push any exported modules onto the stack to be marked as visible.

+    bool AnyWildcard = false;

+    bool UnrestrictedWildcard = false;

+    llvm::SmallVector<Module *, 4> WildcardRestrictions;

+    for (unsigned I = 0, N = Mod->Exports.size(); I != N; ++I) {

+      Module *Exported = Mod->Exports[I].getPointer();

+      if (!Mod->Exports[I].getInt()) {

+        // Export a named module directly; no wildcards involved.

+        if (Visited.insert(Exported))

+          Stack.push_back(Exported);

+        

+        continue;

+      }

+      

+      // Wildcard export: export all of the imported modules that match

+      // the given pattern.

+      AnyWildcard = true;

+      if (UnrestrictedWildcard)

+        continue;

+

+      if (Module *Restriction = Mod->Exports[I].getPointer())

+        WildcardRestrictions.push_back(Restriction);

+      else {

+        WildcardRestrictions.clear();

+        UnrestrictedWildcard = true;

+      }

+    }

+    

+    // If there were any wildcards, push any imported modules that were

+    // re-exported by the wildcard restriction.

+    if (!AnyWildcard)

+      continue;

+    

+    for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) {

+      Module *Imported = Mod->Imports[I];

+      if (!Visited.insert(Imported))

+        continue;

+      

+      bool Acceptable = UnrestrictedWildcard;

+      if (!Acceptable) {

+        // Check whether this module meets one of the restrictions.

+        for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {

+          Module *Restriction = WildcardRestrictions[R];

+          if (Imported == Restriction || Imported->isSubModuleOf(Restriction)) {

+            Acceptable = true;

+            break;

+          }

+        }

+      }

+      

+      if (!Acceptable)

+        continue;

+      

+      Stack.push_back(Imported);

+    }

+  }

+}

+

+ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,

+                                            ModuleKind Type,

+                                            SourceLocation ImportLoc,

+                                            unsigned ClientLoadCapabilities) {

+  // Bump the generation number.

+  unsigned PreviousGeneration = CurrentGeneration++;

+

+  unsigned NumModules = ModuleMgr.size();

+  llvm::SmallVector<ImportedModule, 4> Loaded;

+  switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,

+                                                /*ImportedBy=*/0, Loaded,

+                                                ClientLoadCapabilities)) {

+  case Failure:

+  case OutOfDate:

+  case VersionMismatch:

+  case ConfigurationMismatch:

+  case HadErrors:

+    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end());

+    return ReadResult;

+

+  case Success:

+    break;

+  }

+

+  // Here comes stuff that we only do once the entire chain is loaded.

+

+  // Load the AST blocks of all of the modules that we loaded.

+  for (llvm::SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),

+                                                  MEnd = Loaded.end();

+       M != MEnd; ++M) {

+    ModuleFile &F = *M->Mod;

+

+    // Read the AST block.

+    if (ReadASTBlock(F))

+      return Failure;

+

+    // Once read, set the ModuleFile bit base offset and update the size in 

+    // bits of all files we've seen.

+    F.GlobalBitOffset = TotalModulesSizeInBits;

+    TotalModulesSizeInBits += F.SizeInBits;

+    GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));

+    

+    // Preload SLocEntries.

+    for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {

+      int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;

+      // Load it through the SourceManager and don't call ReadSLocEntry()

+      // directly because the entry may have already been loaded in which case

+      // calling ReadSLocEntry() directly would trigger an assertion in

+      // SourceManager.

+      SourceMgr.getLoadedSLocEntryByID(Index);

+    }

+  }

+

+  // Setup the import locations.

+  for (llvm::SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),

+                                                    MEnd = Loaded.end();

+       M != MEnd; ++M) {

+    ModuleFile &F = *M->Mod;

+    if (!M->ImportedBy)

+      F.ImportLoc = M->ImportLoc;

+    else

+      F.ImportLoc = ReadSourceLocation(*M->ImportedBy,

+                                       M->ImportLoc.getRawEncoding());

+  }

+

+  // Mark all of the identifiers in the identifier table as being out of date,

+  // so that various accessors know to check the loaded modules when the

+  // identifier is used.

+  for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),

+                              IdEnd = PP.getIdentifierTable().end();

+       Id != IdEnd; ++Id)

+    Id->second->setOutOfDate(true);

+  

+  // Resolve any unresolved module exports.

+  for (unsigned I = 0, N = UnresolvedModuleImportExports.size(); I != N; ++I) {

+    UnresolvedModuleImportExport &Unresolved = UnresolvedModuleImportExports[I];

+    SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID);

+    Module *ResolvedMod = getSubmodule(GlobalID);

+    

+    if (Unresolved.IsImport) {

+      if (ResolvedMod)

+        Unresolved.Mod->Imports.push_back(ResolvedMod);

+      continue;

+    }

+

+    if (ResolvedMod || Unresolved.IsWildcard)

+      Unresolved.Mod->Exports.push_back(

+        Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));

+  }

+  UnresolvedModuleImportExports.clear();

+  

+  InitializeContext();

+

+  if (DeserializationListener)

+    DeserializationListener->ReaderInitialized(this);

+

+  ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule();

+  if (!PrimaryModule.OriginalSourceFileID.isInvalid()) {

+    PrimaryModule.OriginalSourceFileID 

+      = FileID::get(PrimaryModule.SLocEntryBaseID

+                    + PrimaryModule.OriginalSourceFileID.getOpaqueValue() - 1);

+

+    // If this AST file is a precompiled preamble, then set the

+    // preamble file ID of the source manager to the file source file

+    // from which the preamble was built.

+    if (Type == MK_Preamble) {

+      SourceMgr.setPreambleFileID(PrimaryModule.OriginalSourceFileID);

+    } else if (Type == MK_MainFile) {

+      SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID);

+    }

+  }

+  

+  // For any Objective-C class definitions we have already loaded, make sure

+  // that we load any additional categories.

+  for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) {

+    loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), 

+                       ObjCClassesLoaded[I],

+                       PreviousGeneration);

+  }

+  

+  return Success;

+}

+

+ASTReader::ASTReadResult

+ASTReader::ReadASTCore(StringRef FileName,

+                       ModuleKind Type,

+                       SourceLocation ImportLoc,

+                       ModuleFile *ImportedBy,

+                       llvm::SmallVectorImpl<ImportedModule> &Loaded,

+                       unsigned ClientLoadCapabilities) {

+  ModuleFile *M;

+  bool NewModule;

+  std::string ErrorStr;

+  llvm::tie(M, NewModule) = ModuleMgr.addModule(FileName, Type, ImportLoc,

+                                                ImportedBy, CurrentGeneration,

+                                                ErrorStr);

+

+  if (!M) {

+    // We couldn't load the module.

+    std::string Msg = "Unable to load module \"" + FileName.str() + "\": "

+      + ErrorStr;

+    Error(Msg);

+    return Failure;

+  }

+

+  if (!NewModule) {

+    // We've already loaded this module.

+    return Success;

+  }

+

+  // FIXME: This seems rather a hack. Should CurrentDir be part of the

+  // module?

+  if (FileName != "-") {

+    CurrentDir = llvm::sys::path::parent_path(FileName);

+    if (CurrentDir.empty()) CurrentDir = ".";

+  }

+

+  ModuleFile &F = *M;

+  llvm::BitstreamCursor &Stream = F.Stream;

+  Stream.init(F.StreamFile);

+  F.SizeInBits = F.Buffer->getBufferSize() * 8;

+  

+  // Sniff for the signature.

+  if (Stream.Read(8) != 'C' ||

+      Stream.Read(8) != 'P' ||

+      Stream.Read(8) != 'C' ||

+      Stream.Read(8) != 'H') {

+    Diag(diag::err_not_a_pch_file) << FileName;

+    return Failure;

+  }

+

+  // This is used for compatibility with older PCH formats.

+  bool HaveReadControlBlock = false;

+

+  while (!Stream.AtEndOfStream()) {

+    unsigned Code = Stream.ReadCode();

+

+    if (Code != llvm::bitc::ENTER_SUBBLOCK) {

+      Error("invalid record at top-level of AST file");

+      return Failure;

+    }

+

+    unsigned BlockID = Stream.ReadSubBlockID();

+

+    // We only know the control subblock ID.

+    switch (BlockID) {

+    case llvm::bitc::BLOCKINFO_BLOCK_ID:

+      if (Stream.ReadBlockInfoBlock()) {

+        Error("malformed BlockInfoBlock in AST file");

+        return Failure;

+      }

+      break;

+    case CONTROL_BLOCK_ID:

+      HaveReadControlBlock = true;

+      switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {

+      case Success:

+        break;

+

+      case Failure: return Failure;

+      case OutOfDate: return OutOfDate;

+      case VersionMismatch: return VersionMismatch;

+      case ConfigurationMismatch: return ConfigurationMismatch;

+      case HadErrors: return HadErrors;

+      }

+      break;

+    case AST_BLOCK_ID:

+      if (!HaveReadControlBlock) {

+        if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)

+          Diag(diag::warn_pch_version_too_old);

+        return VersionMismatch;

+      }

+

+      // Record that we've loaded this module.

+      Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));

+      return Success;

+

+    default:

+      if (Stream.SkipBlock()) {

+        Error("malformed block record in AST file");

+        return Failure;

+      }

+      break;

+    }

+  }

+  

+  return Success;

+}

+

+void ASTReader::InitializeContext() {  

+  // If there's a listener, notify them that we "read" the translation unit.

+  if (DeserializationListener)

+    DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, 

+                                      Context.getTranslationUnitDecl());

+

+  // Make sure we load the declaration update records for the translation unit,

+  // if there are any.

+  loadDeclUpdateRecords(PREDEF_DECL_TRANSLATION_UNIT_ID, 

+                        Context.getTranslationUnitDecl());

+  

+  // FIXME: Find a better way to deal with collisions between these

+  // built-in types. Right now, we just ignore the problem.

+  

+  // Load the special types.

+  if (SpecialTypes.size() >= NumSpecialTypeIDs) {

+    if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {

+      if (!Context.CFConstantStringTypeDecl)

+        Context.setCFConstantStringType(GetType(String));

+    }

+    

+    if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {

+      QualType FileType = GetType(File);

+      if (FileType.isNull()) {

+        Error("FILE type is NULL");

+        return;

+      }

+      

+      if (!Context.FILEDecl) {

+        if (const TypedefType *Typedef = FileType->getAs<TypedefType>())

+          Context.setFILEDecl(Typedef->getDecl());

+        else {

+          const TagType *Tag = FileType->getAs<TagType>();

+          if (!Tag) {

+            Error("Invalid FILE type in AST file");

+            return;

+          }

+          Context.setFILEDecl(Tag->getDecl());

+        }

+      }

+    }

+    

+    if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {

+      QualType Jmp_bufType = GetType(Jmp_buf);

+      if (Jmp_bufType.isNull()) {

+        Error("jmp_buf type is NULL");

+        return;

+      }

+      

+      if (!Context.jmp_bufDecl) {

+        if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())

+          Context.setjmp_bufDecl(Typedef->getDecl());

+        else {

+          const TagType *Tag = Jmp_bufType->getAs<TagType>();

+          if (!Tag) {

+            Error("Invalid jmp_buf type in AST file");

+            return;

+          }

+          Context.setjmp_bufDecl(Tag->getDecl());

+        }

+      }

+    }

+    

+    if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {

+      QualType Sigjmp_bufType = GetType(Sigjmp_buf);

+      if (Sigjmp_bufType.isNull()) {

+        Error("sigjmp_buf type is NULL");

+        return;

+      }

+      

+      if (!Context.sigjmp_bufDecl) {

+        if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())

+          Context.setsigjmp_bufDecl(Typedef->getDecl());

+        else {

+          const TagType *Tag = Sigjmp_bufType->getAs<TagType>();

+          assert(Tag && "Invalid sigjmp_buf type in AST file");

+          Context.setsigjmp_bufDecl(Tag->getDecl());

+        }

+      }

+    }

+

+    if (unsigned ObjCIdRedef

+          = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {

+      if (Context.ObjCIdRedefinitionType.isNull())

+        Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef);

+    }

+

+    if (unsigned ObjCClassRedef

+          = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {

+      if (Context.ObjCClassRedefinitionType.isNull())

+        Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef);

+    }

+

+    if (unsigned ObjCSelRedef

+          = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {

+      if (Context.ObjCSelRedefinitionType.isNull())

+        Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef);

+    }

+

+    if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) {

+      QualType Ucontext_tType = GetType(Ucontext_t);

+      if (Ucontext_tType.isNull()) {

+        Error("ucontext_t type is NULL");

+        return;

+      }

+

+      if (!Context.ucontext_tDecl) {

+        if (const TypedefType *Typedef = Ucontext_tType->getAs<TypedefType>())

+          Context.setucontext_tDecl(Typedef->getDecl());

+        else {

+          const TagType *Tag = Ucontext_tType->getAs<TagType>();

+          assert(Tag && "Invalid ucontext_t type in AST file");

+          Context.setucontext_tDecl(Tag->getDecl());

+        }

+      }

+    }

+  }

+  

+  ReadPragmaDiagnosticMappings(Context.getDiagnostics());

+

+  // If there were any CUDA special declarations, deserialize them.

+  if (!CUDASpecialDeclRefs.empty()) {

+    assert(CUDASpecialDeclRefs.size() == 1 && "More decl refs than expected!");

+    Context.setcudaConfigureCallDecl(

+                           cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));

+  }

+  

+  // Re-export any modules that were imported by a non-module AST file.

+  for (unsigned I = 0, N = ImportedModules.size(); I != N; ++I) {

+    if (Module *Imported = getSubmodule(ImportedModules[I]))

+      makeModuleVisible(Imported, Module::AllVisible);

+  }

+  ImportedModules.clear();

+}

+

+void ASTReader::finalizeForWriting() {

+  for (HiddenNamesMapType::iterator Hidden = HiddenNamesMap.begin(),

+                                 HiddenEnd = HiddenNamesMap.end();

+       Hidden != HiddenEnd; ++Hidden) {

+    makeNamesVisible(Hidden->second);

+  }

+  HiddenNamesMap.clear();

+}

+

+/// \brief Retrieve the name of the original source file name

+/// directly from the AST file, without actually loading the AST

+/// file.

+std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,

+                                             FileManager &FileMgr,

+                                             DiagnosticsEngine &Diags) {

+  // Open the AST file.

+  std::string ErrStr;

+  OwningPtr<llvm::MemoryBuffer> Buffer;

+  Buffer.reset(FileMgr.getBufferForFile(ASTFileName, &ErrStr));

+  if (!Buffer) {

+    Diags.Report(diag::err_fe_unable_to_read_pch_file) << ASTFileName << ErrStr;

+    return std::string();

+  }

+

+  // Initialize the stream

+  llvm::BitstreamReader StreamFile;

+  llvm::BitstreamCursor Stream;

+  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),

+                  (const unsigned char *)Buffer->getBufferEnd());

+  Stream.init(StreamFile);

+

+  // Sniff for the signature.

+  if (Stream.Read(8) != 'C' ||

+      Stream.Read(8) != 'P' ||

+      Stream.Read(8) != 'C' ||

+      Stream.Read(8) != 'H') {

+    Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;

+    return std::string();

+  }

+

+  RecordData Record;

+  while (!Stream.AtEndOfStream()) {

+    unsigned Code = Stream.ReadCode();

+

+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+      unsigned BlockID = Stream.ReadSubBlockID();

+

+      // We only know the AST subblock ID.

+      switch (BlockID) {

+      case CONTROL_BLOCK_ID:

+        if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {

+          Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;

+          return std::string();

+        }

+        break;

+

+      default:

+        if (Stream.SkipBlock()) {

+          Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;

+          return std::string();

+        }

+        break;

+      }

+      continue;

+    }

+

+    if (Code == llvm::bitc::END_BLOCK) {

+      if (Stream.ReadBlockEnd()) {

+        Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;

+        return std::string();

+      }

+      continue;

+    }

+

+    if (Code == llvm::bitc::DEFINE_ABBREV) {

+      Stream.ReadAbbrevRecord();

+      continue;

+    }

+

+    Record.clear();

+    const char *BlobStart = 0;

+    unsigned BlobLen = 0;

+    if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen) == ORIGINAL_FILE)

+      return std::string(BlobStart, BlobLen);

+  }

+

+  return std::string();

+}

+

+namespace {

+  class SimplePCHValidator : public ASTReaderListener {

+    const LangOptions &ExistingLangOpts;

+    const TargetOptions &ExistingTargetOpts;

+    const PreprocessorOptions &ExistingPPOpts;

+    FileManager &FileMgr;

+    

+  public:

+    SimplePCHValidator(const LangOptions &ExistingLangOpts,

+                       const TargetOptions &ExistingTargetOpts,

+                       const PreprocessorOptions &ExistingPPOpts,

+                       FileManager &FileMgr)

+      : ExistingLangOpts(ExistingLangOpts),

+        ExistingTargetOpts(ExistingTargetOpts),

+        ExistingPPOpts(ExistingPPOpts),

+        FileMgr(FileMgr)

+    {

+    }

+

+    virtual bool ReadLanguageOptions(const LangOptions &LangOpts,

+                                     bool Complain) {

+      return checkLanguageOptions(ExistingLangOpts, LangOpts, 0);

+    }

+    virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,

+                                   bool Complain) {

+      return checkTargetOptions(ExistingTargetOpts, TargetOpts, 0);

+    }

+    virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,

+                                         bool Complain,

+                                         std::string &SuggestedPredefines) {

+      return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr,

+                                      SuggestedPredefines);

+    }

+  };

+}

+

+bool ASTReader::readASTFileControlBlock(StringRef Filename,

+                                        FileManager &FileMgr,

+                                        ASTReaderListener &Listener) {

+  // Open the AST file.

+  std::string ErrStr;

+  OwningPtr<llvm::MemoryBuffer> Buffer;

+  Buffer.reset(FileMgr.getBufferForFile(Filename, &ErrStr));

+  if (!Buffer) {

+    return true;

+  }

+

+  // Initialize the stream

+  llvm::BitstreamReader StreamFile;

+  llvm::BitstreamCursor Stream;

+  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),

+                  (const unsigned char *)Buffer->getBufferEnd());

+  Stream.init(StreamFile);

+

+  // Sniff for the signature.

+  if (Stream.Read(8) != 'C' ||

+      Stream.Read(8) != 'P' ||

+      Stream.Read(8) != 'C' ||

+      Stream.Read(8) != 'H') {

+    return true;

+  }

+

+  RecordData Record;

+  bool InControlBlock = false;

+  while (!Stream.AtEndOfStream()) {

+    unsigned Code = Stream.ReadCode();

+

+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+      unsigned BlockID = Stream.ReadSubBlockID();

+

+      // We only know the control subblock ID.

+      switch (BlockID) {

+      case CONTROL_BLOCK_ID:

+        if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {

+          return true;

+        } else {

+          InControlBlock = true;

+        }

+        break;

+

+      default:

+        if (Stream.SkipBlock())

+          return true;

+        break;

+      }

+      continue;

+    }

+

+    if (Code == llvm::bitc::END_BLOCK) {

+      if (Stream.ReadBlockEnd()) {

+        return true;

+      }

+

+      InControlBlock = false;

+      continue;

+    }

+

+    if (Code == llvm::bitc::DEFINE_ABBREV) {

+      Stream.ReadAbbrevRecord();

+      continue;

+    }

+

+    Record.clear();

+    const char *BlobStart = 0;

+    unsigned BlobLen = 0;

+    unsigned RecCode = Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen);

+    if (InControlBlock) {

+      switch ((ControlRecordTypes)RecCode) {

+      case METADATA: {

+        if (Record[0] != VERSION_MAJOR) {

+          return true;

+        }

+

+        const std::string &CurBranch = getClangFullRepositoryVersion();

+        StringRef ASTBranch(BlobStart, BlobLen);

+        if (StringRef(CurBranch) != ASTBranch)

+          return true;

+

+        break;

+      }

+      case LANGUAGE_OPTIONS:

+        if (ParseLanguageOptions(Record, false, Listener))

+          return true;

+        break;

+

+      case TARGET_OPTIONS:

+        if (ParseTargetOptions(Record, false, Listener))

+          return true;

+        break;

+

+      case DIAGNOSTIC_OPTIONS:

+        if (ParseDiagnosticOptions(Record, false, Listener))

+          return true;

+        break;

+

+      case FILE_SYSTEM_OPTIONS:

+        if (ParseFileSystemOptions(Record, false, Listener))

+          return true;

+        break;

+

+      case HEADER_SEARCH_OPTIONS:

+        if (ParseHeaderSearchOptions(Record, false, Listener))

+          return true;

+        break;

+

+      case PREPROCESSOR_OPTIONS: {

+        std::string IgnoredSuggestedPredefines;

+        if (ParsePreprocessorOptions(Record, false, Listener,

+                                     IgnoredSuggestedPredefines))

+          return true;

+        break;

+      }

+

+      default:

+        // No other validation to perform.

+        break;

+      }

+    }

+  }

+  

+  return false;

+}

+

+

+bool ASTReader::isAcceptableASTFile(StringRef Filename,

+                                    FileManager &FileMgr,

+                                    const LangOptions &LangOpts,

+                                    const TargetOptions &TargetOpts,

+                                    const PreprocessorOptions &PPOpts) {

+  SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, FileMgr);

+  return !readASTFileControlBlock(Filename, FileMgr, validator);

+}

+

+bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) {

+  // Enter the submodule block.

+  if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {

+    Error("malformed submodule block record in AST file");

+    return true;

+  }

+

+  ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();

+  bool First = true;

+  Module *CurrentModule = 0;

+  RecordData Record;

+  while (true) {

+    unsigned Code = F.Stream.ReadCode();

+    if (Code == llvm::bitc::END_BLOCK) {

+      if (F.Stream.ReadBlockEnd()) {

+        Error("error at end of submodule block in AST file");

+        return true;

+      }

+      return false;

+    }

+    

+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+      // No known subblocks, always skip them.

+      F.Stream.ReadSubBlockID();

+      if (F.Stream.SkipBlock()) {

+        Error("malformed block record in AST file");

+        return true;

+      }

+      continue;

+    }

+    

+    if (Code == llvm::bitc::DEFINE_ABBREV) {

+      F.Stream.ReadAbbrevRecord();

+      continue;

+    }

+    

+    // Read a record.

+    const char *BlobStart;

+    unsigned BlobLen;

+    Record.clear();

+    switch (F.Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {

+    default:  // Default behavior: ignore.

+      break;

+      

+    case SUBMODULE_DEFINITION: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+

+      if (Record.size() < 7) {

+        Error("malformed module definition");

+        return true;

+      }

+      

+      StringRef Name(BlobStart, BlobLen);

+      SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[0]);

+      SubmoduleID Parent = getGlobalSubmoduleID(F, Record[1]);

+      bool IsFramework = Record[2];

+      bool IsExplicit = Record[3];

+      bool IsSystem = Record[4];

+      bool InferSubmodules = Record[5];

+      bool InferExplicitSubmodules = Record[6];

+      bool InferExportWildcard = Record[7];

+      

+      Module *ParentModule = 0;

+      if (Parent)

+        ParentModule = getSubmodule(Parent);

+      

+      // Retrieve this (sub)module from the module map, creating it if

+      // necessary.

+      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, 

+                                                IsFramework, 

+                                                IsExplicit).first;

+      SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;

+      if (GlobalIndex >= SubmodulesLoaded.size() ||

+          SubmodulesLoaded[GlobalIndex]) {

+        Error("too many submodules");

+        return true;

+      }

+      

+      CurrentModule->setASTFile(F.File);

+      CurrentModule->IsFromModuleFile = true;

+      CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;

+      CurrentModule->InferSubmodules = InferSubmodules;

+      CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;

+      CurrentModule->InferExportWildcard = InferExportWildcard;

+      if (DeserializationListener)

+        DeserializationListener->ModuleRead(GlobalID, CurrentModule);

+      

+      SubmodulesLoaded[GlobalIndex] = CurrentModule;

+      break;

+    }

+        

+    case SUBMODULE_UMBRELLA_HEADER: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+

+      if (!CurrentModule)

+        break;

+      

+      StringRef FileName(BlobStart, BlobLen);

+      if (const FileEntry *Umbrella = PP.getFileManager().getFile(FileName)) {

+        if (!CurrentModule->getUmbrellaHeader())

+          ModMap.setUmbrellaHeader(CurrentModule, Umbrella);

+        else if (CurrentModule->getUmbrellaHeader() != Umbrella) {

+          Error("mismatched umbrella headers in submodule");

+          return true;

+        }

+      }

+      break;

+    }

+        

+    case SUBMODULE_HEADER: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+

+      if (!CurrentModule)

+        break;

+      

+      // FIXME: Be more lazy about this!

+      StringRef FileName(BlobStart, BlobLen);

+      if (const FileEntry *File = PP.getFileManager().getFile(FileName)) {

+        if (std::find(CurrentModule->Headers.begin(), 

+                      CurrentModule->Headers.end(), 

+                      File) == CurrentModule->Headers.end())

+          ModMap.addHeader(CurrentModule, File, false);

+      }

+      break;      

+    }

+

+    case SUBMODULE_EXCLUDED_HEADER: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+

+      if (!CurrentModule)

+        break;

+      

+      // FIXME: Be more lazy about this!

+      StringRef FileName(BlobStart, BlobLen);

+      if (const FileEntry *File = PP.getFileManager().getFile(FileName)) {

+        if (std::find(CurrentModule->Headers.begin(), 

+                      CurrentModule->Headers.end(), 

+                      File) == CurrentModule->Headers.end())

+          ModMap.addHeader(CurrentModule, File, true);

+      }

+      break;      

+    }

+

+    case SUBMODULE_TOPHEADER: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+

+      if (!CurrentModule)

+        break;

+

+      // FIXME: Be more lazy about this!

+      StringRef FileName(BlobStart, BlobLen);

+      if (const FileEntry *File = PP.getFileManager().getFile(FileName))

+        CurrentModule->TopHeaders.insert(File);

+      break;

+    }

+

+    case SUBMODULE_UMBRELLA_DIR: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+      

+      if (!CurrentModule)

+        break;

+      

+      StringRef DirName(BlobStart, BlobLen);

+      if (const DirectoryEntry *Umbrella

+                                  = PP.getFileManager().getDirectory(DirName)) {

+        if (!CurrentModule->getUmbrellaDir())

+          ModMap.setUmbrellaDir(CurrentModule, Umbrella);

+        else if (CurrentModule->getUmbrellaDir() != Umbrella) {

+          Error("mismatched umbrella directories in submodule");

+          return true;

+        }

+      }

+      break;

+    }

+        

+    case SUBMODULE_METADATA: {

+      if (!First) {

+        Error("submodule metadata record not at beginning of block");

+        return true;

+      }

+      First = false;

+      

+      F.BaseSubmoduleID = getTotalNumSubmodules();

+      F.LocalNumSubmodules = Record[0];

+      unsigned LocalBaseSubmoduleID = Record[1];

+      if (F.LocalNumSubmodules > 0) {

+        // Introduce the global -> local mapping for submodules within this 

+        // module.

+        GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F));

+        

+        // Introduce the local -> global mapping for submodules within this 

+        // module.

+        F.SubmoduleRemap.insertOrReplace(

+          std::make_pair(LocalBaseSubmoduleID,

+                         F.BaseSubmoduleID - LocalBaseSubmoduleID));

+        

+        SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);

+      }      

+      break;

+    }

+        

+    case SUBMODULE_IMPORTS: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+      

+      if (!CurrentModule)

+        break;

+      

+      for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {

+        UnresolvedModuleImportExport Unresolved;

+        Unresolved.File = &F;

+        Unresolved.Mod = CurrentModule;

+        Unresolved.ID = Record[Idx];

+        Unresolved.IsImport = true;

+        Unresolved.IsWildcard = false;

+        UnresolvedModuleImportExports.push_back(Unresolved);

+      }

+      break;

+    }

+

+    case SUBMODULE_EXPORTS: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+      

+      if (!CurrentModule)

+        break;

+      

+      for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {

+        UnresolvedModuleImportExport Unresolved;

+        Unresolved.File = &F;

+        Unresolved.Mod = CurrentModule;

+        Unresolved.ID = Record[Idx];

+        Unresolved.IsImport = false;

+        Unresolved.IsWildcard = Record[Idx + 1];

+        UnresolvedModuleImportExports.push_back(Unresolved);

+      }

+      

+      // Once we've loaded the set of exports, there's no reason to keep 

+      // the parsed, unresolved exports around.

+      CurrentModule->UnresolvedExports.clear();

+      break;

+    }

+    case SUBMODULE_REQUIRES: {

+      if (First) {

+        Error("missing submodule metadata record at beginning of block");

+        return true;

+      }

+

+      if (!CurrentModule)

+        break;

+

+      CurrentModule->addRequirement(StringRef(BlobStart, BlobLen), 

+                                    Context.getLangOpts(),

+                                    Context.getTargetInfo());

+      break;

+    }

+    }

+  }

+}

+

+/// \brief Parse the record that corresponds to a LangOptions data

+/// structure.

+///

+/// This routine parses the language options from the AST file and then gives

+/// them to the AST listener if one is set.

+///

+/// \returns true if the listener deems the file unacceptable, false otherwise.

+bool ASTReader::ParseLanguageOptions(const RecordData &Record,

+                                     bool Complain,

+                                     ASTReaderListener &Listener) {

+  LangOptions LangOpts;

+  unsigned Idx = 0;

+#define LANGOPT(Name, Bits, Default, Description) \

+  LangOpts.Name = Record[Idx++];

+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \

+  LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));

+#include "clang/Basic/LangOptions.def"

+

+  ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];

+  VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx);

+  LangOpts.ObjCRuntime = ObjCRuntime(runtimeKind, runtimeVersion);

+  

+  unsigned Length = Record[Idx++];

+  LangOpts.CurrentModule.assign(Record.begin() + Idx, 

+                                Record.begin() + Idx + Length);

+  return Listener.ReadLanguageOptions(LangOpts, Complain);

+}

+

+bool ASTReader::ParseTargetOptions(const RecordData &Record,

+                                   bool Complain,

+                                   ASTReaderListener &Listener) {

+  unsigned Idx = 0;

+  TargetOptions TargetOpts;

+  TargetOpts.Triple = ReadString(Record, Idx);

+  TargetOpts.CPU = ReadString(Record, Idx);

+  TargetOpts.ABI = ReadString(Record, Idx);

+  TargetOpts.CXXABI = ReadString(Record, Idx);

+  TargetOpts.LinkerVersion = ReadString(Record, Idx);

+  for (unsigned N = Record[Idx++]; N; --N) {

+    TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));

+  }

+  for (unsigned N = Record[Idx++]; N; --N) {

+    TargetOpts.Features.push_back(ReadString(Record, Idx));

+  }

+

+  return Listener.ReadTargetOptions(TargetOpts, Complain);

+}

+

+bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,

+                                       ASTReaderListener &Listener) {

+  DiagnosticOptions DiagOpts;

+  unsigned Idx = 0;

+#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];

+#define ENUM_DIAGOPT(Name, Type, Bits, Default) \

+  DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));

+#include "clang/Basic/DiagnosticOptions.def"

+

+  for (unsigned N = Record[Idx++]; N; --N) {

+    DiagOpts.Warnings.push_back(ReadString(Record, Idx));

+  }

+

+  return Listener.ReadDiagnosticOptions(DiagOpts, Complain);

+}

+

+bool ASTReader::ParseFileSystemOptions(const RecordData &Record, bool Complain,

+                                       ASTReaderListener &Listener) {

+  FileSystemOptions FSOpts;

+  unsigned Idx = 0;

+  FSOpts.WorkingDir = ReadString(Record, Idx);

+  return Listener.ReadFileSystemOptions(FSOpts, Complain);

+}

+

+bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,

+                                         bool Complain,

+                                         ASTReaderListener &Listener) {

+  HeaderSearchOptions HSOpts;

+  unsigned Idx = 0;

+  HSOpts.Sysroot = ReadString(Record, Idx);

+

+  // Include entries.

+  for (unsigned N = Record[Idx++]; N; --N) {

+    std::string Path = ReadString(Record, Idx);

+    frontend::IncludeDirGroup Group

+      = static_cast<frontend::IncludeDirGroup>(Record[Idx++]);

+    bool IsUserSupplied = Record[Idx++];

+    bool IsFramework = Record[Idx++];

+    bool IgnoreSysRoot = Record[Idx++];

+    bool IsInternal = Record[Idx++];

+    bool ImplicitExternC = Record[Idx++];

+    HSOpts.UserEntries.push_back(

+      HeaderSearchOptions::Entry(Path, Group, IsUserSupplied, IsFramework,

+                                 IgnoreSysRoot, IsInternal, ImplicitExternC));

+  }

+

+  // System header prefixes.

+  for (unsigned N = Record[Idx++]; N; --N) {

+    std::string Prefix = ReadString(Record, Idx);

+    bool IsSystemHeader = Record[Idx++];

+    HSOpts.SystemHeaderPrefixes.push_back(

+      HeaderSearchOptions::SystemHeaderPrefix(Prefix, IsSystemHeader));

+  }

+

+  HSOpts.ResourceDir = ReadString(Record, Idx);

+  HSOpts.ModuleCachePath = ReadString(Record, Idx);

+  HSOpts.DisableModuleHash = Record[Idx++];

+  HSOpts.UseBuiltinIncludes = Record[Idx++];

+  HSOpts.UseStandardSystemIncludes = Record[Idx++];

+  HSOpts.UseStandardCXXIncludes = Record[Idx++];

+  HSOpts.UseLibcxx = Record[Idx++];

+

+  return Listener.ReadHeaderSearchOptions(HSOpts, Complain);

+}

+

+bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,

+                                         bool Complain,

+                                         ASTReaderListener &Listener,

+                                         std::string &SuggestedPredefines) {

+  PreprocessorOptions PPOpts;

+  unsigned Idx = 0;

+

+  // Macro definitions/undefs

+  for (unsigned N = Record[Idx++]; N; --N) {

+    std::string Macro = ReadString(Record, Idx);

+    bool IsUndef = Record[Idx++];

+    PPOpts.Macros.push_back(std::make_pair(Macro, IsUndef));

+  }

+

+  // Includes

+  for (unsigned N = Record[Idx++]; N; --N) {

+    PPOpts.Includes.push_back(ReadString(Record, Idx));

+  }

+

+  // Macro Includes

+  for (unsigned N = Record[Idx++]; N; --N) {

+    PPOpts.MacroIncludes.push_back(ReadString(Record, Idx));

+  }

+

+  PPOpts.UsePredefines = Record[Idx++];

+  PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);

+  PPOpts.ImplicitPTHInclude = ReadString(Record, Idx);

+  PPOpts.ObjCXXARCStandardLibrary =

+    static_cast<ObjCXXARCStandardLibraryKind>(Record[Idx++]);

+  SuggestedPredefines.clear();

+  return Listener.ReadPreprocessorOptions(PPOpts, Complain,

+                                          SuggestedPredefines);

+}

+

+std::pair<ModuleFile *, unsigned>

+ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {

+  GlobalPreprocessedEntityMapType::iterator

+  I = GlobalPreprocessedEntityMap.find(GlobalIndex);

+  assert(I != GlobalPreprocessedEntityMap.end() && 

+         "Corrupted global preprocessed entity map");

+  ModuleFile *M = I->second;

+  unsigned LocalIndex = GlobalIndex - M->BasePreprocessedEntityID;

+  return std::make_pair(M, LocalIndex);

+}

+

+std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>

+ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {

+  if (PreprocessingRecord *PPRec = PP.getPreprocessingRecord())

+    return PPRec->getIteratorsForLoadedRange(Mod.BasePreprocessedEntityID,

+                                             Mod.NumPreprocessedEntities);

+

+  return std::make_pair(PreprocessingRecord::iterator(),

+                        PreprocessingRecord::iterator());

+}

+

+std::pair<ASTReader::ModuleDeclIterator, ASTReader::ModuleDeclIterator>

+ASTReader::getModuleFileLevelDecls(ModuleFile &Mod) {

+  return std::make_pair(ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls),

+                        ModuleDeclIterator(this, &Mod,

+                                 Mod.FileSortedDecls + Mod.NumFileSortedDecls));

+}

+

+PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {

+  PreprocessedEntityID PPID = Index+1;

+  std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);

+  ModuleFile &M = *PPInfo.first;

+  unsigned LocalIndex = PPInfo.second;

+  const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];

+

+  SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);  

+  M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);

+

+  unsigned Code = M.PreprocessorDetailCursor.ReadCode();

+  switch (Code) {

+  case llvm::bitc::END_BLOCK:

+    return 0;

+    

+  case llvm::bitc::ENTER_SUBBLOCK:

+    Error("unexpected subblock record in preprocessor detail block");

+    return 0;

+      

+  case llvm::bitc::DEFINE_ABBREV:

+    Error("unexpected abbrevation record in preprocessor detail block");

+    return 0;

+      

+  default:

+    break;

+  }

+

+  if (!PP.getPreprocessingRecord()) {

+    Error("no preprocessing record");

+    return 0;

+  }

+  

+  // Read the record.

+  SourceRange Range(ReadSourceLocation(M, PPOffs.Begin),

+                    ReadSourceLocation(M, PPOffs.End));

+  PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();

+  const char *BlobStart = 0;

+  unsigned BlobLen = 0;

+  RecordData Record;

+  PreprocessorDetailRecordTypes RecType =

+    (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.ReadRecord(

+                                             Code, Record, BlobStart, BlobLen);

+  switch (RecType) {

+  case PPD_MACRO_EXPANSION: {

+    bool isBuiltin = Record[0];

+    IdentifierInfo *Name = 0;

+    MacroDefinition *Def = 0;

+    if (isBuiltin)

+      Name = getLocalIdentifier(M, Record[1]);

+    else {

+      PreprocessedEntityID

+          GlobalID = getGlobalPreprocessedEntityID(M, Record[1]);

+      Def =cast<MacroDefinition>(PPRec.getLoadedPreprocessedEntity(GlobalID-1));

+    }

+

+    MacroExpansion *ME;

+    if (isBuiltin)

+      ME = new (PPRec) MacroExpansion(Name, Range);

+    else

+      ME = new (PPRec) MacroExpansion(Def, Range);

+

+    return ME;

+  }

+      

+  case PPD_MACRO_DEFINITION: {

+    // Decode the identifier info and then check again; if the macro is

+    // still defined and associated with the identifier,

+    IdentifierInfo *II = getLocalIdentifier(M, Record[0]);

+    MacroDefinition *MD

+      = new (PPRec) MacroDefinition(II, Range);

+

+    if (DeserializationListener)

+      DeserializationListener->MacroDefinitionRead(PPID, MD);

+

+    return MD;

+  }

+      

+  case PPD_INCLUSION_DIRECTIVE: {

+    const char *FullFileNameStart = BlobStart + Record[0];

+    StringRef FullFileName(FullFileNameStart, BlobLen - Record[0]);

+    const FileEntry *File = 0;

+    if (!FullFileName.empty())

+      File = PP.getFileManager().getFile(FullFileName);

+    

+    // FIXME: Stable encoding

+    InclusionDirective::InclusionKind Kind

+      = static_cast<InclusionDirective::InclusionKind>(Record[2]);

+    InclusionDirective *ID

+      = new (PPRec) InclusionDirective(PPRec, Kind,

+                                       StringRef(BlobStart, Record[0]),

+                                       Record[1], Record[3],

+                                       File,

+                                       Range);

+    return ID;

+  }

+  }

+

+  llvm_unreachable("Invalid PreprocessorDetailRecordTypes");

+}

+

+/// \brief \arg SLocMapI points at a chunk of a module that contains no

+/// preprocessed entities or the entities it contains are not the ones we are

+/// looking for. Find the next module that contains entities and return the ID

+/// of the first entry.

+PreprocessedEntityID ASTReader::findNextPreprocessedEntity(

+                       GlobalSLocOffsetMapType::const_iterator SLocMapI) const {

+  ++SLocMapI;

+  for (GlobalSLocOffsetMapType::const_iterator

+         EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {

+    ModuleFile &M = *SLocMapI->second;

+    if (M.NumPreprocessedEntities)

+      return M.BasePreprocessedEntityID;

+  }

+

+  return getTotalNumPreprocessedEntities();

+}

+

+namespace {

+

+template <unsigned PPEntityOffset::*PPLoc>

+struct PPEntityComp {

+  const ASTReader &Reader;

+  ModuleFile &M;

+

+  PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) { }

+

+  bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const {

+    SourceLocation LHS = getLoc(L);

+    SourceLocation RHS = getLoc(R);

+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);

+  }

+

+  bool operator()(const PPEntityOffset &L, SourceLocation RHS) const {

+    SourceLocation LHS = getLoc(L);

+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);

+  }

+

+  bool operator()(SourceLocation LHS, const PPEntityOffset &R) const {

+    SourceLocation RHS = getLoc(R);

+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);

+  }

+

+  SourceLocation getLoc(const PPEntityOffset &PPE) const {

+    return Reader.ReadSourceLocation(M, PPE.*PPLoc);

+  }

+};

+

+}

+

+/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.

+PreprocessedEntityID

+ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {

+  if (SourceMgr.isLocalSourceLocation(BLoc))

+    return getTotalNumPreprocessedEntities();

+

+  GlobalSLocOffsetMapType::const_iterator

+    SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -

+                                        BLoc.getOffset());

+  assert(SLocMapI != GlobalSLocOffsetMap.end() &&

+         "Corrupted global sloc offset map");

+

+  if (SLocMapI->second->NumPreprocessedEntities == 0)

+    return findNextPreprocessedEntity(SLocMapI);

+

+  ModuleFile &M = *SLocMapI->second;

+  typedef const PPEntityOffset *pp_iterator;

+  pp_iterator pp_begin = M.PreprocessedEntityOffsets;

+  pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;

+

+  size_t Count = M.NumPreprocessedEntities;

+  size_t Half;

+  pp_iterator First = pp_begin;

+  pp_iterator PPI;

+

+  // Do a binary search manually instead of using std::lower_bound because

+  // The end locations of entities may be unordered (when a macro expansion

+  // is inside another macro argument), but for this case it is not important

+  // whether we get the first macro expansion or its containing macro.

+  while (Count > 0) {

+    Half = Count/2;

+    PPI = First;

+    std::advance(PPI, Half);

+    if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),

+                                            BLoc)){

+      First = PPI;

+      ++First;

+      Count = Count - Half - 1;

+    } else

+      Count = Half;

+  }

+

+  if (PPI == pp_end)

+    return findNextPreprocessedEntity(SLocMapI);

+

+  return M.BasePreprocessedEntityID + (PPI - pp_begin);

+}

+

+/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.

+PreprocessedEntityID

+ASTReader::findEndPreprocessedEntity(SourceLocation ELoc) const {

+  if (SourceMgr.isLocalSourceLocation(ELoc))

+    return getTotalNumPreprocessedEntities();

+

+  GlobalSLocOffsetMapType::const_iterator

+    SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -

+                                        ELoc.getOffset());

+  assert(SLocMapI != GlobalSLocOffsetMap.end() &&

+         "Corrupted global sloc offset map");

+

+  if (SLocMapI->second->NumPreprocessedEntities == 0)

+    return findNextPreprocessedEntity(SLocMapI);

+

+  ModuleFile &M = *SLocMapI->second;

+  typedef const PPEntityOffset *pp_iterator;

+  pp_iterator pp_begin = M.PreprocessedEntityOffsets;

+  pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;

+  pp_iterator PPI =

+      std::upper_bound(pp_begin, pp_end, ELoc,

+                       PPEntityComp<&PPEntityOffset::Begin>(*this, M));

+

+  if (PPI == pp_end)

+    return findNextPreprocessedEntity(SLocMapI);

+

+  return M.BasePreprocessedEntityID + (PPI - pp_begin);

+}

+

+/// \brief Returns a pair of [Begin, End) indices of preallocated

+/// preprocessed entities that \arg Range encompasses.

+std::pair<unsigned, unsigned>

+    ASTReader::findPreprocessedEntitiesInRange(SourceRange Range) {

+  if (Range.isInvalid())

+    return std::make_pair(0,0);

+  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));

+

+  PreprocessedEntityID BeginID = findBeginPreprocessedEntity(Range.getBegin());

+  PreprocessedEntityID EndID = findEndPreprocessedEntity(Range.getEnd());

+  return std::make_pair(BeginID, EndID);

+}

+

+/// \brief Optionally returns true or false if the preallocated preprocessed

+/// entity with index \arg Index came from file \arg FID.

+llvm::Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,

+                                                             FileID FID) {

+  if (FID.isInvalid())

+    return false;

+

+  std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);

+  ModuleFile &M = *PPInfo.first;

+  unsigned LocalIndex = PPInfo.second;

+  const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];

+  

+  SourceLocation Loc = ReadSourceLocation(M, PPOffs.Begin);

+  if (Loc.isInvalid())

+    return false;

+  

+  if (SourceMgr.isInFileID(SourceMgr.getFileLoc(Loc), FID))

+    return true;

+  else

+    return false;

+}

+

+namespace {

+  /// \brief Visitor used to search for information about a header file.

+  class HeaderFileInfoVisitor {

+    ASTReader &Reader;

+    const FileEntry *FE;

+    

+    llvm::Optional<HeaderFileInfo> HFI;

+    

+  public:

+    HeaderFileInfoVisitor(ASTReader &Reader, const FileEntry *FE)

+      : Reader(Reader), FE(FE) { }

+    

+    static bool visit(ModuleFile &M, void *UserData) {

+      HeaderFileInfoVisitor *This

+        = static_cast<HeaderFileInfoVisitor *>(UserData);

+      

+      HeaderFileInfoTrait Trait(This->Reader, M, 

+                                &This->Reader.getPreprocessor().getHeaderSearchInfo(),

+                                M.HeaderFileFrameworkStrings,

+                                This->FE->getName());

+      

+      HeaderFileInfoLookupTable *Table

+        = static_cast<HeaderFileInfoLookupTable *>(M.HeaderFileInfoTable);

+      if (!Table)

+        return false;

+

+      // Look in the on-disk hash table for an entry for this file name.

+      HeaderFileInfoLookupTable::iterator Pos = Table->find(This->FE->getName(),

+                                                            &Trait);

+      if (Pos == Table->end())

+        return false;

+

+      This->HFI = *Pos;

+      return true;

+    }

+    

+    llvm::Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }

+  };

+}

+

+HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {

+  HeaderFileInfoVisitor Visitor(*this, FE);

+  ModuleMgr.visit(&HeaderFileInfoVisitor::visit, &Visitor);

+  if (llvm::Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) {

+    if (Listener)

+      Listener->ReadHeaderFileInfo(*HFI, FE->getUID());

+    return *HFI;

+  }

+  

+  return HeaderFileInfo();

+}

+

+void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {

+  // FIXME: Make it work properly with modules.

+  llvm::SmallVector<DiagnosticsEngine::DiagState *, 32> DiagStates;

+  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {

+    ModuleFile &F = *(*I);

+    unsigned Idx = 0;

+    DiagStates.clear();

+    assert(!Diag.DiagStates.empty());

+    DiagStates.push_back(&Diag.DiagStates.front()); // the command-line one.

+    while (Idx < F.PragmaDiagMappings.size()) {

+      SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);

+      unsigned DiagStateID = F.PragmaDiagMappings[Idx++];

+      if (DiagStateID != 0) {

+        Diag.DiagStatePoints.push_back(

+                    DiagnosticsEngine::DiagStatePoint(DiagStates[DiagStateID-1],

+                    FullSourceLoc(Loc, SourceMgr)));

+        continue;

+      }

+      

+      assert(DiagStateID == 0);

+      // A new DiagState was created here.

+      Diag.DiagStates.push_back(*Diag.GetCurDiagState());

+      DiagnosticsEngine::DiagState *NewState = &Diag.DiagStates.back();

+      DiagStates.push_back(NewState);

+      Diag.DiagStatePoints.push_back(

+          DiagnosticsEngine::DiagStatePoint(NewState,

+                                            FullSourceLoc(Loc, SourceMgr)));

+      while (1) {

+        assert(Idx < F.PragmaDiagMappings.size() &&

+               "Invalid data, didn't find '-1' marking end of diag/map pairs");

+        if (Idx >= F.PragmaDiagMappings.size()) {

+          break; // Something is messed up but at least avoid infinite loop in

+                 // release build.

+        }

+        unsigned DiagID = F.PragmaDiagMappings[Idx++];

+        if (DiagID == (unsigned)-1) {

+          break; // no more diag/map pairs for this location.

+        }

+        diag::Mapping Map = (diag::Mapping)F.PragmaDiagMappings[Idx++];

+        DiagnosticMappingInfo MappingInfo = Diag.makeMappingInfo(Map, Loc);

+        Diag.GetCurDiagState()->setMappingInfo(DiagID, MappingInfo);

+      }

+    }

+  }

+}

+

+/// \brief Get the correct cursor and offset for loading a type.

+ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {

+  GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index);

+  assert(I != GlobalTypeMap.end() && "Corrupted global type map");

+  ModuleFile *M = I->second;

+  return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]);

+}

+

+/// \brief Read and return the type with the given index..

+///

+/// The index is the type ID, shifted and minus the number of predefs. This

+/// routine actually reads the record corresponding to the type at the given

+/// location. It is a helper routine for GetType, which deals with reading type

+/// IDs.

+QualType ASTReader::readTypeRecord(unsigned Index) {

+  RecordLocation Loc = TypeCursorForIndex(Index);

+  llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;

+

+  // Keep track of where we are in the stream, then jump back there

+  // after reading this type.

+  SavedStreamPosition SavedPosition(DeclsCursor);

+

+  ReadingKindTracker ReadingKind(Read_Type, *this);

+

+  // Note that we are loading a type record.

+  Deserializing AType(this);

+

+  unsigned Idx = 0;

+  DeclsCursor.JumpToBit(Loc.Offset);

+  RecordData Record;

+  unsigned Code = DeclsCursor.ReadCode();

+  switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {

+  case TYPE_EXT_QUAL: {

+    if (Record.size() != 2) {

+      Error("Incorrect encoding of extended qualifier type");

+      return QualType();

+    }

+    QualType Base = readType(*Loc.F, Record, Idx);

+    Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[Idx++]);

+    return Context.getQualifiedType(Base, Quals);

+  }

+

+  case TYPE_COMPLEX: {

+    if (Record.size() != 1) {

+      Error("Incorrect encoding of complex type");

+      return QualType();

+    }

+    QualType ElemType = readType(*Loc.F, Record, Idx);

+    return Context.getComplexType(ElemType);

+  }

+

+  case TYPE_POINTER: {

+    if (Record.size() != 1) {

+      Error("Incorrect encoding of pointer type");

+      return QualType();

+    }

+    QualType PointeeType = readType(*Loc.F, Record, Idx);

+    return Context.getPointerType(PointeeType);

+  }

+

+  case TYPE_BLOCK_POINTER: {

+    if (Record.size() != 1) {

+      Error("Incorrect encoding of block pointer type");

+      return QualType();

+    }

+    QualType PointeeType = readType(*Loc.F, Record, Idx);

+    return Context.getBlockPointerType(PointeeType);

+  }

+

+  case TYPE_LVALUE_REFERENCE: {

+    if (Record.size() != 2) {

+      Error("Incorrect encoding of lvalue reference type");

+      return QualType();

+    }

+    QualType PointeeType = readType(*Loc.F, Record, Idx);

+    return Context.getLValueReferenceType(PointeeType, Record[1]);

+  }

+

+  case TYPE_RVALUE_REFERENCE: {

+    if (Record.size() != 1) {

+      Error("Incorrect encoding of rvalue reference type");

+      return QualType();

+    }

+    QualType PointeeType = readType(*Loc.F, Record, Idx);

+    return Context.getRValueReferenceType(PointeeType);

+  }

+

+  case TYPE_MEMBER_POINTER: {

+    if (Record.size() != 2) {

+      Error("Incorrect encoding of member pointer type");

+      return QualType();

+    }

+    QualType PointeeType = readType(*Loc.F, Record, Idx);

+    QualType ClassType = readType(*Loc.F, Record, Idx);

+    if (PointeeType.isNull() || ClassType.isNull())

+      return QualType();

+    

+    return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());

+  }

+

+  case TYPE_CONSTANT_ARRAY: {

+    QualType ElementType = readType(*Loc.F, Record, Idx);

+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];

+    unsigned IndexTypeQuals = Record[2];

+    unsigned Idx = 3;

+    llvm::APInt Size = ReadAPInt(Record, Idx);

+    return Context.getConstantArrayType(ElementType, Size,

+                                         ASM, IndexTypeQuals);

+  }

+

+  case TYPE_INCOMPLETE_ARRAY: {

+    QualType ElementType = readType(*Loc.F, Record, Idx);

+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];

+    unsigned IndexTypeQuals = Record[2];

+    return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);

+  }

+

+  case TYPE_VARIABLE_ARRAY: {

+    QualType ElementType = readType(*Loc.F, Record, Idx);

+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];

+    unsigned IndexTypeQuals = Record[2];

+    SourceLocation LBLoc = ReadSourceLocation(*Loc.F, Record[3]);

+    SourceLocation RBLoc = ReadSourceLocation(*Loc.F, Record[4]);

+    return Context.getVariableArrayType(ElementType, ReadExpr(*Loc.F),

+                                         ASM, IndexTypeQuals,

+                                         SourceRange(LBLoc, RBLoc));

+  }

+

+  case TYPE_VECTOR: {

+    if (Record.size() != 3) {

+      Error("incorrect encoding of vector type in AST file");

+      return QualType();

+    }

+

+    QualType ElementType = readType(*Loc.F, Record, Idx);

+    unsigned NumElements = Record[1];

+    unsigned VecKind = Record[2];

+    return Context.getVectorType(ElementType, NumElements,

+                                  (VectorType::VectorKind)VecKind);

+  }

+

+  case TYPE_EXT_VECTOR: {

+    if (Record.size() != 3) {

+      Error("incorrect encoding of extended vector type in AST file");

+      return QualType();

+    }

+

+    QualType ElementType = readType(*Loc.F, Record, Idx);

+    unsigned NumElements = Record[1];

+    return Context.getExtVectorType(ElementType, NumElements);

+  }

+

+  case TYPE_FUNCTION_NO_PROTO: {

+    if (Record.size() != 6) {

+      Error("incorrect encoding of no-proto function type");

+      return QualType();

+    }

+    QualType ResultType = readType(*Loc.F, Record, Idx);

+    FunctionType::ExtInfo Info(Record[1], Record[2], Record[3],

+                               (CallingConv)Record[4], Record[5]);

+    return Context.getFunctionNoProtoType(ResultType, Info);

+  }

+

+  case TYPE_FUNCTION_PROTO: {

+    QualType ResultType = readType(*Loc.F, Record, Idx);

+

+    FunctionProtoType::ExtProtoInfo EPI;

+    EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1],

+                                        /*hasregparm*/ Record[2],

+                                        /*regparm*/ Record[3],

+                                        static_cast<CallingConv>(Record[4]),

+                                        /*produces*/ Record[5]);

+

+    unsigned Idx = 6;

+    unsigned NumParams = Record[Idx++];

+    SmallVector<QualType, 16> ParamTypes;

+    for (unsigned I = 0; I != NumParams; ++I)

+      ParamTypes.push_back(readType(*Loc.F, Record, Idx));

+

+    EPI.Variadic = Record[Idx++];

+    EPI.HasTrailingReturn = Record[Idx++];

+    EPI.TypeQuals = Record[Idx++];

+    EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);

+    ExceptionSpecificationType EST =

+        static_cast<ExceptionSpecificationType>(Record[Idx++]);

+    EPI.ExceptionSpecType = EST;

+    SmallVector<QualType, 2> Exceptions;

+    if (EST == EST_Dynamic) {

+      EPI.NumExceptions = Record[Idx++];

+      for (unsigned I = 0; I != EPI.NumExceptions; ++I)

+        Exceptions.push_back(readType(*Loc.F, Record, Idx));

+      EPI.Exceptions = Exceptions.data();

+    } else if (EST == EST_ComputedNoexcept) {

+      EPI.NoexceptExpr = ReadExpr(*Loc.F);

+    } else if (EST == EST_Uninstantiated) {

+      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);

+      EPI.ExceptionSpecTemplate = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);

+    } else if (EST == EST_Unevaluated) {

+      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);

+    }

+    return Context.getFunctionType(ResultType, ParamTypes.data(), NumParams,

+                                    EPI);

+  }

+

+  case TYPE_UNRESOLVED_USING: {

+    unsigned Idx = 0;

+    return Context.getTypeDeclType(

+                  ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx));

+  }

+      

+  case TYPE_TYPEDEF: {

+    if (Record.size() != 2) {

+      Error("incorrect encoding of typedef type");

+      return QualType();

+    }

+    unsigned Idx = 0;

+    TypedefNameDecl *Decl = ReadDeclAs<TypedefNameDecl>(*Loc.F, Record, Idx);

+    QualType Canonical = readType(*Loc.F, Record, Idx);

+    if (!Canonical.isNull())

+      Canonical = Context.getCanonicalType(Canonical);

+    return Context.getTypedefType(Decl, Canonical);

+  }

+

+  case TYPE_TYPEOF_EXPR:

+    return Context.getTypeOfExprType(ReadExpr(*Loc.F));

+

+  case TYPE_TYPEOF: {

+    if (Record.size() != 1) {

+      Error("incorrect encoding of typeof(type) in AST file");

+      return QualType();

+    }

+    QualType UnderlyingType = readType(*Loc.F, Record, Idx);

+    return Context.getTypeOfType(UnderlyingType);

+  }

+

+  case TYPE_DECLTYPE: {

+    QualType UnderlyingType = readType(*Loc.F, Record, Idx);

+    return Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType);

+  }

+

+  case TYPE_UNARY_TRANSFORM: {

+    QualType BaseType = readType(*Loc.F, Record, Idx);

+    QualType UnderlyingType = readType(*Loc.F, Record, Idx);

+    UnaryTransformType::UTTKind UKind = (UnaryTransformType::UTTKind)Record[2];

+    return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind);

+  }

+

+  case TYPE_AUTO:

+    return Context.getAutoType(readType(*Loc.F, Record, Idx));

+

+  case TYPE_RECORD: {

+    if (Record.size() != 2) {

+      Error("incorrect encoding of record type");

+      return QualType();

+    }

+    unsigned Idx = 0;

+    bool IsDependent = Record[Idx++];

+    RecordDecl *RD = ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx);

+    RD = cast_or_null<RecordDecl>(RD->getCanonicalDecl());

+    QualType T = Context.getRecordType(RD);

+    const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);

+    return T;

+  }

+

+  case TYPE_ENUM: {

+    if (Record.size() != 2) {

+      Error("incorrect encoding of enum type");

+      return QualType();

+    }

+    unsigned Idx = 0;

+    bool IsDependent = Record[Idx++];

+    QualType T

+      = Context.getEnumType(ReadDeclAs<EnumDecl>(*Loc.F, Record, Idx));

+    const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);

+    return T;

+  }

+

+  case TYPE_ATTRIBUTED: {

+    if (Record.size() != 3) {

+      Error("incorrect encoding of attributed type");

+      return QualType();

+    }

+    QualType modifiedType = readType(*Loc.F, Record, Idx);

+    QualType equivalentType = readType(*Loc.F, Record, Idx);

+    AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);

+    return Context.getAttributedType(kind, modifiedType, equivalentType);

+  }

+

+  case TYPE_PAREN: {

+    if (Record.size() != 1) {

+      Error("incorrect encoding of paren type");

+      return QualType();

+    }

+    QualType InnerType = readType(*Loc.F, Record, Idx);

+    return Context.getParenType(InnerType);

+  }

+

+  case TYPE_PACK_EXPANSION: {

+    if (Record.size() != 2) {

+      Error("incorrect encoding of pack expansion type");

+      return QualType();

+    }

+    QualType Pattern = readType(*Loc.F, Record, Idx);

+    if (Pattern.isNull())

+      return QualType();

+    llvm::Optional<unsigned> NumExpansions;

+    if (Record[1])

+      NumExpansions = Record[1] - 1;

+    return Context.getPackExpansionType(Pattern, NumExpansions);

+  }

+

+  case TYPE_ELABORATED: {

+    unsigned Idx = 0;

+    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];

+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);

+    QualType NamedType = readType(*Loc.F, Record, Idx);

+    return Context.getElaboratedType(Keyword, NNS, NamedType);

+  }

+

+  case TYPE_OBJC_INTERFACE: {

+    unsigned Idx = 0;

+    ObjCInterfaceDecl *ItfD

+      = ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);

+    return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());

+  }

+

+  case TYPE_OBJC_OBJECT: {

+    unsigned Idx = 0;

+    QualType Base = readType(*Loc.F, Record, Idx);

+    unsigned NumProtos = Record[Idx++];

+    SmallVector<ObjCProtocolDecl*, 4> Protos;

+    for (unsigned I = 0; I != NumProtos; ++I)

+      Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));

+    return Context.getObjCObjectType(Base, Protos.data(), NumProtos);

+  }

+

+  case TYPE_OBJC_OBJECT_POINTER: {

+    unsigned Idx = 0;

+    QualType Pointee = readType(*Loc.F, Record, Idx);

+    return Context.getObjCObjectPointerType(Pointee);

+  }

+

+  case TYPE_SUBST_TEMPLATE_TYPE_PARM: {

+    unsigned Idx = 0;

+    QualType Parm = readType(*Loc.F, Record, Idx);

+    QualType Replacement = readType(*Loc.F, Record, Idx);

+    return

+      Context.getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),

+                                            Replacement);

+  }

+

+  case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {

+    unsigned Idx = 0;

+    QualType Parm = readType(*Loc.F, Record, Idx);

+    TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx);

+    return Context.getSubstTemplateTypeParmPackType(

+                                               cast<TemplateTypeParmType>(Parm),

+                                                     ArgPack);

+  }

+

+  case TYPE_INJECTED_CLASS_NAME: {

+    CXXRecordDecl *D = ReadDeclAs<CXXRecordDecl>(*Loc.F, Record, Idx);

+    QualType TST = readType(*Loc.F, Record, Idx); // probably derivable

+    // FIXME: ASTContext::getInjectedClassNameType is not currently suitable

+    // for AST reading, too much interdependencies.

+    return

+      QualType(new (Context, TypeAlignment) InjectedClassNameType(D, TST), 0);

+  }

+

+  case TYPE_TEMPLATE_TYPE_PARM: {

+    unsigned Idx = 0;

+    unsigned Depth = Record[Idx++];

+    unsigned Index = Record[Idx++];

+    bool Pack = Record[Idx++];

+    TemplateTypeParmDecl *D

+      = ReadDeclAs<TemplateTypeParmDecl>(*Loc.F, Record, Idx);

+    return Context.getTemplateTypeParmType(Depth, Index, Pack, D);

+  }

+

+  case TYPE_DEPENDENT_NAME: {

+    unsigned Idx = 0;

+    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];

+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);

+    const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);

+    QualType Canon = readType(*Loc.F, Record, Idx);

+    if (!Canon.isNull())

+      Canon = Context.getCanonicalType(Canon);

+    return Context.getDependentNameType(Keyword, NNS, Name, Canon);

+  }

+

+  case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {

+    unsigned Idx = 0;

+    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];

+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);

+    const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);

+    unsigned NumArgs = Record[Idx++];

+    SmallVector<TemplateArgument, 8> Args;

+    Args.reserve(NumArgs);

+    while (NumArgs--)

+      Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx));

+    return Context.getDependentTemplateSpecializationType(Keyword, NNS, Name,

+                                                      Args.size(), Args.data());

+  }

+

+  case TYPE_DEPENDENT_SIZED_ARRAY: {

+    unsigned Idx = 0;

+

+    // ArrayType

+    QualType ElementType = readType(*Loc.F, Record, Idx);

+    ArrayType::ArraySizeModifier ASM

+      = (ArrayType::ArraySizeModifier)Record[Idx++];

+    unsigned IndexTypeQuals = Record[Idx++];

+

+    // DependentSizedArrayType

+    Expr *NumElts = ReadExpr(*Loc.F);

+    SourceRange Brackets = ReadSourceRange(*Loc.F, Record, Idx);

+

+    return Context.getDependentSizedArrayType(ElementType, NumElts, ASM,

+                                               IndexTypeQuals, Brackets);

+  }

+

+  case TYPE_TEMPLATE_SPECIALIZATION: {

+    unsigned Idx = 0;

+    bool IsDependent = Record[Idx++];

+    TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);

+    SmallVector<TemplateArgument, 8> Args;

+    ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);

+    QualType Underlying = readType(*Loc.F, Record, Idx);

+    QualType T;

+    if (Underlying.isNull())

+      T = Context.getCanonicalTemplateSpecializationType(Name, Args.data(),

+                                                          Args.size());

+    else

+      T = Context.getTemplateSpecializationType(Name, Args.data(),

+                                                 Args.size(), Underlying);

+    const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);

+    return T;

+  }

+

+  case TYPE_ATOMIC: {

+    if (Record.size() != 1) {

+      Error("Incorrect encoding of atomic type");

+      return QualType();

+    }

+    QualType ValueType = readType(*Loc.F, Record, Idx);

+    return Context.getAtomicType(ValueType);

+  }

+  }

+  llvm_unreachable("Invalid TypeCode!");

+}

+

+class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {

+  ASTReader &Reader;

+  ModuleFile &F;

+  const ASTReader::RecordData &Record;

+  unsigned &Idx;

+

+  SourceLocation ReadSourceLocation(const ASTReader::RecordData &R,

+                                    unsigned &I) {

+    return Reader.ReadSourceLocation(F, R, I);

+  }

+

+  template<typename T>

+  T *ReadDeclAs(const ASTReader::RecordData &Record, unsigned &Idx) {

+    return Reader.ReadDeclAs<T>(F, Record, Idx);

+  }

+  

+public:

+  TypeLocReader(ASTReader &Reader, ModuleFile &F,

+                const ASTReader::RecordData &Record, unsigned &Idx)

+    : Reader(Reader), F(F), Record(Record), Idx(Idx)

+  { }

+

+  // We want compile-time assurance that we've enumerated all of

+  // these, so unfortunately we have to declare them first, then

+  // define them out-of-line.

+#define ABSTRACT_TYPELOC(CLASS, PARENT)

+#define TYPELOC(CLASS, PARENT) \

+  void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);

+#include "clang/AST/TypeLocNodes.def"

+

+  void VisitFunctionTypeLoc(FunctionTypeLoc);

+  void VisitArrayTypeLoc(ArrayTypeLoc);

+};

+

+void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {

+  // nothing to do

+}

+void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {

+  TL.setBuiltinLoc(ReadSourceLocation(Record, Idx));

+  if (TL.needsExtraLocalData()) {

+    TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));

+    TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));

+    TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));

+    TL.setModeAttr(Record[Idx++]);

+  }

+}

+void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {

+  TL.setStarLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {

+  TL.setCaretLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {

+  TL.setAmpLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {

+  TL.setAmpAmpLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {

+  TL.setStarLoc(ReadSourceLocation(Record, Idx));

+  TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));

+}

+void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {

+  TL.setLBracketLoc(ReadSourceLocation(Record, Idx));

+  TL.setRBracketLoc(ReadSourceLocation(Record, Idx));

+  if (Record[Idx++])

+    TL.setSizeExpr(Reader.ReadExpr(F));

+  else

+    TL.setSizeExpr(0);

+}

+void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {

+  VisitArrayTypeLoc(TL);

+}

+void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {

+  VisitArrayTypeLoc(TL);

+}

+void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {

+  VisitArrayTypeLoc(TL);

+}

+void TypeLocReader::VisitDependentSizedArrayTypeLoc(

+                                            DependentSizedArrayTypeLoc TL) {

+  VisitArrayTypeLoc(TL);

+}

+void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(

+                                        DependentSizedExtVectorTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {

+  TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx));

+  TL.setLParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setRParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx));

+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {

+    TL.setArg(i, ReadDeclAs<ParmVarDecl>(Record, Idx));

+  }

+}

+void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {

+  VisitFunctionTypeLoc(TL);

+}

+void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {

+  VisitFunctionTypeLoc(TL);

+}

+void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {

+  TL.setTypeofLoc(ReadSourceLocation(Record, Idx));

+  TL.setLParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setRParenLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {

+  TL.setTypeofLoc(ReadSourceLocation(Record, Idx));

+  TL.setLParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setRParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));

+}

+void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {

+  TL.setKWLoc(ReadSourceLocation(Record, Idx));

+  TL.setLParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setRParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));

+}

+void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {

+  TL.setAttrNameLoc(ReadSourceLocation(Record, Idx));

+  if (TL.hasAttrOperand()) {

+    SourceRange range;

+    range.setBegin(ReadSourceLocation(Record, Idx));

+    range.setEnd(ReadSourceLocation(Record, Idx));

+    TL.setAttrOperandParensRange(range);

+  }

+  if (TL.hasAttrExprOperand()) {

+    if (Record[Idx++])

+      TL.setAttrExprOperand(Reader.ReadExpr(F));

+    else

+      TL.setAttrExprOperand(0);

+  } else if (TL.hasAttrEnumOperand())

+    TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(

+                                            SubstTemplateTypeParmTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(

+                                          SubstTemplateTypeParmPackTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitTemplateSpecializationTypeLoc(

+                                           TemplateSpecializationTypeLoc TL) {

+  TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));

+  TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));

+  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));

+  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));

+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)

+    TL.setArgLocInfo(i,

+        Reader.GetTemplateArgumentLocInfo(F,

+                                          TL.getTypePtr()->getArg(i).getKind(),

+                                          Record, Idx));

+}

+void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {

+  TL.setLParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setRParenLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {

+  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));

+  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));

+}

+void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {

+  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));

+  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(

+       DependentTemplateSpecializationTypeLoc TL) {

+  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));

+  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));

+  TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));

+  TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));

+  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));

+  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));

+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)

+    TL.setArgLocInfo(I,

+        Reader.GetTemplateArgumentLocInfo(F,

+                                          TL.getTypePtr()->getArg(I).getKind(),

+                                          Record, Idx));

+}

+void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {

+  TL.setEllipsisLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {

+  TL.setNameLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {

+  TL.setHasBaseTypeAsWritten(Record[Idx++]);

+  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));

+  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));

+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)

+    TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {

+  TL.setStarLoc(ReadSourceLocation(Record, Idx));

+}

+void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {

+  TL.setKWLoc(ReadSourceLocation(Record, Idx));

+  TL.setLParenLoc(ReadSourceLocation(Record, Idx));

+  TL.setRParenLoc(ReadSourceLocation(Record, Idx));

+}

+

+TypeSourceInfo *ASTReader::GetTypeSourceInfo(ModuleFile &F,

+                                             const RecordData &Record,

+                                             unsigned &Idx) {

+  QualType InfoTy = readType(F, Record, Idx);

+  if (InfoTy.isNull())

+    return 0;

+

+  TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);

+  TypeLocReader TLR(*this, F, Record, Idx);

+  for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())

+    TLR.Visit(TL);

+  return TInfo;

+}

+

+QualType ASTReader::GetType(TypeID ID) {

+  unsigned FastQuals = ID & Qualifiers::FastMask;

+  unsigned Index = ID >> Qualifiers::FastWidth;

+

+  if (Index < NUM_PREDEF_TYPE_IDS) {

+    QualType T;

+    switch ((PredefinedTypeIDs)Index) {

+    case PREDEF_TYPE_NULL_ID: return QualType();

+    case PREDEF_TYPE_VOID_ID: T = Context.VoidTy; break;

+    case PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break;

+

+    case PREDEF_TYPE_CHAR_U_ID:

+    case PREDEF_TYPE_CHAR_S_ID:

+      // FIXME: Check that the signedness of CharTy is correct!

+      T = Context.CharTy;

+      break;

+

+    case PREDEF_TYPE_UCHAR_ID:      T = Context.UnsignedCharTy;     break;

+    case PREDEF_TYPE_USHORT_ID:     T = Context.UnsignedShortTy;    break;

+    case PREDEF_TYPE_UINT_ID:       T = Context.UnsignedIntTy;      break;

+    case PREDEF_TYPE_ULONG_ID:      T = Context.UnsignedLongTy;     break;

+    case PREDEF_TYPE_ULONGLONG_ID:  T = Context.UnsignedLongLongTy; break;

+    case PREDEF_TYPE_UINT128_ID:    T = Context.UnsignedInt128Ty;   break;

+    case PREDEF_TYPE_SCHAR_ID:      T = Context.SignedCharTy;       break;

+    case PREDEF_TYPE_WCHAR_ID:      T = Context.WCharTy;            break;

+    case PREDEF_TYPE_SHORT_ID:      T = Context.ShortTy;            break;

+    case PREDEF_TYPE_INT_ID:        T = Context.IntTy;              break;

+    case PREDEF_TYPE_LONG_ID:       T = Context.LongTy;             break;

+    case PREDEF_TYPE_LONGLONG_ID:   T = Context.LongLongTy;         break;

+    case PREDEF_TYPE_INT128_ID:     T = Context.Int128Ty;           break;

+    case PREDEF_TYPE_HALF_ID:       T = Context.HalfTy;             break;

+    case PREDEF_TYPE_FLOAT_ID:      T = Context.FloatTy;            break;

+    case PREDEF_TYPE_DOUBLE_ID:     T = Context.DoubleTy;           break;

+    case PREDEF_TYPE_LONGDOUBLE_ID: T = Context.LongDoubleTy;       break;

+    case PREDEF_TYPE_OVERLOAD_ID:   T = Context.OverloadTy;         break;

+    case PREDEF_TYPE_BOUND_MEMBER:  T = Context.BoundMemberTy;      break;

+    case PREDEF_TYPE_PSEUDO_OBJECT: T = Context.PseudoObjectTy;     break;

+    case PREDEF_TYPE_DEPENDENT_ID:  T = Context.DependentTy;        break;

+    case PREDEF_TYPE_UNKNOWN_ANY:   T = Context.UnknownAnyTy;       break;

+    case PREDEF_TYPE_NULLPTR_ID:    T = Context.NullPtrTy;          break;

+    case PREDEF_TYPE_CHAR16_ID:     T = Context.Char16Ty;           break;

+    case PREDEF_TYPE_CHAR32_ID:     T = Context.Char32Ty;           break;

+    case PREDEF_TYPE_OBJC_ID:       T = Context.ObjCBuiltinIdTy;    break;

+    case PREDEF_TYPE_OBJC_CLASS:    T = Context.ObjCBuiltinClassTy; break;

+    case PREDEF_TYPE_OBJC_SEL:      T = Context.ObjCBuiltinSelTy;   break;

+    case PREDEF_TYPE_IMAGE1D_ID:    T = Context.OCLImage1dTy;       break;

+    case PREDEF_TYPE_IMAGE1D_ARR_ID: T = Context.OCLImage1dArrayTy; break;

+    case PREDEF_TYPE_IMAGE1D_BUFF_ID: T = Context.OCLImage1dBufferTy; break;

+    case PREDEF_TYPE_IMAGE2D_ID:    T = Context.OCLImage2dTy;       break;

+    case PREDEF_TYPE_IMAGE2D_ARR_ID: T = Context.OCLImage2dArrayTy; break;

+    case PREDEF_TYPE_IMAGE3D_ID:    T = Context.OCLImage3dTy;       break;

+    case PREDEF_TYPE_AUTO_DEDUCT:   T = Context.getAutoDeductType(); break;

+        

+    case PREDEF_TYPE_AUTO_RREF_DEDUCT: 

+      T = Context.getAutoRRefDeductType(); 

+      break;

+

+    case PREDEF_TYPE_ARC_UNBRIDGED_CAST:

+      T = Context.ARCUnbridgedCastTy;

+      break;

+

+    case PREDEF_TYPE_VA_LIST_TAG:

+      T = Context.getVaListTagType();

+      break;

+

+    case PREDEF_TYPE_BUILTIN_FN:

+      T = Context.BuiltinFnTy;

+      break;

+    }

+

+    assert(!T.isNull() && "Unknown predefined type");

+    return T.withFastQualifiers(FastQuals);

+  }

+

+  Index -= NUM_PREDEF_TYPE_IDS;

+  assert(Index < TypesLoaded.size() && "Type index out-of-range");

+  if (TypesLoaded[Index].isNull()) {

+    TypesLoaded[Index] = readTypeRecord(Index);

+    if (TypesLoaded[Index].isNull())

+      return QualType();

+

+    TypesLoaded[Index]->setFromAST();

+    if (DeserializationListener)

+      DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),

+                                        TypesLoaded[Index]);

+  }

+

+  return TypesLoaded[Index].withFastQualifiers(FastQuals);

+}

+

+QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) {

+  return GetType(getGlobalTypeID(F, LocalID));

+}

+

+serialization::TypeID 

+ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const {

+  unsigned FastQuals = LocalID & Qualifiers::FastMask;

+  unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;

+  

+  if (LocalIndex < NUM_PREDEF_TYPE_IDS)

+    return LocalID;

+

+  ContinuousRangeMap<uint32_t, int, 2>::iterator I

+    = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);

+  assert(I != F.TypeRemap.end() && "Invalid index into type index remap");

+  

+  unsigned GlobalIndex = LocalIndex + I->second;

+  return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;

+}

+

+TemplateArgumentLocInfo

+ASTReader::GetTemplateArgumentLocInfo(ModuleFile &F,

+                                      TemplateArgument::ArgKind Kind,

+                                      const RecordData &Record,

+                                      unsigned &Index) {

+  switch (Kind) {

+  case TemplateArgument::Expression:

+    return ReadExpr(F);

+  case TemplateArgument::Type:

+    return GetTypeSourceInfo(F, Record, Index);

+  case TemplateArgument::Template: {

+    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 

+                                                                     Index);

+    SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);

+    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,

+                                   SourceLocation());

+  }

+  case TemplateArgument::TemplateExpansion: {

+    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 

+                                                                     Index);

+    SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);

+    SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);

+    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, 

+                                   EllipsisLoc);

+  }

+  case TemplateArgument::Null:

+  case TemplateArgument::Integral:

+  case TemplateArgument::Declaration:

+  case TemplateArgument::NullPtr:

+  case TemplateArgument::Pack:

+    // FIXME: Is this right?

+    return TemplateArgumentLocInfo();

+  }

+  llvm_unreachable("unexpected template argument loc");

+}

+

+TemplateArgumentLoc

+ASTReader::ReadTemplateArgumentLoc(ModuleFile &F,

+                                   const RecordData &Record, unsigned &Index) {

+  TemplateArgument Arg = ReadTemplateArgument(F, Record, Index);

+

+  if (Arg.getKind() == TemplateArgument::Expression) {

+    if (Record[Index++]) // bool InfoHasSameExpr.

+      return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));

+  }

+  return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(F, Arg.getKind(),

+                                                             Record, Index));

+}

+

+Decl *ASTReader::GetExternalDecl(uint32_t ID) {

+  return GetDecl(ID);

+}

+

+uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, 

+                                          unsigned &Idx){

+  if (Idx >= Record.size())

+    return 0;

+  

+  unsigned LocalID = Record[Idx++];

+  return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);

+}

+

+CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {

+  RecordLocation Loc = getLocalBitOffset(Offset);

+  llvm::BitstreamCursor &Cursor = Loc.F->DeclsCursor;

+  SavedStreamPosition SavedPosition(Cursor);

+  Cursor.JumpToBit(Loc.Offset);

+  ReadingKindTracker ReadingKind(Read_Decl, *this);

+  RecordData Record;

+  unsigned Code = Cursor.ReadCode();

+  unsigned RecCode = Cursor.ReadRecord(Code, Record);

+  if (RecCode != DECL_CXX_BASE_SPECIFIERS) {

+    Error("Malformed AST file: missing C++ base specifiers");

+    return 0;

+  }

+

+  unsigned Idx = 0;

+  unsigned NumBases = Record[Idx++];

+  void *Mem = Context.Allocate(sizeof(CXXBaseSpecifier) * NumBases);

+  CXXBaseSpecifier *Bases = new (Mem) CXXBaseSpecifier [NumBases];

+  for (unsigned I = 0; I != NumBases; ++I)

+    Bases[I] = ReadCXXBaseSpecifier(*Loc.F, Record, Idx);

+  return Bases;

+}

+

+serialization::DeclID 

+ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {

+  if (LocalID < NUM_PREDEF_DECL_IDS)

+    return LocalID;

+

+  ContinuousRangeMap<uint32_t, int, 2>::iterator I

+    = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);

+  assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");

+  

+  return LocalID + I->second;

+}

+

+bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,

+                                   ModuleFile &M) const {

+  GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID);

+  assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");

+  return &M == I->second;

+}

+

+ModuleFile *ASTReader::getOwningModuleFile(Decl *D) {

+  if (!D->isFromASTFile())

+    return 0;

+  GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());

+  assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");

+  return I->second;

+}

+

+SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {

+  if (ID < NUM_PREDEF_DECL_IDS)

+    return SourceLocation();

+  

+  unsigned Index = ID - NUM_PREDEF_DECL_IDS;

+

+  if (Index > DeclsLoaded.size()) {

+    Error("declaration ID out-of-range for AST file");

+    return SourceLocation();

+  }

+  

+  if (Decl *D = DeclsLoaded[Index])

+    return D->getLocation();

+

+  unsigned RawLocation = 0;

+  RecordLocation Rec = DeclCursorForID(ID, RawLocation);

+  return ReadSourceLocation(*Rec.F, RawLocation);

+}

+

+Decl *ASTReader::GetDecl(DeclID ID) {

+  if (ID < NUM_PREDEF_DECL_IDS) {    

+    switch ((PredefinedDeclIDs)ID) {

+    case PREDEF_DECL_NULL_ID:

+      return 0;

+        

+    case PREDEF_DECL_TRANSLATION_UNIT_ID:

+      return Context.getTranslationUnitDecl();

+        

+    case PREDEF_DECL_OBJC_ID_ID:

+      return Context.getObjCIdDecl();

+

+    case PREDEF_DECL_OBJC_SEL_ID:

+      return Context.getObjCSelDecl();

+

+    case PREDEF_DECL_OBJC_CLASS_ID:

+      return Context.getObjCClassDecl();

+        

+    case PREDEF_DECL_OBJC_PROTOCOL_ID:

+      return Context.getObjCProtocolDecl();

+        

+    case PREDEF_DECL_INT_128_ID:

+      return Context.getInt128Decl();

+

+    case PREDEF_DECL_UNSIGNED_INT_128_ID:

+      return Context.getUInt128Decl();

+        

+    case PREDEF_DECL_OBJC_INSTANCETYPE_ID:

+      return Context.getObjCInstanceTypeDecl();

+

+    case PREDEF_DECL_BUILTIN_VA_LIST_ID:

+      return Context.getBuiltinVaListDecl();

+    }

+  }

+  

+  unsigned Index = ID - NUM_PREDEF_DECL_IDS;

+

+  if (Index >= DeclsLoaded.size()) {

+    assert(0 && "declaration ID out-of-range for AST file");

+    Error("declaration ID out-of-range for AST file");

+    return 0;

+  }

+  

+  if (!DeclsLoaded[Index]) {

+    ReadDeclRecord(ID);

+    if (DeserializationListener)

+      DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);

+  }

+

+  return DeclsLoaded[Index];

+}

+

+DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, 

+                                                  DeclID GlobalID) {

+  if (GlobalID < NUM_PREDEF_DECL_IDS)

+    return GlobalID;

+  

+  GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID);

+  assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");

+  ModuleFile *Owner = I->second;

+

+  llvm::DenseMap<ModuleFile *, serialization::DeclID>::iterator Pos

+    = M.GlobalToLocalDeclIDs.find(Owner);

+  if (Pos == M.GlobalToLocalDeclIDs.end())

+    return 0;

+      

+  return GlobalID - Owner->BaseDeclID + Pos->second;

+}

+

+serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, 

+                                            const RecordData &Record,

+                                            unsigned &Idx) {

+  if (Idx >= Record.size()) {

+    Error("Corrupted AST file");

+    return 0;

+  }

+  

+  return getGlobalDeclID(F, Record[Idx++]);

+}

+

+/// \brief Resolve the offset of a statement into a statement.

+///

+/// This operation will read a new statement from the external

+/// source each time it is called, and is meant to be used via a

+/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).

+Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {

+  // Switch case IDs are per Decl.

+  ClearSwitchCaseIDs();

+

+  // Offset here is a global offset across the entire chain.

+  RecordLocation Loc = getLocalBitOffset(Offset);

+  Loc.F->DeclsCursor.JumpToBit(Loc.Offset);

+  return ReadStmtFromStream(*Loc.F);

+}

+

+namespace {

+  class FindExternalLexicalDeclsVisitor {

+    ASTReader &Reader;

+    const DeclContext *DC;

+    bool (*isKindWeWant)(Decl::Kind);

+    

+    SmallVectorImpl<Decl*> &Decls;

+    bool PredefsVisited[NUM_PREDEF_DECL_IDS];

+

+  public:

+    FindExternalLexicalDeclsVisitor(ASTReader &Reader, const DeclContext *DC,

+                                    bool (*isKindWeWant)(Decl::Kind),

+                                    SmallVectorImpl<Decl*> &Decls)

+      : Reader(Reader), DC(DC), isKindWeWant(isKindWeWant), Decls(Decls) 

+    {

+      for (unsigned I = 0; I != NUM_PREDEF_DECL_IDS; ++I)

+        PredefsVisited[I] = false;

+    }

+

+    static bool visit(ModuleFile &M, bool Preorder, void *UserData) {

+      if (Preorder)

+        return false;

+

+      FindExternalLexicalDeclsVisitor *This

+        = static_cast<FindExternalLexicalDeclsVisitor *>(UserData);

+

+      ModuleFile::DeclContextInfosMap::iterator Info

+        = M.DeclContextInfos.find(This->DC);

+      if (Info == M.DeclContextInfos.end() || !Info->second.LexicalDecls)

+        return false;

+

+      // Load all of the declaration IDs

+      for (const KindDeclIDPair *ID = Info->second.LexicalDecls,

+                               *IDE = ID + Info->second.NumLexicalDecls; 

+           ID != IDE; ++ID) {

+        if (This->isKindWeWant && !This->isKindWeWant((Decl::Kind)ID->first))

+          continue;

+

+        // Don't add predefined declarations to the lexical context more

+        // than once.

+        if (ID->second < NUM_PREDEF_DECL_IDS) {

+          if (This->PredefsVisited[ID->second])

+            continue;

+

+          This->PredefsVisited[ID->second] = true;

+        }

+

+        if (Decl *D = This->Reader.GetLocalDecl(M, ID->second)) {

+          if (!This->DC->isDeclInLexicalTraversal(D))

+            This->Decls.push_back(D);

+        }

+      }

+

+      return false;

+    }

+  };

+}

+

+ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,

+                                         bool (*isKindWeWant)(Decl::Kind),

+                                         SmallVectorImpl<Decl*> &Decls) {

+  // There might be lexical decls in multiple modules, for the TU at

+  // least. Walk all of the modules in the order they were loaded.

+  FindExternalLexicalDeclsVisitor Visitor(*this, DC, isKindWeWant, Decls);

+  ModuleMgr.visitDepthFirst(&FindExternalLexicalDeclsVisitor::visit, &Visitor);

+  ++NumLexicalDeclContextsRead;

+  return ELR_Success;

+}

+

+namespace {

+

+class DeclIDComp {

+  ASTReader &Reader;

+  ModuleFile &Mod;

+

+public:

+  DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {}

+

+  bool operator()(LocalDeclID L, LocalDeclID R) const {

+    SourceLocation LHS = getLocation(L);

+    SourceLocation RHS = getLocation(R);

+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);

+  }

+

+  bool operator()(SourceLocation LHS, LocalDeclID R) const {

+    SourceLocation RHS = getLocation(R);

+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);

+  }

+

+  bool operator()(LocalDeclID L, SourceLocation RHS) const {

+    SourceLocation LHS = getLocation(L);

+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);

+  }

+

+  SourceLocation getLocation(LocalDeclID ID) const {

+    return Reader.getSourceManager().getFileLoc(

+            Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID)));

+  }

+};

+

+}

+

+void ASTReader::FindFileRegionDecls(FileID File,

+                                    unsigned Offset, unsigned Length,

+                                    SmallVectorImpl<Decl *> &Decls) {

+  SourceManager &SM = getSourceManager();

+

+  llvm::DenseMap<FileID, FileDeclsInfo>::iterator I = FileDeclIDs.find(File);

+  if (I == FileDeclIDs.end())

+    return;

+

+  FileDeclsInfo &DInfo = I->second;

+  if (DInfo.Decls.empty())

+    return;

+

+  SourceLocation

+    BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset);

+  SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length);

+

+  DeclIDComp DIDComp(*this, *DInfo.Mod);

+  ArrayRef<serialization::LocalDeclID>::iterator

+    BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(),

+                               BeginLoc, DIDComp);

+  if (BeginIt != DInfo.Decls.begin())

+    --BeginIt;

+

+  // If we are pointing at a top-level decl inside an objc container, we need

+  // to backtrack until we find it otherwise we will fail to report that the

+  // region overlaps with an objc container.

+  while (BeginIt != DInfo.Decls.begin() &&

+         GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt))

+             ->isTopLevelDeclInObjCContainer())

+    --BeginIt;

+

+  ArrayRef<serialization::LocalDeclID>::iterator

+    EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(),

+                             EndLoc, DIDComp);

+  if (EndIt != DInfo.Decls.end())

+    ++EndIt;

+  

+  for (ArrayRef<serialization::LocalDeclID>::iterator

+         DIt = BeginIt; DIt != EndIt; ++DIt)

+    Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));

+}

+

+namespace {

+  /// \brief ModuleFile visitor used to perform name lookup into a

+  /// declaration context.

+  class DeclContextNameLookupVisitor {

+    ASTReader &Reader;

+    llvm::SmallVectorImpl<const DeclContext *> &Contexts;

+    DeclarationName Name;

+    SmallVectorImpl<NamedDecl *> &Decls;

+

+  public:

+    DeclContextNameLookupVisitor(ASTReader &Reader, 

+                                 SmallVectorImpl<const DeclContext *> &Contexts, 

+                                 DeclarationName Name,

+                                 SmallVectorImpl<NamedDecl *> &Decls)

+      : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls) { }

+

+    static bool visit(ModuleFile &M, void *UserData) {

+      DeclContextNameLookupVisitor *This

+        = static_cast<DeclContextNameLookupVisitor *>(UserData);

+

+      // Check whether we have any visible declaration information for

+      // this context in this module.

+      ModuleFile::DeclContextInfosMap::iterator Info;

+      bool FoundInfo = false;

+      for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) {

+        Info = M.DeclContextInfos.find(This->Contexts[I]);

+        if (Info != M.DeclContextInfos.end() && 

+            Info->second.NameLookupTableData) {

+          FoundInfo = true;

+          break;

+        }

+      }

+

+      if (!FoundInfo)

+        return false;

+      

+      // Look for this name within this module.

+      ASTDeclContextNameLookupTable *LookupTable =

+        Info->second.NameLookupTableData;

+      ASTDeclContextNameLookupTable::iterator Pos

+        = LookupTable->find(This->Name);

+      if (Pos == LookupTable->end())

+        return false;

+

+      bool FoundAnything = false;

+      ASTDeclContextNameLookupTrait::data_type Data = *Pos;

+      for (; Data.first != Data.second; ++Data.first) {

+        NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);

+        if (!ND)

+          continue;

+

+        if (ND->getDeclName() != This->Name) {

+          // A name might be null because the decl's redeclarable part is

+          // currently read before reading its name. The lookup is triggered by

+          // building that decl (likely indirectly), and so it is later in the

+          // sense of "already existing" and can be ignored here.

+          continue;

+        }

+      

+        // Record this declaration.

+        FoundAnything = true;

+        This->Decls.push_back(ND);

+      }

+

+      return FoundAnything;

+    }

+  };

+}

+

+DeclContext::lookup_result

+ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,

+                                          DeclarationName Name) {

+  assert(DC->hasExternalVisibleStorage() &&

+         "DeclContext has no visible decls in storage");

+  if (!Name)

+    return DeclContext::lookup_result(DeclContext::lookup_iterator(0),

+                                      DeclContext::lookup_iterator(0));

+

+  SmallVector<NamedDecl *, 64> Decls;

+  

+  // Compute the declaration contexts we need to look into. Multiple such

+  // declaration contexts occur when two declaration contexts from disjoint

+  // modules get merged, e.g., when two namespaces with the same name are 

+  // independently defined in separate modules.

+  SmallVector<const DeclContext *, 2> Contexts;

+  Contexts.push_back(DC);

+  

+  if (DC->isNamespace()) {

+    MergedDeclsMap::iterator Merged

+      = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));

+    if (Merged != MergedDecls.end()) {

+      for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)

+        Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));

+    }

+  }

+  

+  DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls);

+  ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);

+  ++NumVisibleDeclContextsRead;

+  SetExternalVisibleDeclsForName(DC, Name, Decls);

+  return const_cast<DeclContext*>(DC)->lookup(Name);

+}

+

+namespace {

+  /// \brief ModuleFile visitor used to retrieve all visible names in a

+  /// declaration context.

+  class DeclContextAllNamesVisitor {

+    ASTReader &Reader;

+    llvm::SmallVectorImpl<const DeclContext *> &Contexts;

+    llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls;

+

+  public:

+    DeclContextAllNamesVisitor(ASTReader &Reader,

+                               SmallVectorImpl<const DeclContext *> &Contexts,

+                               llvm::DenseMap<DeclarationName,

+                                           SmallVector<NamedDecl *, 8> > &Decls)

+      : Reader(Reader), Contexts(Contexts), Decls(Decls) { }

+

+    static bool visit(ModuleFile &M, void *UserData) {

+      DeclContextAllNamesVisitor *This

+        = static_cast<DeclContextAllNamesVisitor *>(UserData);

+

+      // Check whether we have any visible declaration information for

+      // this context in this module.

+      ModuleFile::DeclContextInfosMap::iterator Info;

+      bool FoundInfo = false;

+      for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) {

+        Info = M.DeclContextInfos.find(This->Contexts[I]);

+        if (Info != M.DeclContextInfos.end() &&

+            Info->second.NameLookupTableData) {

+          FoundInfo = true;

+          break;

+        }

+      }

+

+      if (!FoundInfo)

+        return false;

+

+      ASTDeclContextNameLookupTable *LookupTable =

+        Info->second.NameLookupTableData;

+      bool FoundAnything = false;

+      for (ASTDeclContextNameLookupTable::data_iterator

+	     I = LookupTable->data_begin(), E = LookupTable->data_end();

+	   I != E; ++I) {

+        ASTDeclContextNameLookupTrait::data_type Data = *I;

+        for (; Data.first != Data.second; ++Data.first) {

+          NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M,

+                                                                 *Data.first);

+          if (!ND)

+            continue;

+

+          // Record this declaration.

+          FoundAnything = true;

+          This->Decls[ND->getDeclName()].push_back(ND);

+        }

+      }

+

+      return FoundAnything;

+    }

+  };

+}

+

+void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {

+  if (!DC->hasExternalVisibleStorage())

+    return;

+  llvm::DenseMap<DeclarationName, llvm::SmallVector<NamedDecl*, 8> > Decls;

+

+  // Compute the declaration contexts we need to look into. Multiple such

+  // declaration contexts occur when two declaration contexts from disjoint

+  // modules get merged, e.g., when two namespaces with the same name are

+  // independently defined in separate modules.

+  SmallVector<const DeclContext *, 2> Contexts;

+  Contexts.push_back(DC);

+

+  if (DC->isNamespace()) {

+    MergedDeclsMap::iterator Merged

+      = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));

+    if (Merged != MergedDecls.end()) {

+      for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)

+        Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));

+    }

+  }

+

+  DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls);

+  ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor);

+  ++NumVisibleDeclContextsRead;

+

+  for (llvm::DenseMap<DeclarationName,

+                      llvm::SmallVector<NamedDecl*, 8> >::iterator

+         I = Decls.begin(), E = Decls.end(); I != E; ++I) {

+    SetExternalVisibleDeclsForName(DC, I->first, I->second);

+  }

+  const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false);

+}

+

+/// \brief Under non-PCH compilation the consumer receives the objc methods

+/// before receiving the implementation, and codegen depends on this.

+/// We simulate this by deserializing and passing to consumer the methods of the

+/// implementation before passing the deserialized implementation decl.

+static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,

+                                       ASTConsumer *Consumer) {

+  assert(ImplD && Consumer);

+

+  for (ObjCImplDecl::method_iterator

+         I = ImplD->meth_begin(), E = ImplD->meth_end(); I != E; ++I)

+    Consumer->HandleInterestingDecl(DeclGroupRef(*I));

+

+  Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));

+}

+

+void ASTReader::PassInterestingDeclsToConsumer() {

+  assert(Consumer);

+  while (!InterestingDecls.empty()) {

+    Decl *D = InterestingDecls.front();

+    InterestingDecls.pop_front();

+

+    PassInterestingDeclToConsumer(D);

+  }

+}

+

+void ASTReader::PassInterestingDeclToConsumer(Decl *D) {

+  if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))

+    PassObjCImplDeclToConsumer(ImplD, Consumer);

+  else

+    Consumer->HandleInterestingDecl(DeclGroupRef(D));

+}

+

+void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {

+  this->Consumer = Consumer;

+

+  if (!Consumer)

+    return;

+

+  for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {

+    // Force deserialization of this decl, which will cause it to be queued for

+    // passing to the consumer.

+    GetDecl(ExternalDefinitions[I]);

+  }

+  ExternalDefinitions.clear();

+

+  PassInterestingDeclsToConsumer();

+}

+

+void ASTReader::PrintStats() {

+  std::fprintf(stderr, "*** AST File Statistics:\n");

+

+  unsigned NumTypesLoaded

+    = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),

+                                      QualType());

+  unsigned NumDeclsLoaded

+    = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),

+                                      (Decl *)0);

+  unsigned NumIdentifiersLoaded

+    = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),

+                                            IdentifiersLoaded.end(),

+                                            (IdentifierInfo *)0);

+  unsigned NumMacrosLoaded

+    = MacrosLoaded.size() - std::count(MacrosLoaded.begin(),

+                                       MacrosLoaded.end(),

+                                       (MacroInfo *)0);

+  unsigned NumSelectorsLoaded

+    = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),

+                                          SelectorsLoaded.end(),

+                                          Selector());

+

+  if (unsigned TotalNumSLocEntries = getTotalNumSLocs())

+    std::fprintf(stderr, "  %u/%u source location entries read (%f%%)\n",

+                 NumSLocEntriesRead, TotalNumSLocEntries,

+                 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));

+  if (!TypesLoaded.empty())

+    std::fprintf(stderr, "  %u/%u types read (%f%%)\n",

+                 NumTypesLoaded, (unsigned)TypesLoaded.size(),

+                 ((float)NumTypesLoaded/TypesLoaded.size() * 100));

+  if (!DeclsLoaded.empty())

+    std::fprintf(stderr, "  %u/%u declarations read (%f%%)\n",

+                 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),

+                 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));

+  if (!IdentifiersLoaded.empty())

+    std::fprintf(stderr, "  %u/%u identifiers read (%f%%)\n",

+                 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),

+                 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));

+  if (!MacrosLoaded.empty())

+    std::fprintf(stderr, "  %u/%u macros read (%f%%)\n",

+                 NumMacrosLoaded, (unsigned)MacrosLoaded.size(),

+                 ((float)NumMacrosLoaded/MacrosLoaded.size() * 100));

+  if (!SelectorsLoaded.empty())

+    std::fprintf(stderr, "  %u/%u selectors read (%f%%)\n",

+                 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),

+                 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));

+  if (TotalNumStatements)

+    std::fprintf(stderr, "  %u/%u statements read (%f%%)\n",

+                 NumStatementsRead, TotalNumStatements,

+                 ((float)NumStatementsRead/TotalNumStatements * 100));

+  if (TotalNumMacros)

+    std::fprintf(stderr, "  %u/%u macros read (%f%%)\n",

+                 NumMacrosRead, TotalNumMacros,

+                 ((float)NumMacrosRead/TotalNumMacros * 100));

+  if (TotalLexicalDeclContexts)

+    std::fprintf(stderr, "  %u/%u lexical declcontexts read (%f%%)\n",

+                 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,

+                 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts

+                  * 100));

+  if (TotalVisibleDeclContexts)

+    std::fprintf(stderr, "  %u/%u visible declcontexts read (%f%%)\n",

+                 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,

+                 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts

+                  * 100));

+  if (TotalNumMethodPoolEntries) {

+    std::fprintf(stderr, "  %u/%u method pool entries read (%f%%)\n",

+                 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,

+                 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries

+                  * 100));

+    std::fprintf(stderr, "  %u method pool misses\n", NumMethodPoolMisses);

+  }

+  std::fprintf(stderr, "\n");

+  dump();

+  std::fprintf(stderr, "\n");

+}

+

+template<typename Key, typename ModuleFile, unsigned InitialCapacity>

+static void 

+dumpModuleIDMap(StringRef Name,

+                const ContinuousRangeMap<Key, ModuleFile *, 

+                                         InitialCapacity> &Map) {

+  if (Map.begin() == Map.end())

+    return;

+  

+  typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType;

+  llvm::errs() << Name << ":\n";

+  for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); 

+       I != IEnd; ++I) {

+    llvm::errs() << "  " << I->first << " -> " << I->second->FileName

+      << "\n";

+  }

+}

+

+void ASTReader::dump() {

+  llvm::errs() << "*** PCH/ModuleFile Remappings:\n";

+  dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);

+  dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);

+  dumpModuleIDMap("Global type map", GlobalTypeMap);

+  dumpModuleIDMap("Global declaration map", GlobalDeclMap);

+  dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);

+  dumpModuleIDMap("Global macro map", GlobalMacroMap);

+  dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);

+  dumpModuleIDMap("Global selector map", GlobalSelectorMap);

+  dumpModuleIDMap("Global preprocessed entity map", 

+                  GlobalPreprocessedEntityMap);

+  

+  llvm::errs() << "\n*** PCH/Modules Loaded:";

+  for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(), 

+                                       MEnd = ModuleMgr.end();

+       M != MEnd; ++M)

+    (*M)->dump();

+}

+

+/// Return the amount of memory used by memory buffers, breaking down

+/// by heap-backed versus mmap'ed memory.

+void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {

+  for (ModuleConstIterator I = ModuleMgr.begin(),

+      E = ModuleMgr.end(); I != E; ++I) {

+    if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {

+      size_t bytes = buf->getBufferSize();

+      switch (buf->getBufferKind()) {

+        case llvm::MemoryBuffer::MemoryBuffer_Malloc:

+          sizes.malloc_bytes += bytes;

+          break;

+        case llvm::MemoryBuffer::MemoryBuffer_MMap:

+          sizes.mmap_bytes += bytes;

+          break;

+      }

+    }

+  }

+}

+

+void ASTReader::InitializeSema(Sema &S) {

+  SemaObj = &S;

+  S.addExternalSource(this);

+

+  // Makes sure any declarations that were deserialized "too early"

+  // still get added to the identifier's declaration chains.

+  for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {

+    SemaObj->pushExternalDeclIntoScope(PreloadedDecls[I], 

+                                       PreloadedDecls[I]->getDeclName());

+  }

+  PreloadedDecls.clear();

+

+  // Load the offsets of the declarations that Sema references.

+  // They will be lazily deserialized when needed.

+  if (!SemaDeclRefs.empty()) {

+    assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");

+    if (!SemaObj->StdNamespace)

+      SemaObj->StdNamespace = SemaDeclRefs[0];

+    if (!SemaObj->StdBadAlloc)

+      SemaObj->StdBadAlloc = SemaDeclRefs[1];

+  }

+

+  if (!FPPragmaOptions.empty()) {

+    assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");

+    SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];

+  }

+

+  if (!OpenCLExtensions.empty()) {

+    unsigned I = 0;

+#define OPENCLEXT(nm)  SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++];

+#include "clang/Basic/OpenCLExtensions.def"

+

+    assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS");

+  }

+}

+

+IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {

+  // Note that we are loading an identifier.

+  Deserializing AnIdentifier(this);

+  

+  IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart),

+                                  /*PriorGeneration=*/0);

+  ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);

+  IdentifierInfo *II = Visitor.getIdentifierInfo();

+  markIdentifierUpToDate(II);

+  return II;

+}

+

+namespace clang {

+  /// \brief An identifier-lookup iterator that enumerates all of the

+  /// identifiers stored within a set of AST files.

+  class ASTIdentifierIterator : public IdentifierIterator {

+    /// \brief The AST reader whose identifiers are being enumerated.

+    const ASTReader &Reader;

+

+    /// \brief The current index into the chain of AST files stored in

+    /// the AST reader.

+    unsigned Index;

+

+    /// \brief The current position within the identifier lookup table

+    /// of the current AST file.

+    ASTIdentifierLookupTable::key_iterator Current;

+

+    /// \brief The end position within the identifier lookup table of

+    /// the current AST file.

+    ASTIdentifierLookupTable::key_iterator End;

+

+  public:

+    explicit ASTIdentifierIterator(const ASTReader &Reader);

+

+    virtual StringRef Next();

+  };

+}

+

+ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader)

+  : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) {

+  ASTIdentifierLookupTable *IdTable

+    = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable;

+  Current = IdTable->key_begin();

+  End = IdTable->key_end();

+}

+

+StringRef ASTIdentifierIterator::Next() {

+  while (Current == End) {

+    // If we have exhausted all of our AST files, we're done.

+    if (Index == 0)

+      return StringRef();

+

+    --Index;

+    ASTIdentifierLookupTable *IdTable

+      = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].

+        IdentifierLookupTable;

+    Current = IdTable->key_begin();

+    End = IdTable->key_end();

+  }

+

+  // We have any identifiers remaining in the current AST file; return

+  // the next one.

+  std::pair<const char*, unsigned> Key = *Current;

+  ++Current;

+  return StringRef(Key.first, Key.second);

+}

+

+IdentifierIterator *ASTReader::getIdentifiers() const {

+  return new ASTIdentifierIterator(*this);

+}

+

+namespace clang { namespace serialization {

+  class ReadMethodPoolVisitor {

+    ASTReader &Reader;

+    Selector Sel;

+    unsigned PriorGeneration;

+    llvm::SmallVector<ObjCMethodDecl *, 4> InstanceMethods;

+    llvm::SmallVector<ObjCMethodDecl *, 4> FactoryMethods;

+

+  public:

+    ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel, 

+                          unsigned PriorGeneration)

+      : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) { }

+    

+    static bool visit(ModuleFile &M, void *UserData) {

+      ReadMethodPoolVisitor *This

+        = static_cast<ReadMethodPoolVisitor *>(UserData);

+      

+      if (!M.SelectorLookupTable)

+        return false;

+      

+      // If we've already searched this module file, skip it now.

+      if (M.Generation <= This->PriorGeneration)

+        return true;

+

+      ASTSelectorLookupTable *PoolTable

+        = (ASTSelectorLookupTable*)M.SelectorLookupTable;

+      ASTSelectorLookupTable::iterator Pos = PoolTable->find(This->Sel);

+      if (Pos == PoolTable->end())

+        return false;

+      

+      ++This->Reader.NumSelectorsRead;

+      // FIXME: Not quite happy with the statistics here. We probably should

+      // disable this tracking when called via LoadSelector.

+      // Also, should entries without methods count as misses?

+      ++This->Reader.NumMethodPoolEntriesRead;

+      ASTSelectorLookupTrait::data_type Data = *Pos;

+      if (This->Reader.DeserializationListener)

+        This->Reader.DeserializationListener->SelectorRead(Data.ID, 

+                                                           This->Sel);

+      

+      This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());

+      This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());

+      return true;

+    }

+    

+    /// \brief Retrieve the instance methods found by this visitor.

+    ArrayRef<ObjCMethodDecl *> getInstanceMethods() const { 

+      return InstanceMethods; 

+    }

+

+    /// \brief Retrieve the instance methods found by this visitor.

+    ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { 

+      return FactoryMethods;

+    }

+  };

+} } // end namespace clang::serialization

+

+/// \brief Add the given set of methods to the method list.

+static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,

+                             ObjCMethodList &List) {

+  for (unsigned I = 0, N = Methods.size(); I != N; ++I) {

+    S.addMethodToGlobalList(&List, Methods[I]);

+  }

+}

+                             

+void ASTReader::ReadMethodPool(Selector Sel) {

+  // Get the selector generation and update it to the current generation.

+  unsigned &Generation = SelectorGeneration[Sel];

+  unsigned PriorGeneration = Generation;

+  Generation = CurrentGeneration;

+  

+  // Search for methods defined with this selector.

+  ReadMethodPoolVisitor Visitor(*this, Sel, PriorGeneration);

+  ModuleMgr.visit(&ReadMethodPoolVisitor::visit, &Visitor);

+  

+  if (Visitor.getInstanceMethods().empty() &&

+      Visitor.getFactoryMethods().empty()) {

+    ++NumMethodPoolMisses;

+    return;

+  }

+  

+  if (!getSema())

+    return;

+  

+  Sema &S = *getSema();

+  Sema::GlobalMethodPool::iterator Pos

+    = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first;

+  

+  addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);

+  addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);

+}

+

+void ASTReader::ReadKnownNamespaces(

+                          SmallVectorImpl<NamespaceDecl *> &Namespaces) {

+  Namespaces.clear();

+  

+  for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {

+    if (NamespaceDecl *Namespace 

+                = dyn_cast_or_null<NamespaceDecl>(GetDecl(KnownNamespaces[I])))

+      Namespaces.push_back(Namespace);

+  }

+}

+

+void ASTReader::ReadTentativeDefinitions(

+                  SmallVectorImpl<VarDecl *> &TentativeDefs) {

+  for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {

+    VarDecl *Var = dyn_cast_or_null<VarDecl>(GetDecl(TentativeDefinitions[I]));

+    if (Var)

+      TentativeDefs.push_back(Var);

+  }

+  TentativeDefinitions.clear();

+}

+

+void ASTReader::ReadUnusedFileScopedDecls(

+                               SmallVectorImpl<const DeclaratorDecl *> &Decls) {

+  for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {

+    DeclaratorDecl *D

+      = dyn_cast_or_null<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));

+    if (D)

+      Decls.push_back(D);

+  }

+  UnusedFileScopedDecls.clear();

+}

+

+void ASTReader::ReadDelegatingConstructors(

+                                 SmallVectorImpl<CXXConstructorDecl *> &Decls) {

+  for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) {

+    CXXConstructorDecl *D

+      = dyn_cast_or_null<CXXConstructorDecl>(GetDecl(DelegatingCtorDecls[I]));

+    if (D)

+      Decls.push_back(D);

+  }

+  DelegatingCtorDecls.clear();

+}

+

+void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {

+  for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I) {

+    TypedefNameDecl *D

+      = dyn_cast_or_null<TypedefNameDecl>(GetDecl(ExtVectorDecls[I]));

+    if (D)

+      Decls.push_back(D);

+  }

+  ExtVectorDecls.clear();

+}

+

+void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {

+  for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {

+    CXXRecordDecl *D

+      = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I]));

+    if (D)

+      Decls.push_back(D);

+  }

+  DynamicClasses.clear();

+}

+

+void 

+ASTReader::ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl *> &Decls) {

+  for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {

+    NamedDecl *D 

+      = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));

+    if (D)

+      Decls.push_back(D);

+  }

+  LocallyScopedExternalDecls.clear();

+}

+

+void ASTReader::ReadReferencedSelectors(

+       SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {

+  if (ReferencedSelectorsData.empty())

+    return;

+  

+  // If there are @selector references added them to its pool. This is for

+  // implementation of -Wselector.

+  unsigned int DataSize = ReferencedSelectorsData.size()-1;

+  unsigned I = 0;

+  while (I < DataSize) {

+    Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);

+    SourceLocation SelLoc

+      = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);

+    Sels.push_back(std::make_pair(Sel, SelLoc));

+  }

+  ReferencedSelectorsData.clear();

+}

+

+void ASTReader::ReadWeakUndeclaredIdentifiers(

+       SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) {

+  if (WeakUndeclaredIdentifiers.empty())

+    return;

+

+  for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) {

+    IdentifierInfo *WeakId 

+      = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);

+    IdentifierInfo *AliasId 

+      = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);

+    SourceLocation Loc

+      = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]);

+    bool Used = WeakUndeclaredIdentifiers[I++];

+    WeakInfo WI(AliasId, Loc);

+    WI.setUsed(Used);

+    WeakIDs.push_back(std::make_pair(WeakId, WI));

+  }

+  WeakUndeclaredIdentifiers.clear();

+}

+

+void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {

+  for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) {

+    ExternalVTableUse VT;

+    VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));

+    VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]);

+    VT.DefinitionRequired = VTableUses[Idx++];

+    VTables.push_back(VT);

+  }

+  

+  VTableUses.clear();

+}

+

+void ASTReader::ReadPendingInstantiations(

+       SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) {

+  for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {

+    ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));

+    SourceLocation Loc

+      = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);

+

+    Pending.push_back(std::make_pair(D, Loc));

+  }  

+  PendingInstantiations.clear();

+}

+

+void ASTReader::LoadSelector(Selector Sel) {

+  // It would be complicated to avoid reading the methods anyway. So don't.

+  ReadMethodPool(Sel);

+}

+

+void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {

+  assert(ID && "Non-zero identifier ID required");

+  assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");

+  IdentifiersLoaded[ID - 1] = II;

+  if (DeserializationListener)

+    DeserializationListener->IdentifierRead(ID, II);

+}

+

+/// \brief Set the globally-visible declarations associated with the given

+/// identifier.

+///

+/// If the AST reader is currently in a state where the given declaration IDs

+/// cannot safely be resolved, they are queued until it is safe to resolve

+/// them.

+///

+/// \param II an IdentifierInfo that refers to one or more globally-visible

+/// declarations.

+///

+/// \param DeclIDs the set of declaration IDs with the name @p II that are

+/// visible at global scope.

+///

+/// \param Nonrecursive should be true to indicate that the caller knows that

+/// this call is non-recursive, and therefore the globally-visible declarations

+/// will not be placed onto the pending queue.

+void

+ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,

+                              const SmallVectorImpl<uint32_t> &DeclIDs,

+                                   bool Nonrecursive) {

+  if (NumCurrentElementsDeserializing && !Nonrecursive) {

+    PendingIdentifierInfos.push_back(PendingIdentifierInfo());

+    PendingIdentifierInfo &PII = PendingIdentifierInfos.back();

+    PII.II = II;

+    PII.DeclIDs.append(DeclIDs.begin(), DeclIDs.end());

+    return;

+  }

+

+  for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {

+    NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));

+    if (SemaObj) {

+      // Introduce this declaration into the translation-unit scope

+      // and add it to the declaration chain for this identifier, so

+      // that (unqualified) name lookup will find it.

+      SemaObj->pushExternalDeclIntoScope(D, II);

+    } else {

+      // Queue this declaration so that it will be added to the

+      // translation unit scope and identifier's declaration chain

+      // once a Sema object is known.

+      PreloadedDecls.push_back(D);

+    }

+  }

+}

+

+IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {

+  if (ID == 0)

+    return 0;

+

+  if (IdentifiersLoaded.empty()) {

+    Error("no identifier table in AST file");

+    return 0;

+  }

+

+  ID -= 1;

+  if (!IdentifiersLoaded[ID]) {

+    GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1);

+    assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map");

+    ModuleFile *M = I->second;

+    unsigned Index = ID - M->BaseIdentifierID;

+    const char *Str = M->IdentifierTableData + M->IdentifierOffsets[Index];

+

+    // All of the strings in the AST file are preceded by a 16-bit length.

+    // Extract that 16-bit length to avoid having to execute strlen().

+    // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as

+    //  unsigned integers.  This is important to avoid integer overflow when

+    //  we cast them to 'unsigned'.

+    const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;

+    unsigned StrLen = (((unsigned) StrLenPtr[0])

+                       | (((unsigned) StrLenPtr[1]) << 8)) - 1;

+    IdentifiersLoaded[ID]

+      = &PP.getIdentifierTable().get(StringRef(Str, StrLen));

+    if (DeserializationListener)

+      DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);

+  }

+

+  return IdentifiersLoaded[ID];

+}

+

+IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) {

+  return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID));

+}

+

+IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {

+  if (LocalID < NUM_PREDEF_IDENT_IDS)

+    return LocalID;

+  

+  ContinuousRangeMap<uint32_t, int, 2>::iterator I

+    = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);

+  assert(I != M.IdentifierRemap.end() 

+         && "Invalid index into identifier index remap");

+  

+  return LocalID + I->second;

+}

+

+MacroInfo *ASTReader::getMacro(MacroID ID, MacroInfo *Hint) {

+  if (ID == 0)

+    return 0;

+

+  if (MacrosLoaded.empty()) {

+    Error("no macro table in AST file");

+    return 0;

+  }

+

+  ID -= NUM_PREDEF_MACRO_IDS;

+  if (!MacrosLoaded[ID]) {

+    GlobalMacroMapType::iterator I

+      = GlobalMacroMap.find(ID + NUM_PREDEF_MACRO_IDS);

+    assert(I != GlobalMacroMap.end() && "Corrupted global macro map");

+    ModuleFile *M = I->second;

+    unsigned Index = ID - M->BaseMacroID;

+    ReadMacroRecord(*M, M->MacroOffsets[Index], Hint);

+  }

+

+  return MacrosLoaded[ID];

+}

+

+MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {

+  if (LocalID < NUM_PREDEF_MACRO_IDS)

+    return LocalID;

+

+  ContinuousRangeMap<uint32_t, int, 2>::iterator I

+    = M.MacroRemap.find(LocalID - NUM_PREDEF_MACRO_IDS);

+  assert(I != M.MacroRemap.end() && "Invalid index into macro index remap");

+

+  return LocalID + I->second;

+}

+

+serialization::SubmoduleID

+ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {

+  if (LocalID < NUM_PREDEF_SUBMODULE_IDS)

+    return LocalID;

+  

+  ContinuousRangeMap<uint32_t, int, 2>::iterator I

+    = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);

+  assert(I != M.SubmoduleRemap.end() 

+         && "Invalid index into submodule index remap");

+  

+  return LocalID + I->second;

+}

+

+Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {

+  if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {

+    assert(GlobalID == 0 && "Unhandled global submodule ID");

+    return 0;

+  }

+  

+  if (GlobalID > SubmodulesLoaded.size()) {

+    Error("submodule ID out of range in AST file");

+    return 0;

+  }

+  

+  return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];

+}

+                               

+Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {

+  return DecodeSelector(getGlobalSelectorID(M, LocalID));

+}

+

+Selector ASTReader::DecodeSelector(serialization::SelectorID ID) {

+  if (ID == 0)

+    return Selector();

+

+  if (ID > SelectorsLoaded.size()) {

+    Error("selector ID out of range in AST file");

+    return Selector();

+  }

+

+  if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {

+    // Load this selector from the selector table.

+    GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);

+    assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");

+    ModuleFile &M = *I->second;

+    ASTSelectorLookupTrait Trait(*this, M);

+    unsigned Idx = ID - M.BaseSelectorID - NUM_PREDEF_SELECTOR_IDS;

+    SelectorsLoaded[ID - 1] =

+      Trait.ReadKey(M.SelectorLookupTableData + M.SelectorOffsets[Idx], 0);

+    if (DeserializationListener)

+      DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);

+  }

+

+  return SelectorsLoaded[ID - 1];

+}

+

+Selector ASTReader::GetExternalSelector(serialization::SelectorID ID) {

+  return DecodeSelector(ID);

+}

+

+uint32_t ASTReader::GetNumExternalSelectors() {

+  // ID 0 (the null selector) is considered an external selector.

+  return getTotalNumSelectors() + 1;

+}

+

+serialization::SelectorID

+ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const {

+  if (LocalID < NUM_PREDEF_SELECTOR_IDS)

+    return LocalID;

+  

+  ContinuousRangeMap<uint32_t, int, 2>::iterator I

+    = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);

+  assert(I != M.SelectorRemap.end() 

+         && "Invalid index into selector index remap");

+  

+  return LocalID + I->second;

+}

+

+DeclarationName

+ASTReader::ReadDeclarationName(ModuleFile &F, 

+                               const RecordData &Record, unsigned &Idx) {

+  DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];

+  switch (Kind) {

+  case DeclarationName::Identifier:

+    return DeclarationName(GetIdentifierInfo(F, Record, Idx));

+

+  case DeclarationName::ObjCZeroArgSelector:

+  case DeclarationName::ObjCOneArgSelector:

+  case DeclarationName::ObjCMultiArgSelector:

+    return DeclarationName(ReadSelector(F, Record, Idx));

+

+  case DeclarationName::CXXConstructorName:

+    return Context.DeclarationNames.getCXXConstructorName(

+                          Context.getCanonicalType(readType(F, Record, Idx)));

+

+  case DeclarationName::CXXDestructorName:

+    return Context.DeclarationNames.getCXXDestructorName(

+                          Context.getCanonicalType(readType(F, Record, Idx)));

+

+  case DeclarationName::CXXConversionFunctionName:

+    return Context.DeclarationNames.getCXXConversionFunctionName(

+                          Context.getCanonicalType(readType(F, Record, Idx)));

+

+  case DeclarationName::CXXOperatorName:

+    return Context.DeclarationNames.getCXXOperatorName(

+                                       (OverloadedOperatorKind)Record[Idx++]);

+

+  case DeclarationName::CXXLiteralOperatorName:

+    return Context.DeclarationNames.getCXXLiteralOperatorName(

+                                       GetIdentifierInfo(F, Record, Idx));

+

+  case DeclarationName::CXXUsingDirective:

+    return DeclarationName::getUsingDirectiveName();

+  }

+

+  llvm_unreachable("Invalid NameKind!");

+}

+

+void ASTReader::ReadDeclarationNameLoc(ModuleFile &F,

+                                       DeclarationNameLoc &DNLoc,

+                                       DeclarationName Name,

+                                      const RecordData &Record, unsigned &Idx) {

+  switch (Name.getNameKind()) {

+  case DeclarationName::CXXConstructorName:

+  case DeclarationName::CXXDestructorName:

+  case DeclarationName::CXXConversionFunctionName:

+    DNLoc.NamedType.TInfo = GetTypeSourceInfo(F, Record, Idx);

+    break;

+

+  case DeclarationName::CXXOperatorName:

+    DNLoc.CXXOperatorName.BeginOpNameLoc

+        = ReadSourceLocation(F, Record, Idx).getRawEncoding();

+    DNLoc.CXXOperatorName.EndOpNameLoc

+        = ReadSourceLocation(F, Record, Idx).getRawEncoding();

+    break;

+

+  case DeclarationName::CXXLiteralOperatorName:

+    DNLoc.CXXLiteralOperatorName.OpNameLoc

+        = ReadSourceLocation(F, Record, Idx).getRawEncoding();

+    break;

+

+  case DeclarationName::Identifier:

+  case DeclarationName::ObjCZeroArgSelector:

+  case DeclarationName::ObjCOneArgSelector:

+  case DeclarationName::ObjCMultiArgSelector:

+  case DeclarationName::CXXUsingDirective:

+    break;

+  }

+}

+

+void ASTReader::ReadDeclarationNameInfo(ModuleFile &F,

+                                        DeclarationNameInfo &NameInfo,

+                                      const RecordData &Record, unsigned &Idx) {

+  NameInfo.setName(ReadDeclarationName(F, Record, Idx));

+  NameInfo.setLoc(ReadSourceLocation(F, Record, Idx));

+  DeclarationNameLoc DNLoc;

+  ReadDeclarationNameLoc(F, DNLoc, NameInfo.getName(), Record, Idx);

+  NameInfo.setInfo(DNLoc);

+}

+

+void ASTReader::ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info,

+                                  const RecordData &Record, unsigned &Idx) {

+  Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);

+  unsigned NumTPLists = Record[Idx++];

+  Info.NumTemplParamLists = NumTPLists;

+  if (NumTPLists) {

+    Info.TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];

+    for (unsigned i=0; i != NumTPLists; ++i)

+      Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx);

+  }

+}

+

+TemplateName

+ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, 

+                            unsigned &Idx) {

+  TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];

+  switch (Kind) {

+  case TemplateName::Template:

+      return TemplateName(ReadDeclAs<TemplateDecl>(F, Record, Idx));

+

+  case TemplateName::OverloadedTemplate: {

+    unsigned size = Record[Idx++];

+    UnresolvedSet<8> Decls;

+    while (size--)

+      Decls.addDecl(ReadDeclAs<NamedDecl>(F, Record, Idx));

+

+    return Context.getOverloadedTemplateName(Decls.begin(), Decls.end());

+  }

+

+  case TemplateName::QualifiedTemplate: {

+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);

+    bool hasTemplKeyword = Record[Idx++];

+    TemplateDecl *Template = ReadDeclAs<TemplateDecl>(F, Record, Idx);

+    return Context.getQualifiedTemplateName(NNS, hasTemplKeyword, Template);

+  }

+

+  case TemplateName::DependentTemplate: {

+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);

+    if (Record[Idx++])  // isIdentifier

+      return Context.getDependentTemplateName(NNS,

+                                               GetIdentifierInfo(F, Record, 

+                                                                 Idx));

+    return Context.getDependentTemplateName(NNS,

+                                         (OverloadedOperatorKind)Record[Idx++]);

+  }

+

+  case TemplateName::SubstTemplateTemplateParm: {

+    TemplateTemplateParmDecl *param

+      = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);

+    if (!param) return TemplateName();

+    TemplateName replacement = ReadTemplateName(F, Record, Idx);

+    return Context.getSubstTemplateTemplateParm(param, replacement);

+  }

+      

+  case TemplateName::SubstTemplateTemplateParmPack: {

+    TemplateTemplateParmDecl *Param 

+      = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);

+    if (!Param)

+      return TemplateName();

+    

+    TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx);

+    if (ArgPack.getKind() != TemplateArgument::Pack)

+      return TemplateName();

+    

+    return Context.getSubstTemplateTemplateParmPack(Param, ArgPack);

+  }

+  }

+

+  llvm_unreachable("Unhandled template name kind!");

+}

+

+TemplateArgument

+ASTReader::ReadTemplateArgument(ModuleFile &F,

+                                const RecordData &Record, unsigned &Idx) {

+  TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++];

+  switch (Kind) {

+  case TemplateArgument::Null:

+    return TemplateArgument();

+  case TemplateArgument::Type:

+    return TemplateArgument(readType(F, Record, Idx));

+  case TemplateArgument::Declaration: {

+    ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx);

+    bool ForReferenceParam = Record[Idx++];

+    return TemplateArgument(D, ForReferenceParam);

+  }

+  case TemplateArgument::NullPtr:

+    return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true);

+  case TemplateArgument::Integral: {

+    llvm::APSInt Value = ReadAPSInt(Record, Idx);

+    QualType T = readType(F, Record, Idx);

+    return TemplateArgument(Context, Value, T);

+  }

+  case TemplateArgument::Template: 

+    return TemplateArgument(ReadTemplateName(F, Record, Idx));

+  case TemplateArgument::TemplateExpansion: {

+    TemplateName Name = ReadTemplateName(F, Record, Idx);

+    llvm::Optional<unsigned> NumTemplateExpansions;

+    if (unsigned NumExpansions = Record[Idx++])

+      NumTemplateExpansions = NumExpansions - 1;

+    return TemplateArgument(Name, NumTemplateExpansions);

+  }

+  case TemplateArgument::Expression:

+    return TemplateArgument(ReadExpr(F));

+  case TemplateArgument::Pack: {

+    unsigned NumArgs = Record[Idx++];

+    TemplateArgument *Args = new (Context) TemplateArgument[NumArgs];

+    for (unsigned I = 0; I != NumArgs; ++I)

+      Args[I] = ReadTemplateArgument(F, Record, Idx);

+    return TemplateArgument(Args, NumArgs);

+  }

+  }

+

+  llvm_unreachable("Unhandled template argument kind!");

+}

+

+TemplateParameterList *

+ASTReader::ReadTemplateParameterList(ModuleFile &F,

+                                     const RecordData &Record, unsigned &Idx) {

+  SourceLocation TemplateLoc = ReadSourceLocation(F, Record, Idx);

+  SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Idx);

+  SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Idx);

+

+  unsigned NumParams = Record[Idx++];

+  SmallVector<NamedDecl *, 16> Params;

+  Params.reserve(NumParams);

+  while (NumParams--)

+    Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));

+

+  TemplateParameterList* TemplateParams =

+    TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,

+                                  Params.data(), Params.size(), RAngleLoc);

+  return TemplateParams;

+}

+

+void

+ASTReader::

+ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs,

+                         ModuleFile &F, const RecordData &Record,

+                         unsigned &Idx) {

+  unsigned NumTemplateArgs = Record[Idx++];

+  TemplArgs.reserve(NumTemplateArgs);

+  while (NumTemplateArgs--)

+    TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx));

+}

+

+/// \brief Read a UnresolvedSet structure.

+void ASTReader::ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set,

+                                  const RecordData &Record, unsigned &Idx) {

+  unsigned NumDecls = Record[Idx++];

+  Set.reserve(Context, NumDecls);

+  while (NumDecls--) {

+    NamedDecl *D = ReadDeclAs<NamedDecl>(F, Record, Idx);

+    AccessSpecifier AS = (AccessSpecifier)Record[Idx++];

+    Set.addDecl(Context, D, AS);

+  }

+}

+

+CXXBaseSpecifier

+ASTReader::ReadCXXBaseSpecifier(ModuleFile &F,

+                                const RecordData &Record, unsigned &Idx) {

+  bool isVirtual = static_cast<bool>(Record[Idx++]);

+  bool isBaseOfClass = static_cast<bool>(Record[Idx++]);

+  AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);

+  bool inheritConstructors = static_cast<bool>(Record[Idx++]);

+  TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx);

+  SourceRange Range = ReadSourceRange(F, Record, Idx);

+  SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx);

+  CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo, 

+                          EllipsisLoc);

+  Result.setInheritConstructors(inheritConstructors);

+  return Result;

+}

+

+std::pair<CXXCtorInitializer **, unsigned>

+ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,

+                                   unsigned &Idx) {

+  CXXCtorInitializer **CtorInitializers = 0;

+  unsigned NumInitializers = Record[Idx++];

+  if (NumInitializers) {

+    CtorInitializers

+        = new (Context) CXXCtorInitializer*[NumInitializers];

+    for (unsigned i=0; i != NumInitializers; ++i) {

+      TypeSourceInfo *TInfo = 0;

+      bool IsBaseVirtual = false;

+      FieldDecl *Member = 0;

+      IndirectFieldDecl *IndirectMember = 0;

+

+      CtorInitializerType Type = (CtorInitializerType)Record[Idx++];

+      switch (Type) {

+      case CTOR_INITIALIZER_BASE:

+        TInfo = GetTypeSourceInfo(F, Record, Idx);

+        IsBaseVirtual = Record[Idx++];

+        break;

+          

+      case CTOR_INITIALIZER_DELEGATING:

+        TInfo = GetTypeSourceInfo(F, Record, Idx);

+        break;

+

+       case CTOR_INITIALIZER_MEMBER:

+        Member = ReadDeclAs<FieldDecl>(F, Record, Idx);

+        break;

+

+       case CTOR_INITIALIZER_INDIRECT_MEMBER:

+        IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx);

+        break;

+      }

+

+      SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx);

+      Expr *Init = ReadExpr(F);

+      SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);

+      SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);

+      bool IsWritten = Record[Idx++];

+      unsigned SourceOrderOrNumArrayIndices;

+      SmallVector<VarDecl *, 8> Indices;

+      if (IsWritten) {

+        SourceOrderOrNumArrayIndices = Record[Idx++];

+      } else {

+        SourceOrderOrNumArrayIndices = Record[Idx++];

+        Indices.reserve(SourceOrderOrNumArrayIndices);

+        for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)

+          Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx));

+      }

+

+      CXXCtorInitializer *BOMInit;

+      if (Type == CTOR_INITIALIZER_BASE) {

+        BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, IsBaseVirtual,

+                                             LParenLoc, Init, RParenLoc,

+                                             MemberOrEllipsisLoc);

+      } else if (Type == CTOR_INITIALIZER_DELEGATING) {

+        BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, LParenLoc,

+                                                   Init, RParenLoc);

+      } else if (IsWritten) {

+        if (Member)

+          BOMInit = new (Context) CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc,

+                                               LParenLoc, Init, RParenLoc);

+        else 

+          BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember,

+                                               MemberOrEllipsisLoc, LParenLoc,

+                                               Init, RParenLoc);

+      } else {

+        BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc,

+                                             LParenLoc, Init, RParenLoc,

+                                             Indices.data(), Indices.size());

+      }

+

+      if (IsWritten)

+        BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices);

+      CtorInitializers[i] = BOMInit;

+    }

+  }

+

+  return std::make_pair(CtorInitializers, NumInitializers);

+}

+

+NestedNameSpecifier *

+ASTReader::ReadNestedNameSpecifier(ModuleFile &F,

+                                   const RecordData &Record, unsigned &Idx) {

+  unsigned N = Record[Idx++];

+  NestedNameSpecifier *NNS = 0, *Prev = 0;

+  for (unsigned I = 0; I != N; ++I) {

+    NestedNameSpecifier::SpecifierKind Kind

+      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];

+    switch (Kind) {

+    case NestedNameSpecifier::Identifier: {

+      IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);

+      NNS = NestedNameSpecifier::Create(Context, Prev, II);

+      break;

+    }

+

+    case NestedNameSpecifier::Namespace: {

+      NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);

+      NNS = NestedNameSpecifier::Create(Context, Prev, NS);

+      break;

+    }

+

+    case NestedNameSpecifier::NamespaceAlias: {

+      NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);

+      NNS = NestedNameSpecifier::Create(Context, Prev, Alias);

+      break;

+    }

+

+    case NestedNameSpecifier::TypeSpec:

+    case NestedNameSpecifier::TypeSpecWithTemplate: {

+      const Type *T = readType(F, Record, Idx).getTypePtrOrNull();

+      if (!T)

+        return 0;

+      

+      bool Template = Record[Idx++];

+      NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);

+      break;

+    }

+

+    case NestedNameSpecifier::Global: {

+      NNS = NestedNameSpecifier::GlobalSpecifier(Context);

+      // No associated value, and there can't be a prefix.

+      break;

+    }

+    }

+    Prev = NNS;

+  }

+  return NNS;

+}

+

+NestedNameSpecifierLoc

+ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, 

+                                      unsigned &Idx) {

+  unsigned N = Record[Idx++];

+  NestedNameSpecifierLocBuilder Builder;

+  for (unsigned I = 0; I != N; ++I) {

+    NestedNameSpecifier::SpecifierKind Kind

+      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];

+    switch (Kind) {

+    case NestedNameSpecifier::Identifier: {

+      IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);      

+      SourceRange Range = ReadSourceRange(F, Record, Idx);

+      Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());

+      break;

+    }

+

+    case NestedNameSpecifier::Namespace: {

+      NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);

+      SourceRange Range = ReadSourceRange(F, Record, Idx);

+      Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());

+      break;

+    }

+

+    case NestedNameSpecifier::NamespaceAlias: {

+      NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);

+      SourceRange Range = ReadSourceRange(F, Record, Idx);

+      Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());

+      break;

+    }

+

+    case NestedNameSpecifier::TypeSpec:

+    case NestedNameSpecifier::TypeSpecWithTemplate: {

+      bool Template = Record[Idx++];

+      TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);

+      if (!T)

+        return NestedNameSpecifierLoc();

+      SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);

+

+      // FIXME: 'template' keyword location not saved anywhere, so we fake it.

+      Builder.Extend(Context, 

+                     Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),

+                     T->getTypeLoc(), ColonColonLoc);

+      break;

+    }

+

+    case NestedNameSpecifier::Global: {

+      SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);

+      Builder.MakeGlobal(Context, ColonColonLoc);

+      break;

+    }

+    }

+  }

+  

+  return Builder.getWithLocInContext(Context);

+}

+

+SourceRange

+ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record,

+                           unsigned &Idx) {

+  SourceLocation beg = ReadSourceLocation(F, Record, Idx);

+  SourceLocation end = ReadSourceLocation(F, Record, Idx);

+  return SourceRange(beg, end);

+}

+

+/// \brief Read an integral value

+llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {

+  unsigned BitWidth = Record[Idx++];

+  unsigned NumWords = llvm::APInt::getNumWords(BitWidth);

+  llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);

+  Idx += NumWords;

+  return Result;

+}

+

+/// \brief Read a signed integral value

+llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {

+  bool isUnsigned = Record[Idx++];

+  return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);

+}

+

+/// \brief Read a floating-point value

+llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {

+  return llvm::APFloat(ReadAPInt(Record, Idx));

+}

+

+// \brief Read a string

+std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {

+  unsigned Len = Record[Idx++];

+  std::string Result(Record.data() + Idx, Record.data() + Idx + Len);

+  Idx += Len;

+  return Result;

+}

+

+VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, 

+                                         unsigned &Idx) {

+  unsigned Major = Record[Idx++];

+  unsigned Minor = Record[Idx++];

+  unsigned Subminor = Record[Idx++];

+  if (Minor == 0)

+    return VersionTuple(Major);

+  if (Subminor == 0)

+    return VersionTuple(Major, Minor - 1);

+  return VersionTuple(Major, Minor - 1, Subminor - 1);

+}

+

+CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, 

+                                          const RecordData &Record,

+                                          unsigned &Idx) {

+  CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx);

+  return CXXTemporary::Create(Context, Decl);

+}

+

+DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {

+  return Diag(SourceLocation(), DiagID);

+}

+

+DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {

+  return Diags.Report(Loc, DiagID);

+}

+

+/// \brief Retrieve the identifier table associated with the

+/// preprocessor.

+IdentifierTable &ASTReader::getIdentifierTable() {

+  return PP.getIdentifierTable();

+}

+

+/// \brief Record that the given ID maps to the given switch-case

+/// statement.

+void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {

+  assert((*CurrSwitchCaseStmts)[ID] == 0 &&

+         "Already have a SwitchCase with this ID");

+  (*CurrSwitchCaseStmts)[ID] = SC;

+}

+

+/// \brief Retrieve the switch-case statement with the given ID.

+SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {

+  assert((*CurrSwitchCaseStmts)[ID] != 0 && "No SwitchCase with this ID");

+  return (*CurrSwitchCaseStmts)[ID];

+}

+

+void ASTReader::ClearSwitchCaseIDs() {

+  CurrSwitchCaseStmts->clear();

+}

+

+void ASTReader::ReadComments() {

+  std::vector<RawComment *> Comments;

+  for (SmallVectorImpl<std::pair<llvm::BitstreamCursor,

+                                 serialization::ModuleFile *> >::iterator

+       I = CommentsCursors.begin(),

+       E = CommentsCursors.end();

+       I != E; ++I) {

+    llvm::BitstreamCursor &Cursor = I->first;

+    serialization::ModuleFile &F = *I->second;

+    SavedStreamPosition SavedPosition(Cursor);

+

+    RecordData Record;

+    while (true) {

+      unsigned Code = Cursor.ReadCode();

+      if (Code == llvm::bitc::END_BLOCK)

+        break;

+

+      if (Code == llvm::bitc::ENTER_SUBBLOCK) {

+        // No known subblocks, always skip them.

+        Cursor.ReadSubBlockID();

+        if (Cursor.SkipBlock()) {

+          Error("malformed block record in AST file");

+          return;

+        }

+        continue;

+      }

+

+      if (Code == llvm::bitc::DEFINE_ABBREV) {

+        Cursor.ReadAbbrevRecord();

+        continue;

+      }

+

+      // Read a record.

+      Record.clear();

+      switch ((CommentRecordTypes) Cursor.ReadRecord(Code, Record)) {

+      case COMMENTS_RAW_COMMENT: {

+        unsigned Idx = 0;

+        SourceRange SR = ReadSourceRange(F, Record, Idx);

+        RawComment::CommentKind Kind =

+            (RawComment::CommentKind) Record[Idx++];

+        bool IsTrailingComment = Record[Idx++];

+        bool IsAlmostTrailingComment = Record[Idx++];

+        Comments.push_back(new (Context) RawComment(SR, Kind,

+                                                    IsTrailingComment,

+                                                    IsAlmostTrailingComment));

+        break;

+      }

+      }

+    }

+  }

+  Context.Comments.addCommentsToFront(Comments);

+}

+

+void ASTReader::finishPendingActions() {

+  while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() ||

+         !PendingMacroIDs.empty()) {

+    // If any identifiers with corresponding top-level declarations have

+    // been loaded, load those declarations now.

+    while (!PendingIdentifierInfos.empty()) {

+      SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,

+                              PendingIdentifierInfos.front().DeclIDs, true);

+      PendingIdentifierInfos.pop_front();

+    }

+  

+    // Load pending declaration chains.

+    for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {

+      loadPendingDeclChain(PendingDeclChains[I]);

+      PendingDeclChainsKnown.erase(PendingDeclChains[I]);

+    }

+    PendingDeclChains.clear();

+

+    // Load any pending macro definitions.

+    for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) {

+      // FIXME: std::move here

+      SmallVector<MacroID, 2> GlobalIDs = PendingMacroIDs.begin()[I].second;

+      MacroInfo *Hint = 0;

+      for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx !=  NumIDs;

+           ++IDIdx) {

+        Hint = getMacro(GlobalIDs[IDIdx], Hint);

+      }

+    }

+    PendingMacroIDs.clear();

+  }

+  

+  // If we deserialized any C++ or Objective-C class definitions, any

+  // Objective-C protocol definitions, or any redeclarable templates, make sure

+  // that all redeclarations point to the definitions. Note that this can only 

+  // happen now, after the redeclaration chains have been fully wired.

+  for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),

+                                           DEnd = PendingDefinitions.end();

+       D != DEnd; ++D) {

+    if (TagDecl *TD = dyn_cast<TagDecl>(*D)) {

+      if (const TagType *TagT = dyn_cast<TagType>(TD->TypeForDecl)) {

+        // Make sure that the TagType points at the definition.

+        const_cast<TagType*>(TagT)->decl = TD;

+      }

+      

+      if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {

+        for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),

+                                         REnd = RD->redecls_end();

+             R != REnd; ++R)

+          cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;

+        

+      }

+

+      continue;

+    }

+    

+    if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {

+      // Make sure that the ObjCInterfaceType points at the definition.

+      const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))

+        ->Decl = ID;

+      

+      for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),

+                                           REnd = ID->redecls_end();

+           R != REnd; ++R)

+        R->Data = ID->Data;

+      

+      continue;

+    }

+    

+    if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(*D)) {

+      for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),

+                                          REnd = PD->redecls_end();

+           R != REnd; ++R)

+        R->Data = PD->Data;

+      

+      continue;

+    }

+    

+    RedeclarableTemplateDecl *RTD

+      = cast<RedeclarableTemplateDecl>(*D)->getCanonicalDecl();

+    for (RedeclarableTemplateDecl::redecl_iterator R = RTD->redecls_begin(),

+                                                REnd = RTD->redecls_end();

+         R != REnd; ++R)

+      R->Common = RTD->Common;

+  }

+  PendingDefinitions.clear();

+

+  // Load the bodies of any functions or methods we've encountered. We do

+  // this now (delayed) so that we can be sure that the declaration chains

+  // have been fully wired up.

+  for (PendingBodiesMap::iterator PB = PendingBodies.begin(),

+                               PBEnd = PendingBodies.end();

+       PB != PBEnd; ++PB) {

+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {

+      // FIXME: Check for =delete/=default?

+      // FIXME: Complain about ODR violations here?

+      if (!getContext().getLangOpts().Modules || !FD->hasBody())

+        FD->setLazyBody(PB->second);

+      continue;

+    }

+

+    ObjCMethodDecl *MD = cast<ObjCMethodDecl>(PB->first);

+    if (!getContext().getLangOpts().Modules || !MD->hasBody())

+      MD->setLazyBody(PB->second);

+  }

+  PendingBodies.clear();

+}

+

+void ASTReader::FinishedDeserializing() {

+  assert(NumCurrentElementsDeserializing &&

+         "FinishedDeserializing not paired with StartedDeserializing");

+  if (NumCurrentElementsDeserializing == 1) {

+    // We decrease NumCurrentElementsDeserializing only after pending actions

+    // are finished, to avoid recursively re-calling finishPendingActions().

+    finishPendingActions();

+  }

+  --NumCurrentElementsDeserializing;

+

+  if (NumCurrentElementsDeserializing == 0 &&

+      Consumer && !PassingDeclsToConsumer) {

+    // Guard variable to avoid recursively redoing the process of passing

+    // decls to consumer.

+    SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,

+                                                     true);

+

+    while (!InterestingDecls.empty()) {

+      // We are not in recursive loading, so it's safe to pass the "interesting"

+      // decls to the consumer.

+      Decl *D = InterestingDecls.front();

+      InterestingDecls.pop_front();

+      PassInterestingDeclToConsumer(D);

+    }

+  }

+}

+

+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,

+                     StringRef isysroot, bool DisableValidation,

+                     bool AllowASTWithCompilerErrors)

+  : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),

+    SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),

+    Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),

+    Consumer(0), ModuleMgr(PP.getFileManager()),

+    isysroot(isysroot), DisableValidation(DisableValidation),

+    AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), 

+    CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),

+    NumSLocEntriesRead(0), TotalNumSLocEntries(0), 

+    NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), 

+    TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0), 

+    NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0), 

+    NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), 

+    NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),

+    TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),

+    PassingDeclsToConsumer(false),

+    NumCXXBaseSpecifiersLoaded(0)

+{

+  SourceMgr.setExternalSLocEntrySource(this);

+}

+

+ASTReader::~ASTReader() {

+  for (DeclContextVisibleUpdatesPending::iterator

+           I = PendingVisibleUpdates.begin(),

+           E = PendingVisibleUpdates.end();

+       I != E; ++I) {

+    for (DeclContextVisibleUpdates::iterator J = I->second.begin(),

+                                             F = I->second.end();

+         J != F; ++J)

+      delete J->first;

+  }

+}