diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index d750ba9..86b2c42 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -716,9 +716,6 @@
   CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
   CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
   CanQualType ObjCBuiltinBoolTy;
-  CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
-  CanQualType OCLImage2dTy, OCLImage2dArrayTy;
-  CanQualType OCLImage3dTy;
 
   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
   mutable QualType AutoDeductTy;     // Deduction against 'auto'.
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index 75ebb2c..ba322fb 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -1,234 +1,226 @@
-//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- 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 database about various builtin singleton types.
-//
-//  BuiltinType::Id is the enumerator defining the type.
-//
-//  Context.SingletonId is the global singleton of this type.  Some global
-//  singletons are shared by multiple types.
-//
-//    BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been
-//    covered by any other #define.  Defining this macro covers all
-//    the builtins.
-//
-//    SIGNED_TYPE(Id, SingletonId) - A signed integral type.
-//
-//    UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type.
-//
-//    FLOATING_TYPE(Id, SingletonId) - A floating-point type.
-//
-//    PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type.  Placeholder
-//    types are used to perform context-sensitive checking of specific
-//    forms of expression.
-//
-//    SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds
-//    to a builtin which uses a shared singleton type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SIGNED_TYPE
-#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef UNSIGNED_TYPE
-#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef FLOATING_TYPE
-#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef PLACEHOLDER_TYPE
-#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef SHARED_SINGLETON_TYPE
-#define SHARED_SINGLETON_TYPE(Expansion) Expansion
-#endif
-
-//===- Builtin Types ------------------------------------------------------===//
-
-// void
-BUILTIN_TYPE(Void, VoidTy)
-
-//===- Unsigned Types -----------------------------------------------------===//
-
-// 'bool' in C++, '_Bool' in C99
-UNSIGNED_TYPE(Bool, BoolTy)
-
-// 'char' for targets where it's unsigned
-SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy))
-
-// 'unsigned char', explicitly qualified
-UNSIGNED_TYPE(UChar, UnsignedCharTy)
-
-// 'wchar_t' for targets where it's unsigned
-SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
-
-// 'char16_t' in C++
-UNSIGNED_TYPE(Char16, Char16Ty)
-
-// 'char32_t' in C++
-UNSIGNED_TYPE(Char32, Char32Ty)
-
-// 'unsigned short'
-UNSIGNED_TYPE(UShort, UnsignedShortTy)
-
-// 'unsigned int'
-UNSIGNED_TYPE(UInt, UnsignedIntTy)
-
-// 'unsigned long'
-UNSIGNED_TYPE(ULong, UnsignedLongTy)
-
-// 'unsigned long long'
-UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy)
-
-// '__uint128_t'
-UNSIGNED_TYPE(UInt128, UnsignedInt128Ty)
-
-//===- Signed Types -------------------------------------------------------===//
-
-// 'char' for targets where it's signed
-SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy))
-
-// 'signed char', explicitly qualified
-SIGNED_TYPE(SChar, SignedCharTy)
-
-// 'wchar_t' for targets where it's signed
-SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy))
-
-// 'short' or 'signed short'
-SIGNED_TYPE(Short, ShortTy)
-
-// 'int' or 'signed int'
-SIGNED_TYPE(Int, IntTy)
-
-// 'long' or 'signed long'
-SIGNED_TYPE(Long, LongTy)
-
-// 'long long' or 'signed long long'
-SIGNED_TYPE(LongLong, LongLongTy)
-
-// '__int128_t'
-SIGNED_TYPE(Int128, Int128Ty)
-
-//===- Floating point types -----------------------------------------------===//
-
-// 'half' in OpenCL, '__fp16' in ARM NEON.
-FLOATING_TYPE(Half, HalfTy)
-
-// 'float'
-FLOATING_TYPE(Float, FloatTy)
-
-// 'double'
-FLOATING_TYPE(Double, DoubleTy)
-
-// 'long double'
-FLOATING_TYPE(LongDouble, LongDoubleTy)
-
-//===- Language-specific types --------------------------------------------===//
-
-// This is the type of C++0x 'nullptr'.
-BUILTIN_TYPE(NullPtr, NullPtrTy)
-
-// The primitive Objective C 'id' type.  The user-visible 'id'
-// type is a typedef of an ObjCObjectPointerType to an
-// ObjCObjectType with this as its base.  In fact, this only ever
-// shows up in an AST as the base type of an ObjCObjectType.
-BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy)
-
-// The primitive Objective C 'Class' type.  The user-visible
-// 'Class' type is a typedef of an ObjCObjectPointerType to an
-// ObjCObjectType with this as its base.  In fact, this only ever
-// shows up in an AST as the base type of an ObjCObjectType.
-BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
-
-// The primitive Objective C 'SEL' type.  The user-visible 'SEL'
-// type is a typedef of a PointerType to this.
-BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
-
-// OpenCL image types.
-BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
-BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
-BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
-BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
-BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
-BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
-
-// This represents the type of an expression whose type is
-// totally unknown, e.g. 'T::foo'.  It is permitted for this to
-// appear in situations where the structure of the type is
-// theoretically deducible.
-BUILTIN_TYPE(Dependent, DependentTy)
-
-// The type of an unresolved overload set.  A placeholder type.
-// Expressions with this type have one of the following basic
-// forms, with parentheses generally permitted:
-//   foo          # possibly qualified, not if an implicit access
-//   foo          # possibly qualified, not if an implicit access
-//   &foo         # possibly qualified, not if an implicit access
-//   x->foo       # only if might be a static member function
-//   &x->foo      # only if might be a static member function
-//   &Class::foo  # when a pointer-to-member; sub-expr also has this type
-// OverloadExpr::find can be used to analyze the expression.
-//
-// Overload should be the first placeholder type, or else change
-// BuiltinType::isNonOverloadPlaceholderType()
-PLACEHOLDER_TYPE(Overload, OverloadTy)
-
-// The type of a bound C++ non-static member function.
-// A placeholder type.  Expressions with this type have one of the
-// following basic forms:
-//   foo          # if an implicit access
-//   x->foo       # if only contains non-static members
-PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
-
-// The type of an expression which refers to a pseudo-object,
-// such as those introduced by Objective C's @property or
-// VS.NET's __property declarations.  A placeholder type.  The
-// pseudo-object is actually accessed by emitting a call to
-// some sort of function or method;  typically there is a pair
-// of a setter and a getter, with the setter used if the
-// pseudo-object reference is used syntactically as the
-// left-hand-side of an assignment operator.
-//
-// A pseudo-object reference naming an Objective-C @property is
-// always a dot access with a base of object-pointer type,
-// e.g. 'x.foo'.
-//
-// In VS.NET, a __property declaration creates an implicit
-// member with an associated name, which can then be named
-// in any of the normal ways an ordinary member could be.
-PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
-
-// __builtin_any_type.  A placeholder type.  Useful for clients
-// like debuggers that don't know what type to give something.
-// Only a small number of operations are valid on expressions of
-// unknown type, most notably explicit casts.
-PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
-
-PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
-
-// The type of a cast which, in ARC, would normally require a
-// __bridge, but which might be okay depending on the immediate
-// context.
-PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
-
-#ifdef LAST_BUILTIN_TYPE
-LAST_BUILTIN_TYPE(ARCUnbridgedCast)
-#undef LAST_BUILTIN_TYPE
-#endif
-
-#undef SHARED_SINGLETON_TYPE
-#undef PLACEHOLDER_TYPE
-#undef FLOATING_TYPE
-#undef SIGNED_TYPE
-#undef UNSIGNED_TYPE
-#undef BUILTIN_TYPE
+//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- 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 database about various builtin singleton types.
+//
+//  BuiltinType::Id is the enumerator defining the type.
+//
+//  Context.SingletonId is the global singleton of this type.  Some global
+//  singletons are shared by multiple types.
+//
+//    BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been
+//    covered by any other #define.  Defining this macro covers all
+//    the builtins.
+//
+//    SIGNED_TYPE(Id, SingletonId) - A signed integral type.
+//
+//    UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type.
+//
+//    FLOATING_TYPE(Id, SingletonId) - A floating-point type.
+//
+//    PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type.  Placeholder
+//    types are used to perform context-sensitive checking of specific
+//    forms of expression.
+//
+//    SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds
+//    to a builtin which uses a shared singleton type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SIGNED_TYPE
+#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef UNSIGNED_TYPE
+#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef FLOATING_TYPE
+#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef PLACEHOLDER_TYPE
+#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef SHARED_SINGLETON_TYPE
+#define SHARED_SINGLETON_TYPE(Expansion) Expansion
+#endif
+
+//===- Builtin Types ------------------------------------------------------===//
+
+// void
+BUILTIN_TYPE(Void, VoidTy)
+
+//===- Unsigned Types -----------------------------------------------------===//
+
+// 'bool' in C++, '_Bool' in C99
+UNSIGNED_TYPE(Bool, BoolTy)
+
+// 'char' for targets where it's unsigned
+SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy))
+
+// 'unsigned char', explicitly qualified
+UNSIGNED_TYPE(UChar, UnsignedCharTy)
+
+// 'wchar_t' for targets where it's unsigned
+SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
+
+// 'char16_t' in C++
+UNSIGNED_TYPE(Char16, Char16Ty)
+
+// 'char32_t' in C++
+UNSIGNED_TYPE(Char32, Char32Ty)
+
+// 'unsigned short'
+UNSIGNED_TYPE(UShort, UnsignedShortTy)
+
+// 'unsigned int'
+UNSIGNED_TYPE(UInt, UnsignedIntTy)
+
+// 'unsigned long'
+UNSIGNED_TYPE(ULong, UnsignedLongTy)
+
+// 'unsigned long long'
+UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy)
+
+// '__uint128_t'
+UNSIGNED_TYPE(UInt128, UnsignedInt128Ty)
+
+//===- Signed Types -------------------------------------------------------===//
+
+// 'char' for targets where it's signed
+SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy))
+
+// 'signed char', explicitly qualified
+SIGNED_TYPE(SChar, SignedCharTy)
+
+// 'wchar_t' for targets where it's signed
+SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy))
+
+// 'short' or 'signed short'
+SIGNED_TYPE(Short, ShortTy)
+
+// 'int' or 'signed int'
+SIGNED_TYPE(Int, IntTy)
+
+// 'long' or 'signed long'
+SIGNED_TYPE(Long, LongTy)
+
+// 'long long' or 'signed long long'
+SIGNED_TYPE(LongLong, LongLongTy)
+
+// '__int128_t'
+SIGNED_TYPE(Int128, Int128Ty)
+
+//===- Floating point types -----------------------------------------------===//
+
+// 'half' in OpenCL, '__fp16' in ARM NEON.
+FLOATING_TYPE(Half, HalfTy)
+
+// 'float'
+FLOATING_TYPE(Float, FloatTy)
+
+// 'double'
+FLOATING_TYPE(Double, DoubleTy)
+
+// 'long double'
+FLOATING_TYPE(LongDouble, LongDoubleTy)
+
+//===- Language-specific types --------------------------------------------===//
+
+// This is the type of C++0x 'nullptr'.
+BUILTIN_TYPE(NullPtr, NullPtrTy)
+
+// The primitive Objective C 'id' type.  The user-visible 'id'
+// type is a typedef of an ObjCObjectPointerType to an
+// ObjCObjectType with this as its base.  In fact, this only ever
+// shows up in an AST as the base type of an ObjCObjectType.
+BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy)
+
+// The primitive Objective C 'Class' type.  The user-visible
+// 'Class' type is a typedef of an ObjCObjectPointerType to an
+// ObjCObjectType with this as its base.  In fact, this only ever
+// shows up in an AST as the base type of an ObjCObjectType.
+BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
+
+// The primitive Objective C 'SEL' type.  The user-visible 'SEL'
+// type is a typedef of a PointerType to this.
+BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
+
+// This represents the type of an expression whose type is
+// totally unknown, e.g. 'T::foo'.  It is permitted for this to
+// appear in situations where the structure of the type is
+// theoretically deducible.
+BUILTIN_TYPE(Dependent, DependentTy)
+
+// The type of an unresolved overload set.  A placeholder type.
+// Expressions with this type have one of the following basic
+// forms, with parentheses generally permitted:
+//   foo          # possibly qualified, not if an implicit access
+//   foo          # possibly qualified, not if an implicit access
+//   &foo         # possibly qualified, not if an implicit access
+//   x->foo       # only if might be a static member function
+//   &x->foo      # only if might be a static member function
+//   &Class::foo  # when a pointer-to-member; sub-expr also has this type
+// OverloadExpr::find can be used to analyze the expression.
+//
+// Overload should be the first placeholder type, or else change
+// BuiltinType::isNonOverloadPlaceholderType()
+PLACEHOLDER_TYPE(Overload, OverloadTy)
+
+// The type of a bound C++ non-static member function.
+// A placeholder type.  Expressions with this type have one of the
+// following basic forms:
+//   foo          # if an implicit access
+//   x->foo       # if only contains non-static members
+PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
+
+// The type of an expression which refers to a pseudo-object,
+// such as those introduced by Objective C's @property or
+// VS.NET's __property declarations.  A placeholder type.  The
+// pseudo-object is actually accessed by emitting a call to
+// some sort of function or method;  typically there is a pair
+// of a setter and a getter, with the setter used if the
+// pseudo-object reference is used syntactically as the
+// left-hand-side of an assignment operator.
+//
+// A pseudo-object reference naming an Objective-C @property is
+// always a dot access with a base of object-pointer type,
+// e.g. 'x.foo'.
+//
+// In VS.NET, a __property declaration creates an implicit
+// member with an associated name, which can then be named
+// in any of the normal ways an ordinary member could be.
+PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
+
+// __builtin_any_type.  A placeholder type.  Useful for clients
+// like debuggers that don't know what type to give something.
+// Only a small number of operations are valid on expressions of
+// unknown type, most notably explicit casts.
+PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
+
+PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
+
+// The type of a cast which, in ARC, would normally require a
+// __bridge, but which might be okay depending on the immediate
+// context.
+PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
+
+#ifdef LAST_BUILTIN_TYPE
+LAST_BUILTIN_TYPE(ARCUnbridgedCast)
+#undef LAST_BUILTIN_TYPE
+#endif
+
+#undef SHARED_SINGLETON_TYPE
+#undef PLACEHOLDER_TYPE
+#undef FLOATING_TYPE
+#undef SIGNED_TYPE
+#undef UNSIGNED_TYPE
+#undef BUILTIN_TYPE
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index cf3b565..368be8d 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1580,17 +1580,6 @@
   bool isNullPtrType() const;                   // C++0x nullptr_t
   bool isAtomicType() const;                    // C11 _Atomic()
 
-  bool isImage1dT() const;                      // OpenCL image1d_t
-  bool isImage1dArrayT() const;                 // OpenCL image1d_array_t
-  bool isImage1dBufferT() const;                // OpenCL image1d_buffer_t
-  bool isImage2dT() const;                      // OpenCL image2d_t
-  bool isImage2dArrayT() const;                 // OpenCL image2d_array_t
-  bool isImage3dT() const;                      // OpenCL image3d_t
-
-  bool isImageType() const;                     // Any OpenCL image type
-
-  bool isOpenCLSpecificType() const;            // Any OpenCL specific type
-
   /// Determines if this type, which must satisfy
   /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
   /// than implicitly __strong.
@@ -4894,40 +4883,6 @@
 inline bool Type::isObjCBuiltinType() const {
   return isObjCIdType() || isObjCClassType() || isObjCSelType();
 }
-
-inline bool Type::isImage1dT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLImage1d);
-}
-
-inline bool Type::isImage1dArrayT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLImage1dArray);
-}
-
-inline bool Type::isImage1dBufferT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer);
-}
-
-inline bool Type::isImage2dT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLImage2d);
-}
-
-inline bool Type::isImage2dArrayT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLImage2dArray);
-}
-
-inline bool Type::isImage3dT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLImage3d);
-}
-inline bool Type::isImageType() const {
-  return isImage3dT() ||
-         isImage2dT() || isImage2dArrayT() ||
-         isImage1dT() || isImage1dArrayT() || isImage1dBufferT();
-}
-
-inline bool Type::isOpenCLSpecificType() const {
-  return isImageType();
-}
-
 inline bool Type::isTemplateTypeParmType() const {
   return isa<TemplateTypeParmType>(CanonicalType);
 }
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 8a6c629..c82b8cb 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -1,200 +1,194 @@
-//===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines various enumerations that describe declaration and
-/// type specifiers.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
-#define LLVM_CLANG_BASIC_SPECIFIERS_H
-
-namespace clang {
-  /// \brief Specifies the width of a type, e.g., short, long, or long long.
-  enum TypeSpecifierWidth {
-    TSW_unspecified,
-    TSW_short,
-    TSW_long,
-    TSW_longlong
-  };
-  
-  /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
-  enum TypeSpecifierSign {
-    TSS_unspecified,
-    TSS_signed,
-    TSS_unsigned
-  };
-  
-  /// \brief Specifies the kind of type.
-  enum TypeSpecifierType {
-    TST_unspecified,
-    TST_void,
-    TST_char,
-    TST_wchar,        // C++ wchar_t
-    TST_char16,       // C++0x char16_t
-    TST_char32,       // C++0x char32_t
-    TST_int,
-    TST_int128,
-    TST_half,         // OpenCL half, ARM NEON __fp16
-    TST_float,
-    TST_double,
-    TST_bool,         // _Bool
-    TST_decimal32,    // _Decimal32
-    TST_decimal64,    // _Decimal64
-    TST_decimal128,   // _Decimal128
-    TST_enum,
-    TST_union,
-    TST_struct,
-    TST_class,        // C++ class type
-    TST_interface,    // C++ (Microsoft-specific) __interface type
-    TST_typename,     // Typedef, C++ class-name or enum name, etc.
-    TST_typeofType,
-    TST_typeofExpr,
-    TST_decltype,     // C++0x decltype
-    TST_underlyingType, // __underlying_type for C++0x
-    TST_auto,         // C++0x auto
-    TST_unknown_anytype, // __unknown_anytype extension
-    TST_atomic,       // C11 _Atomic
-    TST_image1d_t,        // OpenCL image1d_t
-    TST_image1d_array_t,  // OpenCL image1d_array_t
-    TST_image1d_buffer_t, // OpenCL image1d_buffer_t
-    TST_image2d_t,        // OpenCL image2d_t
-    TST_image2d_array_t,  // OpenCL image2d_array_t
-    TST_image3d_t,        // OpenCL image3d_t
-    TST_error         // erroneous type
-  };
-  
-  /// \brief Structure that packs information about the type specifiers that
-  /// were written in a particular type specifier sequence.
-  struct WrittenBuiltinSpecs {
-    /*DeclSpec::TST*/ unsigned Type  : 6;
-    /*DeclSpec::TSS*/ unsigned Sign  : 2;
-    /*DeclSpec::TSW*/ unsigned Width : 2;
-    bool ModeAttr : 1;
-  };  
-
-  /// \brief A C++ access specifier (public, private, protected), plus the
-  /// special value "none" which means different things in different contexts.
-  enum AccessSpecifier {
-    AS_public,
-    AS_protected,
-    AS_private,
-    AS_none
-  };
-
-  /// \brief The categorization of expression values, currently following the
-  /// C++11 scheme.
-  enum ExprValueKind {
-    /// \brief An r-value expression (a pr-value in the C++11 taxonomy)
-    /// produces a temporary value.
-    VK_RValue,
-
-    /// \brief An l-value expression is a reference to an object with
-    /// independent storage.
-    VK_LValue,
-
-    /// \brief An x-value expression is a reference to an object with
-    /// independent storage but which can be "moved", i.e.
-    /// efficiently cannibalized for its resources.
-    VK_XValue
-  };
-
-  /// \brief A further classification of the kind of object referenced by an
-  /// l-value or x-value.
-  enum ExprObjectKind {
-    /// An ordinary object is located at an address in memory.
-    OK_Ordinary,
-
-    /// A bitfield object is a bitfield on a C or C++ record.
-    OK_BitField,
-
-    /// A vector component is an element or range of elements on a vector.
-    OK_VectorComponent,
-
-    /// An Objective-C property is a logical field of an Objective-C
-    /// object which is read and written via Objective-C method calls.
-    OK_ObjCProperty,
-    
-    /// An Objective-C array/dictionary subscripting which reads an
-    /// object or writes at the subscripted array/dictionary element via
-    /// Objective-C method calls.
-    OK_ObjCSubscript
-  };
-
-  // \brief Describes the kind of template specialization that a
-  // particular template specialization declaration represents.
-  enum TemplateSpecializationKind {
-    /// This template specialization was formed from a template-id but
-    /// has not yet been declared, defined, or instantiated.
-    TSK_Undeclared = 0,
-    /// This template specialization was implicitly instantiated from a
-    /// template. (C++ [temp.inst]).
-    TSK_ImplicitInstantiation,
-    /// This template specialization was declared or defined by an
-    /// explicit specialization (C++ [temp.expl.spec]) or partial
-    /// specialization (C++ [temp.class.spec]).
-    TSK_ExplicitSpecialization,
-    /// This template specialization was instantiated from a template
-    /// due to an explicit instantiation declaration request
-    /// (C++0x [temp.explicit]).
-    TSK_ExplicitInstantiationDeclaration,
-    /// This template specialization was instantiated from a template
-    /// due to an explicit instantiation definition request
-    /// (C++ [temp.explicit]).
-    TSK_ExplicitInstantiationDefinition
-  };
-
-  /// \brief Storage classes.
-  enum StorageClass {
-    // These are legal on both functions and variables.
-    SC_None,
-    SC_Extern,
-    SC_Static,
-    SC_PrivateExtern,
-
-    // These are only legal on variables.
-    SC_OpenCLWorkGroupLocal,
-    SC_Auto,
-    SC_Register
-  };
-
-  /// \brief Checks whether the given storage class is legal for functions.
-  inline bool isLegalForFunction(StorageClass SC) {
-    return SC <= SC_PrivateExtern;
-  }
-
-  /// \brief Checks whether the given storage class is legal for variables.
-  inline bool isLegalForVariable(StorageClass SC) {
-    return true;
-  }
-
-  /// \brief In-class initialization styles for non-static data members.
-  enum InClassInitStyle {
-    ICIS_NoInit,   ///< No in-class initializer.
-    ICIS_CopyInit, ///< Copy initialization.
-    ICIS_ListInit  ///< Direct list-initialization.
-  };
-
-  /// \brief CallingConv - Specifies the calling convention that a function uses.
-  enum CallingConv {
-    CC_Default,
-    CC_C,           // __attribute__((cdecl))
-    CC_X86StdCall,  // __attribute__((stdcall))
-    CC_X86FastCall, // __attribute__((fastcall))
-    CC_X86ThisCall, // __attribute__((thiscall))
-    CC_X86Pascal,   // __attribute__((pascal))
-    CC_AAPCS,       // __attribute__((pcs("aapcs")))
-    CC_AAPCS_VFP,   // __attribute__((pcs("aapcs-vfp")))
-    CC_PnaclCall    // __attribute__((pnaclcall))
-  };
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
+//===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines various enumerations that describe declaration and
+/// type specifiers.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
+#define LLVM_CLANG_BASIC_SPECIFIERS_H
+
+namespace clang {
+  /// \brief Specifies the width of a type, e.g., short, long, or long long.
+  enum TypeSpecifierWidth {
+    TSW_unspecified,
+    TSW_short,
+    TSW_long,
+    TSW_longlong
+  };
+  
+  /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
+  enum TypeSpecifierSign {
+    TSS_unspecified,
+    TSS_signed,
+    TSS_unsigned
+  };
+  
+  /// \brief Specifies the kind of type.
+  enum TypeSpecifierType {
+    TST_unspecified,
+    TST_void,
+    TST_char,
+    TST_wchar,        // C++ wchar_t
+    TST_char16,       // C++0x char16_t
+    TST_char32,       // C++0x char32_t
+    TST_int,
+    TST_int128,
+    TST_half,         // OpenCL half, ARM NEON __fp16
+    TST_float,
+    TST_double,
+    TST_bool,         // _Bool
+    TST_decimal32,    // _Decimal32
+    TST_decimal64,    // _Decimal64
+    TST_decimal128,   // _Decimal128
+    TST_enum,
+    TST_union,
+    TST_struct,
+    TST_class,        // C++ class type
+    TST_interface,    // C++ (Microsoft-specific) __interface type
+    TST_typename,     // Typedef, C++ class-name or enum name, etc.
+    TST_typeofType,
+    TST_typeofExpr,
+    TST_decltype,     // C++0x decltype
+    TST_underlyingType, // __underlying_type for C++0x
+    TST_auto,         // C++0x auto
+    TST_unknown_anytype, // __unknown_anytype extension
+    TST_atomic,       // C11 _Atomic
+    TST_error         // erroneous type
+  };
+  
+  /// \brief Structure that packs information about the type specifiers that
+  /// were written in a particular type specifier sequence.
+  struct WrittenBuiltinSpecs {
+    /*DeclSpec::TST*/ unsigned Type  : 5;
+    /*DeclSpec::TSS*/ unsigned Sign  : 2;
+    /*DeclSpec::TSW*/ unsigned Width : 2;
+    bool ModeAttr : 1;
+  };  
+
+  /// \brief A C++ access specifier (public, private, protected), plus the
+  /// special value "none" which means different things in different contexts.
+  enum AccessSpecifier {
+    AS_public,
+    AS_protected,
+    AS_private,
+    AS_none
+  };
+
+  /// \brief The categorization of expression values, currently following the
+  /// C++11 scheme.
+  enum ExprValueKind {
+    /// \brief An r-value expression (a pr-value in the C++11 taxonomy)
+    /// produces a temporary value.
+    VK_RValue,
+
+    /// \brief An l-value expression is a reference to an object with
+    /// independent storage.
+    VK_LValue,
+
+    /// \brief An x-value expression is a reference to an object with
+    /// independent storage but which can be "moved", i.e.
+    /// efficiently cannibalized for its resources.
+    VK_XValue
+  };
+
+  /// \brief A further classification of the kind of object referenced by an
+  /// l-value or x-value.
+  enum ExprObjectKind {
+    /// An ordinary object is located at an address in memory.
+    OK_Ordinary,
+
+    /// A bitfield object is a bitfield on a C or C++ record.
+    OK_BitField,
+
+    /// A vector component is an element or range of elements on a vector.
+    OK_VectorComponent,
+
+    /// An Objective-C property is a logical field of an Objective-C
+    /// object which is read and written via Objective-C method calls.
+    OK_ObjCProperty,
+    
+    /// An Objective-C array/dictionary subscripting which reads an
+    /// object or writes at the subscripted array/dictionary element via
+    /// Objective-C method calls.
+    OK_ObjCSubscript
+  };
+
+  // \brief Describes the kind of template specialization that a
+  // particular template specialization declaration represents.
+  enum TemplateSpecializationKind {
+    /// This template specialization was formed from a template-id but
+    /// has not yet been declared, defined, or instantiated.
+    TSK_Undeclared = 0,
+    /// This template specialization was implicitly instantiated from a
+    /// template. (C++ [temp.inst]).
+    TSK_ImplicitInstantiation,
+    /// This template specialization was declared or defined by an
+    /// explicit specialization (C++ [temp.expl.spec]) or partial
+    /// specialization (C++ [temp.class.spec]).
+    TSK_ExplicitSpecialization,
+    /// This template specialization was instantiated from a template
+    /// due to an explicit instantiation declaration request
+    /// (C++0x [temp.explicit]).
+    TSK_ExplicitInstantiationDeclaration,
+    /// This template specialization was instantiated from a template
+    /// due to an explicit instantiation definition request
+    /// (C++ [temp.explicit]).
+    TSK_ExplicitInstantiationDefinition
+  };
+
+  /// \brief Storage classes.
+  enum StorageClass {
+    // These are legal on both functions and variables.
+    SC_None,
+    SC_Extern,
+    SC_Static,
+    SC_PrivateExtern,
+
+    // These are only legal on variables.
+    SC_OpenCLWorkGroupLocal,
+    SC_Auto,
+    SC_Register
+  };
+
+  /// \brief Checks whether the given storage class is legal for functions.
+  inline bool isLegalForFunction(StorageClass SC) {
+    return SC <= SC_PrivateExtern;
+  }
+
+  /// \brief Checks whether the given storage class is legal for variables.
+  inline bool isLegalForVariable(StorageClass SC) {
+    return true;
+  }
+
+  /// \brief In-class initialization styles for non-static data members.
+  enum InClassInitStyle {
+    ICIS_NoInit,   ///< No in-class initializer.
+    ICIS_CopyInit, ///< Copy initialization.
+    ICIS_ListInit  ///< Direct list-initialization.
+  };
+
+  /// \brief CallingConv - Specifies the calling convention that a function uses.
+  enum CallingConv {
+    CC_Default,
+    CC_C,           // __attribute__((cdecl))
+    CC_X86StdCall,  // __attribute__((stdcall))
+    CC_X86FastCall, // __attribute__((fastcall))
+    CC_X86ThisCall, // __attribute__((thiscall))
+    CC_X86Pascal,   // __attribute__((pascal))
+    CC_AAPCS,       // __attribute__((pcs("aapcs")))
+    CC_AAPCS_VFP,   // __attribute__((pcs("aapcs-vfp")))
+    CC_PnaclCall    // __attribute__((pnaclcall))
+  };
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 7bc489b..f02ba64 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -448,12 +448,6 @@
 ALIAS("write_only", __write_only    , KEYOPENCL)
 ALIAS("read_write", __read_write    , KEYOPENCL)
 KEYWORD(__builtin_astype            , KEYOPENCL)
-KEYWORD(image1d_t                   , KEYOPENCL)
-KEYWORD(image1d_array_t             , KEYOPENCL)
-KEYWORD(image1d_buffer_t            , KEYOPENCL)
-KEYWORD(image2d_t                   , KEYOPENCL)
-KEYWORD(image2d_array_t             , KEYOPENCL)
-KEYWORD(image3d_t                   , KEYOPENCL)
 
 // Borland Extensions.
 KEYWORD(__pascal                    , KEYALL)
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index bc8fc64..d261810 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -276,12 +276,6 @@
   static const TST TST_auto = clang::TST_auto;
   static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
   static const TST TST_atomic = clang::TST_atomic;
-  static const TST TST_image1d_t = clang::TST_image1d_t;
-  static const TST TST_image1d_array_t = clang::TST_image1d_array_t;
-  static const TST TST_image1d_buffer_t = clang::TST_image1d_buffer_t;
-  static const TST TST_image2d_t = clang::TST_image2d_t;
-  static const TST TST_image2d_array_t = clang::TST_image2d_array_t;
-  static const TST TST_image3d_t = clang::TST_image3d_t;
   static const TST TST_error = clang::TST_error;
 
   // type-qualifiers
@@ -312,7 +306,7 @@
   /*TSW*/unsigned TypeSpecWidth : 2;
   /*TSC*/unsigned TypeSpecComplex : 2;
   /*TSS*/unsigned TypeSpecSign : 2;
-  /*TST*/unsigned TypeSpecType : 6;
+  /*TST*/unsigned TypeSpecType : 5;
   unsigned TypeAltiVecVector : 1;
   unsigned TypeAltiVecPixel : 1;
   unsigned TypeAltiVecBool : 1;
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 868a175..4273e14 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1,1367 +1,1355 @@
-//===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header defines Bitcode enum values for Clang serialized AST files.
-//
-// The enum values defined in this file should be considered permanent.  If
-// new features are added, they should have values added at the end of the
-// respective lists.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_PCHBITCODES_H
-#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
-
-#include "clang/AST/Type.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Bitcode/BitCodes.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
-  namespace serialization {
-    /// \brief AST file major version number supported by this version of
-    /// Clang.
-    ///
-    /// Whenever the AST file format changes in a way that makes it
-    /// incompatible with previous versions (such that a reader
-    /// designed for the previous version could not support reading
-    /// the new version), this number should be increased.
-    ///
-    /// Version 4 of AST files also requires that the version control branch and
-    /// revision match exactly, since there is no backward compatibility of
-    /// AST files at this time.
-    const unsigned VERSION_MAJOR = 5;
-
-    /// \brief AST file minor version number supported by this version of
-    /// Clang.
-    ///
-    /// Whenever the AST format changes in a way that is still
-    /// compatible with previous versions (such that a reader designed
-    /// for the previous version could still support reading the new
-    /// version by ignoring new kinds of subblocks), this number
-    /// should be increased.
-    const unsigned VERSION_MINOR = 0;
-
-    /// \brief An ID number that refers to an identifier in an AST file.
-    /// 
-    /// The ID numbers of identifiers are consecutive (in order of discovery)
-    /// and start at 1. 0 is reserved for NULL.
-    typedef uint32_t IdentifierID;
-    
-    /// \brief An ID number that refers to a declaration in an AST file.
-    ///
-    /// The ID numbers of declarations are consecutive (in order of
-    /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. 
-    /// At the start of a chain of precompiled headers, declaration ID 1 is 
-    /// used for the translation unit declaration.
-    typedef uint32_t DeclID;
-
-    /// \brief a Decl::Kind/DeclID pair.
-    typedef std::pair<uint32_t, DeclID> KindDeclIDPair;
-
-    // FIXME: Turn these into classes so we can have some type safety when
-    // we go from local ID to global and vice-versa.
-    typedef DeclID LocalDeclID;
-    typedef DeclID GlobalDeclID;
-
-    /// \brief An ID number that refers to a type in an AST file.
-    ///
-    /// The ID of a type is partitioned into two parts: the lower
-    /// three bits are used to store the const/volatile/restrict
-    /// qualifiers (as with QualType) and the upper bits provide a
-    /// type index. The type index values are partitioned into two
-    /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type
-    /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a
-    /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are
-    /// other types that have serialized representations.
-    typedef uint32_t TypeID;
-
-    /// \brief A type index; the type ID with the qualifier bits removed.
-    class TypeIdx {
-      uint32_t Idx;
-    public:
-      TypeIdx() : Idx(0) { }
-      explicit TypeIdx(uint32_t index) : Idx(index) { }
-
-      uint32_t getIndex() const { return Idx; }
-      TypeID asTypeID(unsigned FastQuals) const {
-        if (Idx == uint32_t(-1))
-          return TypeID(-1);
-        
-        return (Idx << Qualifiers::FastWidth) | FastQuals;
-      }
-      static TypeIdx fromTypeID(TypeID ID) {
-        if (ID == TypeID(-1))
-          return TypeIdx(-1);
-        
-        return TypeIdx(ID >> Qualifiers::FastWidth);
-      }
-    };
-
-    /// A structure for putting "fast"-unqualified QualTypes into a
-    /// DenseMap.  This uses the standard pointer hash function.
-    struct UnsafeQualTypeDenseMapInfo {
-      static inline bool isEqual(QualType A, QualType B) { return A == B; }
-      static inline QualType getEmptyKey() {
-        return QualType::getFromOpaquePtr((void*) 1);
-      }
-      static inline QualType getTombstoneKey() {
-        return QualType::getFromOpaquePtr((void*) 2);
-      }
-      static inline unsigned getHashValue(QualType T) {
-        assert(!T.getLocalFastQualifiers() && 
-               "hash invalid for types with fast quals");
-        uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
-        return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
-      }
-    };
-
-    /// \brief An ID number that refers to an identifier in an AST file.
-    typedef uint32_t IdentID;
-
-    /// \brief The number of predefined identifier IDs.
-    const unsigned int NUM_PREDEF_IDENT_IDS = 1;
-
-    /// \brief An ID number that refers to a macro in an AST file.
-    typedef uint32_t MacroID;
-    
-    /// \brief The number of predefined macro IDs.
-    const unsigned int NUM_PREDEF_MACRO_IDS = 1;
-
-    /// \brief An ID number that refers to an ObjC selector in an AST file.
-    typedef uint32_t SelectorID;
-
-    /// \brief The number of predefined selector IDs.
-    const unsigned int NUM_PREDEF_SELECTOR_IDS = 1;
-    
-    /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an 
-    /// AST file.
-    typedef uint32_t CXXBaseSpecifiersID;
-    
-    /// \brief An ID number that refers to an entity in the detailed
-    /// preprocessing record.
-    typedef uint32_t PreprocessedEntityID;
-
-    /// \brief An ID number that refers to a submodule in a module file.
-    typedef uint32_t SubmoduleID;
-    
-    /// \brief The number of predefined submodule IDs.
-    const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
-
-    /// \brief Source range/offset of a preprocessed entity.
-    struct PPEntityOffset {
-      /// \brief Raw source location of beginning of range.
-      unsigned Begin;
-      /// \brief Raw source location of end of range.
-      unsigned End;
-      /// \brief Offset in the AST file.
-      uint32_t BitOffset;
-
-      PPEntityOffset(SourceRange R, uint32_t BitOffset)
-        : Begin(R.getBegin().getRawEncoding()),
-          End(R.getEnd().getRawEncoding()),
-          BitOffset(BitOffset) { }
-    };
-
-    /// \brief Source range/offset of a preprocessed entity.
-    struct DeclOffset {
-      /// \brief Raw source location.
-      unsigned Loc;
-      /// \brief Offset in the AST file.
-      uint32_t BitOffset;
-
-      DeclOffset() : Loc(0), BitOffset(0) { }
-      DeclOffset(SourceLocation Loc, uint32_t BitOffset)
-        : Loc(Loc.getRawEncoding()),
-          BitOffset(BitOffset) { }
-      void setLocation(SourceLocation L) {
-        Loc = L.getRawEncoding();
-      }
-    };
-
-    /// \brief The number of predefined preprocessed entity IDs.
-    const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
-
-    /// \brief Describes the various kinds of blocks that occur within
-    /// an AST file.
-    enum BlockIDs {
-      /// \brief The AST block, which acts as a container around the
-      /// full AST block.
-      AST_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
-
-      /// \brief The block containing information about the source
-      /// manager.
-      SOURCE_MANAGER_BLOCK_ID,
-
-      /// \brief The block containing information about the
-      /// preprocessor.
-      PREPROCESSOR_BLOCK_ID,
-
-      /// \brief The block containing the definitions of all of the
-      /// types and decls used within the AST file.
-      DECLTYPES_BLOCK_ID,
-
-      /// \brief The block containing DECL_UPDATES records.
-      DECL_UPDATES_BLOCK_ID,
-      
-      /// \brief The block containing the detailed preprocessing record.
-      PREPROCESSOR_DETAIL_BLOCK_ID,
-      
-      /// \brief The block containing the submodule structure.
-      SUBMODULE_BLOCK_ID,
-
-      /// \brief The block containing comments.
-      COMMENTS_BLOCK_ID,
-
-      /// \brief The control block, which contains all of the
-      /// information that needs to be validated prior to committing
-      /// to loading the AST file.
-      CONTROL_BLOCK_ID,
-
-      /// \brief The block of input files, which were used as inputs
-      /// to create this AST file.
-      ///
-      /// This block is part of the control block.
-      INPUT_FILES_BLOCK_ID
-    };
-
-    /// \brief Record types that occur within the control block.
-    enum ControlRecordTypes {
-      /// \brief AST file metadata, including the AST file version number
-      /// and information about the compiler used to build this AST file.
-      METADATA = 1,
-
-      /// \brief Record code for the list of other AST files imported by
-      /// this AST file.
-      IMPORTS = 2,
-
-      /// \brief Record code for the language options table.
-      ///
-      /// The record with this code contains the contents of the
-      /// LangOptions structure. We serialize the entire contents of
-      /// the structure, and let the reader decide which options are
-      /// actually important to check.
-      LANGUAGE_OPTIONS = 3,
-
-      /// \brief Record code for the target options table.
-      TARGET_OPTIONS = 4,
-
-      /// \brief Record code for the original file that was used to
-      /// generate the AST file, including both its file ID and its
-      /// name.
-      ORIGINAL_FILE = 5,
-      
-      /// \brief The directory that the PCH was originally created in.
-      ORIGINAL_PCH_DIR = 6,
-
-      /// \brief Record code for file ID of the file or buffer that was used to
-      /// generate the AST file.
-      ORIGINAL_FILE_ID = 7,
-
-      /// \brief Offsets into the input-files block where input files
-      /// reside.
-      INPUT_FILE_OFFSETS = 8,
-
-      /// \brief Record code for the diagnostic options table.
-      DIAGNOSTIC_OPTIONS = 9,
-
-      /// \brief Record code for the filesystem options table.
-      FILE_SYSTEM_OPTIONS = 10,
-
-      /// \brief Record code for the headers search options table.
-      HEADER_SEARCH_OPTIONS = 11,
-
-      /// \brief Record code for the preprocessor options table.
-      PREPROCESSOR_OPTIONS = 12
-    };
-
-    /// \brief Record types that occur within the input-files block
-    /// inside the control block.
-    enum InputFileRecordTypes {
-      /// \brief An input file.
-      INPUT_FILE = 1
-    };
-
-    /// \brief Record types that occur within the AST block itself.
-    enum ASTRecordTypes {
-      /// \brief Record code for the offsets of each type.
-      ///
-      /// The TYPE_OFFSET constant describes the record that occurs
-      /// within the AST block. The record itself is an array of offsets that
-      /// point into the declarations and types block (identified by 
-      /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
-      /// of a type. For a given type ID @c T, the lower three bits of
-      /// @c T are its qualifiers (const, volatile, restrict), as in
-      /// the QualType class. The upper bits, after being shifted and
-      /// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
-      /// TYPE_OFFSET block to determine the offset of that type's
-      /// corresponding record within the DECLTYPES_BLOCK_ID block.
-      TYPE_OFFSET = 1,
-
-      /// \brief Record code for the offsets of each decl.
-      ///
-      /// The DECL_OFFSET constant describes the record that occurs
-      /// within the block identified by DECL_OFFSETS_BLOCK_ID within
-      /// the AST block. The record itself is an array of offsets that
-      /// point into the declarations and types block (identified by
-      /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
-      /// record, after subtracting one to account for the use of
-      /// declaration ID 0 for a NULL declaration pointer. Index 0 is
-      /// reserved for the translation unit declaration.
-      DECL_OFFSET = 2,
-
-      /// \brief Record code for the table of offsets of each
-      /// identifier ID.
-      ///
-      /// The offset table contains offsets into the blob stored in
-      /// the IDENTIFIER_TABLE record. Each offset points to the
-      /// NULL-terminated string that corresponds to that identifier.
-      IDENTIFIER_OFFSET = 3,
-
-      /// \brief This is so that older clang versions, before the introduction
-      /// of the control block, can read and reject the newer PCH format.
-      /// *DON"T CHANGE THIS NUMBER*.
-      METADATA_OLD_FORMAT = 4,
-
-      /// \brief Record code for the identifier table.
-      ///
-      /// The identifier table is a simple blob that contains
-      /// NULL-terminated strings for all of the identifiers
-      /// referenced by the AST file. The IDENTIFIER_OFFSET table
-      /// contains the mapping from identifier IDs to the characters
-      /// in this blob. Note that the starting offsets of all of the
-      /// identifiers are odd, so that, when the identifier offset
-      /// table is loaded in, we can use the low bit to distinguish
-      /// between offsets (for unresolved identifier IDs) and
-      /// IdentifierInfo pointers (for already-resolved identifier
-      /// IDs).
-      IDENTIFIER_TABLE = 5,
-
-      /// \brief Record code for the array of external definitions.
-      ///
-      /// The AST file contains a list of all of the unnamed external
-      /// definitions present within the parsed headers, stored as an
-      /// array of declaration IDs. These external definitions will be
-      /// reported to the AST consumer after the AST file has been
-      /// read, since their presence can affect the semantics of the
-      /// program (e.g., for code generation).
-      EXTERNAL_DEFINITIONS = 6,
-
-      /// \brief Record code for the set of non-builtin, special
-      /// types.
-      ///
-      /// This record contains the type IDs for the various type nodes
-      /// that are constructed during semantic analysis (e.g.,
-      /// __builtin_va_list). The SPECIAL_TYPE_* constants provide
-      /// offsets into this record.
-      SPECIAL_TYPES = 7,
-
-      /// \brief Record code for the extra statistics we gather while
-      /// generating an AST file.
-      STATISTICS = 8,
-
-      /// \brief Record code for the array of tentative definitions.
-      TENTATIVE_DEFINITIONS = 9,
-
-      /// \brief Record code for the array of locally-scoped external
-      /// declarations.
-      LOCALLY_SCOPED_EXTERNAL_DECLS = 10,
-
-      /// \brief Record code for the table of offsets into the
-      /// Objective-C method pool.
-      SELECTOR_OFFSETS = 11,
-
-      /// \brief Record code for the Objective-C method pool,
-      METHOD_POOL = 12,
-
-      /// \brief The value of the next __COUNTER__ to dispense.
-      /// [PP_COUNTER_VALUE, Val]
-      PP_COUNTER_VALUE = 13,
-
-      /// \brief Record code for the table of offsets into the block
-      /// of source-location information.
-      SOURCE_LOCATION_OFFSETS = 14,
-
-      /// \brief Record code for the set of source location entries
-      /// that need to be preloaded by the AST reader.
-      ///
-      /// This set contains the source location entry for the
-      /// predefines buffer and for any file entries that need to be
-      /// preloaded.
-      SOURCE_LOCATION_PRELOADS = 15,
-
-      /// \brief Record code for the set of ext_vector type names.
-      EXT_VECTOR_DECLS = 16,
-      
-      /// \brief Record code for the array of unused file scoped decls.
-      UNUSED_FILESCOPED_DECLS = 17,
-      
-      /// \brief Record code for the table of offsets to entries in the
-      /// preprocessing record.
-      PPD_ENTITIES_OFFSETS = 18,
-
-      /// \brief Record code for the array of VTable uses.
-      VTABLE_USES = 19,
-
-      /// \brief Record code for the array of dynamic classes.
-      DYNAMIC_CLASSES = 20,
-
-      /// \brief Record code for referenced selector pool.
-      REFERENCED_SELECTOR_POOL = 21,
-
-      /// \brief Record code for an update to the TU's lexically contained
-      /// declarations.
-      TU_UPDATE_LEXICAL = 22,
-      
-      /// \brief Record code for the array describing the locations (in the
-      /// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by
-      /// the first known ID.
-      LOCAL_REDECLARATIONS_MAP = 23,
-
-      /// \brief Record code for declarations that Sema keeps references of.
-      SEMA_DECL_REFS = 24,
-
-      /// \brief Record code for weak undeclared identifiers.
-      WEAK_UNDECLARED_IDENTIFIERS = 25,
-
-      /// \brief Record code for pending implicit instantiations.
-      PENDING_IMPLICIT_INSTANTIATIONS = 26,
-
-      /// \brief Record code for a decl replacement block.
-      ///
-      /// If a declaration is modified after having been deserialized, and then
-      /// written to a dependent AST file, its ID and offset must be added to
-      /// the replacement block.
-      DECL_REPLACEMENTS = 27,
-
-      /// \brief Record code for an update to a decl context's lookup table.
-      ///
-      /// In practice, this should only be used for the TU and namespaces.
-      UPDATE_VISIBLE = 28,
-
-      /// \brief Record for offsets of DECL_UPDATES records for declarations
-      /// that were modified after being deserialized and need updates.
-      DECL_UPDATE_OFFSETS = 29,
-
-      /// \brief Record of updates for a declaration that was modified after
-      /// being deserialized.
-      DECL_UPDATES = 30,
-      
-      /// \brief Record code for the table of offsets to CXXBaseSpecifier
-      /// sets.
-      CXX_BASE_SPECIFIER_OFFSETS = 31,
-
-      /// \brief Record code for \#pragma diagnostic mappings.
-      DIAG_PRAGMA_MAPPINGS = 32,
-
-      /// \brief Record code for special CUDA declarations.
-      CUDA_SPECIAL_DECL_REFS = 33,
-      
-      /// \brief Record code for header search information.
-      HEADER_SEARCH_TABLE = 34,
-
-      /// \brief Record code for floating point \#pragma options.
-      FP_PRAGMA_OPTIONS = 35,
-
-      /// \brief Record code for enabled OpenCL extensions.
-      OPENCL_EXTENSIONS = 36,
-
-      /// \brief The list of delegating constructor declarations.
-      DELEGATING_CTORS = 37,
-
-      /// \brief Record code for the set of known namespaces, which are used
-      /// for typo correction.
-      KNOWN_NAMESPACES = 38,
-
-      /// \brief Record code for the remapping information used to relate
-      /// loaded modules to the various offsets and IDs(e.g., source location 
-      /// offests, declaration and type IDs) that are used in that module to
-      /// refer to other modules.
-      MODULE_OFFSET_MAP = 39,
-
-      /// \brief Record code for the source manager line table information,
-      /// which stores information about \#line directives.
-      SOURCE_MANAGER_LINE_TABLE = 40,
-
-      /// \brief Record code for map of Objective-C class definition IDs to the 
-      /// ObjC categories in a module that are attached to that class.
-      OBJC_CATEGORIES_MAP = 41,
-
-      /// \brief Record code for a file sorted array of DeclIDs in a module.
-      FILE_SORTED_DECLS = 42,
-      
-      /// \brief Record code for an array of all of the (sub)modules that were
-      /// imported by the AST file.
-      IMPORTED_MODULES = 43,
-      
-      /// \brief Record code for the set of merged declarations in an AST file.
-      MERGED_DECLARATIONS = 44,
-      
-      /// \brief Record code for the array of redeclaration chains.
-      ///
-      /// This array can only be interpreted properly using the local 
-      /// redeclarations map.
-      LOCAL_REDECLARATIONS = 45,
-      
-      /// \brief Record code for the array of Objective-C categories (including
-      /// extensions).
-      ///
-      /// This array can only be interpreted properly using the Objective-C
-      /// categories map.
-      OBJC_CATEGORIES = 46,
-
-      /// \brief Record code for the table of offsets of each macro ID.
-      ///
-      /// The offset table contains offsets into the blob stored in
-      /// the preprocessor block. Each offset points to the corresponding
-      /// macro definition.
-      MACRO_OFFSET = 47,
-
-      /// \brief Record of updates for a macro that was modified after
-      /// being deserialized.
-      MACRO_UPDATES = 48
-    };
-
-    /// \brief Record types used within a source manager block.
-    enum SourceManagerRecordTypes {
-      /// \brief Describes a source location entry (SLocEntry) for a
-      /// file.
-      SM_SLOC_FILE_ENTRY = 1,
-      /// \brief Describes a source location entry (SLocEntry) for a
-      /// buffer.
-      SM_SLOC_BUFFER_ENTRY = 2,
-      /// \brief Describes a blob that contains the data for a buffer
-      /// entry. This kind of record always directly follows a
-      /// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an
-      /// overridden buffer.
-      SM_SLOC_BUFFER_BLOB = 3,
-      /// \brief Describes a source location entry (SLocEntry) for a
-      /// macro expansion.
-      SM_SLOC_EXPANSION_ENTRY = 4
-    };
-
-    /// \brief Record types used within a preprocessor block.
-    enum PreprocessorRecordTypes {
-      // The macros in the PP section are a PP_MACRO_* instance followed by a
-      // list of PP_TOKEN instances for each token in the definition.
-
-      /// \brief An object-like macro definition.
-      /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed]
-      PP_MACRO_OBJECT_LIKE = 1,
-
-      /// \brief A function-like macro definition.
-      /// [PP_MACRO_FUNCTION_LIKE, \<ObjectLikeStuff>, IsC99Varargs,
-      /// IsGNUVarars, NumArgs, ArgIdentInfoID* ]
-      PP_MACRO_FUNCTION_LIKE = 2,
-
-      /// \brief Describes one token.
-      /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
-      PP_TOKEN = 3
-    };
-
-    /// \brief Record types used within a preprocessor detail block.
-    enum PreprocessorDetailRecordTypes {
-      /// \brief Describes a macro expansion within the preprocessing record.
-      PPD_MACRO_EXPANSION = 0,
-      
-      /// \brief Describes a macro definition within the preprocessing record.
-      PPD_MACRO_DEFINITION = 1,
-      
-      /// \brief Describes an inclusion directive within the preprocessing
-      /// record.
-      PPD_INCLUSION_DIRECTIVE = 2
-    };
-    
-    /// \brief Record types used within a submodule description block.
-    enum SubmoduleRecordTypes {
-      /// \brief Metadata for submodules as a whole.
-      SUBMODULE_METADATA = 0,
-      /// \brief Defines the major attributes of a submodule, including its
-      /// name and parent.
-      SUBMODULE_DEFINITION = 1,
-      /// \brief Specifies the umbrella header used to create this module,
-      /// if any.
-      SUBMODULE_UMBRELLA_HEADER = 2,
-      /// \brief Specifies a header that falls into this (sub)module.
-      SUBMODULE_HEADER = 3,
-      /// \brief Specifies a top-level header that falls into this (sub)module.
-      SUBMODULE_TOPHEADER = 4,
-      /// \brief Specifies an umbrella directory.
-      SUBMODULE_UMBRELLA_DIR = 5,
-      /// \brief Specifies the submodules that are imported by this 
-      /// submodule.
-      SUBMODULE_IMPORTS = 6,
-      /// \brief Specifies the submodules that are re-exported from this 
-      /// submodule.
-      SUBMODULE_EXPORTS = 7,
-      /// \brief Specifies a required feature.
-      SUBMODULE_REQUIRES = 8,
-      /// \brief Specifies a header that has been explicitly excluded
-      /// from this submodule.
-      SUBMODULE_EXCLUDED_HEADER = 9
-    };
-
-    /// \brief Record types used within a comments block.
-    enum CommentRecordTypes {
-      COMMENTS_RAW_COMMENT = 0
-    };
-
-    /// \defgroup ASTAST AST file AST constants
-    ///
-    /// The constants in this group describe various components of the
-    /// abstract syntax tree within an AST file.
-    ///
-    /// @{
-
-    /// \brief Predefined type IDs.
-    ///
-    /// These type IDs correspond to predefined types in the AST
-    /// context, such as built-in types (int) and special place-holder
-    /// types (the \<overload> and \<dependent> type markers). Such
-    /// types are never actually serialized, since they will be built
-    /// by the AST context when it is created.
-    enum PredefinedTypeIDs {
-      /// \brief The NULL type.
-      PREDEF_TYPE_NULL_ID       = 0,
-      /// \brief The void type.
-      PREDEF_TYPE_VOID_ID       = 1,
-      /// \brief The 'bool' or '_Bool' type.
-      PREDEF_TYPE_BOOL_ID       = 2,
-      /// \brief The 'char' type, when it is unsigned.
-      PREDEF_TYPE_CHAR_U_ID     = 3,
-      /// \brief The 'unsigned char' type.
-      PREDEF_TYPE_UCHAR_ID      = 4,
-      /// \brief The 'unsigned short' type.
-      PREDEF_TYPE_USHORT_ID     = 5,
-      /// \brief The 'unsigned int' type.
-      PREDEF_TYPE_UINT_ID       = 6,
-      /// \brief The 'unsigned long' type.
-      PREDEF_TYPE_ULONG_ID      = 7,
-      /// \brief The 'unsigned long long' type.
-      PREDEF_TYPE_ULONGLONG_ID  = 8,
-      /// \brief The 'char' type, when it is signed.
-      PREDEF_TYPE_CHAR_S_ID     = 9,
-      /// \brief The 'signed char' type.
-      PREDEF_TYPE_SCHAR_ID      = 10,
-      /// \brief The C++ 'wchar_t' type.
-      PREDEF_TYPE_WCHAR_ID      = 11,
-      /// \brief The (signed) 'short' type.
-      PREDEF_TYPE_SHORT_ID      = 12,
-      /// \brief The (signed) 'int' type.
-      PREDEF_TYPE_INT_ID        = 13,
-      /// \brief The (signed) 'long' type.
-      PREDEF_TYPE_LONG_ID       = 14,
-      /// \brief The (signed) 'long long' type.
-      PREDEF_TYPE_LONGLONG_ID   = 15,
-      /// \brief The 'float' type.
-      PREDEF_TYPE_FLOAT_ID      = 16,
-      /// \brief The 'double' type.
-      PREDEF_TYPE_DOUBLE_ID     = 17,
-      /// \brief The 'long double' type.
-      PREDEF_TYPE_LONGDOUBLE_ID = 18,
-      /// \brief The placeholder type for overloaded function sets.
-      PREDEF_TYPE_OVERLOAD_ID   = 19,
-      /// \brief The placeholder type for dependent types.
-      PREDEF_TYPE_DEPENDENT_ID  = 20,
-      /// \brief The '__uint128_t' type.
-      PREDEF_TYPE_UINT128_ID    = 21,
-      /// \brief The '__int128_t' type.
-      PREDEF_TYPE_INT128_ID     = 22,
-      /// \brief The type of 'nullptr'.
-      PREDEF_TYPE_NULLPTR_ID    = 23,
-      /// \brief The C++ 'char16_t' type.
-      PREDEF_TYPE_CHAR16_ID     = 24,
-      /// \brief The C++ 'char32_t' type.
-      PREDEF_TYPE_CHAR32_ID     = 25,
-      /// \brief The ObjC 'id' type.
-      PREDEF_TYPE_OBJC_ID       = 26,
-      /// \brief The ObjC 'Class' type.
-      PREDEF_TYPE_OBJC_CLASS    = 27,
-      /// \brief The ObjC 'SEL' type.
-      PREDEF_TYPE_OBJC_SEL      = 28,
-      /// \brief The 'unknown any' placeholder type.
-      PREDEF_TYPE_UNKNOWN_ANY   = 29,
-      /// \brief The placeholder type for bound member functions.
-      PREDEF_TYPE_BOUND_MEMBER  = 30,
-      /// \brief The "auto" deduction type.
-      PREDEF_TYPE_AUTO_DEDUCT   = 31,
-      /// \brief The "auto &&" deduction type.
-      PREDEF_TYPE_AUTO_RREF_DEDUCT = 32,
-      /// \brief The OpenCL 'half' / ARM NEON __fp16 type.
-      PREDEF_TYPE_HALF_ID       = 33,
-      /// \brief ARC's unbridged-cast placeholder type.
-      PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
-      /// \brief The pseudo-object placeholder type.
-      PREDEF_TYPE_PSEUDO_OBJECT = 35,
-      /// \brief The __va_list_tag placeholder type.
-      PREDEF_TYPE_VA_LIST_TAG = 36,
-      /// \brief The placeholder type for builtin functions.
-      PREDEF_TYPE_BUILTIN_FN = 37,
-      /// \brief OpenCL 1d image type.
-      PREDEF_TYPE_IMAGE1D_ID    = 38,
-      /// \brief OpenCL 1d image array type.
-      PREDEF_TYPE_IMAGE1D_ARR_ID = 39,
-      /// \brief OpenCL 1d image buffer type.
-      PREDEF_TYPE_IMAGE1D_BUFF_ID = 40,
-      /// \brief OpenCL 2d image type.
-      PREDEF_TYPE_IMAGE2D_ID    = 41,
-      /// \brief OpenCL 2d image array type.
-      PREDEF_TYPE_IMAGE2D_ARR_ID = 42,
-      /// \brief OpenCL 3d image type.
-      PREDEF_TYPE_IMAGE3D_ID    = 43
-    };
-
-    /// \brief The number of predefined type IDs that are reserved for
-    /// the PREDEF_TYPE_* constants.
-    ///
-    /// Type IDs for non-predefined types will start at
-    /// NUM_PREDEF_TYPE_IDs.
-    const unsigned NUM_PREDEF_TYPE_IDS = 100;
-
-    /// \brief The number of allowed abbreviations in bits
-    const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4;
-
-    /// \brief Record codes for each kind of type.
-    ///
-    /// These constants describe the type records that can occur within a
-    /// block identified by DECLTYPES_BLOCK_ID in the AST file. Each
-    /// constant describes a record for a specific type class in the
-    /// AST.
-    enum TypeCode {
-      /// \brief An ExtQualType record.
-      TYPE_EXT_QUAL                 = 1,
-      /// \brief A ComplexType record.
-      TYPE_COMPLEX                  = 3,
-      /// \brief A PointerType record.
-      TYPE_POINTER                  = 4,
-      /// \brief A BlockPointerType record.
-      TYPE_BLOCK_POINTER            = 5,
-      /// \brief An LValueReferenceType record.
-      TYPE_LVALUE_REFERENCE         = 6,
-      /// \brief An RValueReferenceType record.
-      TYPE_RVALUE_REFERENCE         = 7,
-      /// \brief A MemberPointerType record.
-      TYPE_MEMBER_POINTER           = 8,
-      /// \brief A ConstantArrayType record.
-      TYPE_CONSTANT_ARRAY           = 9,
-      /// \brief An IncompleteArrayType record.
-      TYPE_INCOMPLETE_ARRAY         = 10,
-      /// \brief A VariableArrayType record.
-      TYPE_VARIABLE_ARRAY           = 11,
-      /// \brief A VectorType record.
-      TYPE_VECTOR                   = 12,
-      /// \brief An ExtVectorType record.
-      TYPE_EXT_VECTOR               = 13,
-      /// \brief A FunctionNoProtoType record.
-      TYPE_FUNCTION_NO_PROTO        = 14,
-      /// \brief A FunctionProtoType record.
-      TYPE_FUNCTION_PROTO           = 15,
-      /// \brief A TypedefType record.
-      TYPE_TYPEDEF                  = 16,
-      /// \brief A TypeOfExprType record.
-      TYPE_TYPEOF_EXPR              = 17,
-      /// \brief A TypeOfType record.
-      TYPE_TYPEOF                   = 18,
-      /// \brief A RecordType record.
-      TYPE_RECORD                   = 19,
-      /// \brief An EnumType record.
-      TYPE_ENUM                     = 20,
-      /// \brief An ObjCInterfaceType record.
-      TYPE_OBJC_INTERFACE           = 21,
-      /// \brief An ObjCObjectPointerType record.
-      TYPE_OBJC_OBJECT_POINTER      = 22,
-      /// \brief a DecltypeType record.
-      TYPE_DECLTYPE                 = 23,
-      /// \brief An ElaboratedType record.
-      TYPE_ELABORATED               = 24,
-      /// \brief A SubstTemplateTypeParmType record.
-      TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
-      /// \brief An UnresolvedUsingType record.
-      TYPE_UNRESOLVED_USING         = 26,
-      /// \brief An InjectedClassNameType record.
-      TYPE_INJECTED_CLASS_NAME      = 27,
-      /// \brief An ObjCObjectType record.
-      TYPE_OBJC_OBJECT              = 28,
-      /// \brief An TemplateTypeParmType record.
-      TYPE_TEMPLATE_TYPE_PARM       = 29,
-      /// \brief An TemplateSpecializationType record.
-      TYPE_TEMPLATE_SPECIALIZATION  = 30,
-      /// \brief A DependentNameType record.
-      TYPE_DEPENDENT_NAME           = 31,
-      /// \brief A DependentTemplateSpecializationType record.
-      TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
-      /// \brief A DependentSizedArrayType record.
-      TYPE_DEPENDENT_SIZED_ARRAY    = 33,
-      /// \brief A ParenType record.
-      TYPE_PAREN                    = 34,
-      /// \brief A PackExpansionType record.
-      TYPE_PACK_EXPANSION           = 35,
-      /// \brief An AttributedType record.
-      TYPE_ATTRIBUTED               = 36,
-      /// \brief A SubstTemplateTypeParmPackType record.
-      TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
-      /// \brief A AutoType record.
-      TYPE_AUTO                  = 38,
-      /// \brief A UnaryTransformType record.
-      TYPE_UNARY_TRANSFORM       = 39,
-      /// \brief An AtomicType record.
-      TYPE_ATOMIC                = 40
-    };
-
-    /// \brief The type IDs for special types constructed by semantic
-    /// analysis.
-    ///
-    /// The constants in this enumeration are indices into the
-    /// SPECIAL_TYPES record.
-    enum SpecialTypeIDs {
-      /// \brief CFConstantString type
-      SPECIAL_TYPE_CF_CONSTANT_STRING          = 0,
-      /// \brief C FILE typedef type
-      SPECIAL_TYPE_FILE                        = 1,
-      /// \brief C jmp_buf typedef type
-      SPECIAL_TYPE_JMP_BUF                     = 2,
-      /// \brief C sigjmp_buf typedef type
-      SPECIAL_TYPE_SIGJMP_BUF                  = 3,
-      /// \brief Objective-C "id" redefinition type
-      SPECIAL_TYPE_OBJC_ID_REDEFINITION        = 4,
-      /// \brief Objective-C "Class" redefinition type
-      SPECIAL_TYPE_OBJC_CLASS_REDEFINITION     = 5,
-      /// \brief Objective-C "SEL" redefinition type
-      SPECIAL_TYPE_OBJC_SEL_REDEFINITION       = 6,
-      /// \brief C ucontext_t typedef type
-      SPECIAL_TYPE_UCONTEXT_T                  = 7
-    };
-    
-    /// \brief The number of special type IDs.
-    const unsigned NumSpecialTypeIDs = 8;
-
-    /// \brief Predefined declaration IDs.
-    ///
-    /// These declaration IDs correspond to predefined declarations in the AST
-    /// context, such as the NULL declaration ID. Such declarations are never
-    /// actually serialized, since they will be built by the AST context when 
-    /// it is created.
-    enum PredefinedDeclIDs {
-      /// \brief The NULL declaration.
-      PREDEF_DECL_NULL_ID       = 0,
-      
-      /// \brief The translation unit.
-      PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
-      
-      /// \brief The Objective-C 'id' type.
-      PREDEF_DECL_OBJC_ID_ID = 2,
-      
-      /// \brief The Objective-C 'SEL' type.
-      PREDEF_DECL_OBJC_SEL_ID = 3,
-      
-      /// \brief The Objective-C 'Class' type.
-      PREDEF_DECL_OBJC_CLASS_ID = 4,
-            
-      /// \brief The Objective-C 'Protocol' type.
-      PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
-      
-      /// \brief The signed 128-bit integer type.
-      PREDEF_DECL_INT_128_ID = 6,
-
-      /// \brief The unsigned 128-bit integer type.
-      PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
-      
-      /// \brief The internal 'instancetype' typedef.
-      PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
-
-      /// \brief The internal '__builtin_va_list' typedef.
-      PREDEF_DECL_BUILTIN_VA_LIST_ID = 9
-    };
-
-    /// \brief The number of declaration IDs that are predefined.
-    ///
-    /// For more information about predefined declarations, see the
-    /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
-    const unsigned int NUM_PREDEF_DECL_IDS = 10;
-    
-    /// \brief Record codes for each kind of declaration.
-    ///
-    /// These constants describe the declaration records that can occur within
-    /// a declarations block (identified by DECLS_BLOCK_ID). Each
-    /// constant describes a record for a specific declaration class
-    /// in the AST.
-    enum DeclCode {
-      /// \brief A TypedefDecl record.
-      DECL_TYPEDEF = 51,
-      /// \brief A TypeAliasDecl record.
-      DECL_TYPEALIAS,
-      /// \brief An EnumDecl record.
-      DECL_ENUM,
-      /// \brief A RecordDecl record.
-      DECL_RECORD,
-      /// \brief An EnumConstantDecl record.
-      DECL_ENUM_CONSTANT,
-      /// \brief A FunctionDecl record.
-      DECL_FUNCTION,
-      /// \brief A ObjCMethodDecl record.
-      DECL_OBJC_METHOD,
-      /// \brief A ObjCInterfaceDecl record.
-      DECL_OBJC_INTERFACE,
-      /// \brief A ObjCProtocolDecl record.
-      DECL_OBJC_PROTOCOL,
-      /// \brief A ObjCIvarDecl record.
-      DECL_OBJC_IVAR,
-      /// \brief A ObjCAtDefsFieldDecl record.
-      DECL_OBJC_AT_DEFS_FIELD,
-      /// \brief A ObjCCategoryDecl record.
-      DECL_OBJC_CATEGORY,
-      /// \brief A ObjCCategoryImplDecl record.
-      DECL_OBJC_CATEGORY_IMPL,
-      /// \brief A ObjCImplementationDecl record.
-      DECL_OBJC_IMPLEMENTATION,
-      /// \brief A ObjCCompatibleAliasDecl record.
-      DECL_OBJC_COMPATIBLE_ALIAS,
-      /// \brief A ObjCPropertyDecl record.
-      DECL_OBJC_PROPERTY,
-      /// \brief A ObjCPropertyImplDecl record.
-      DECL_OBJC_PROPERTY_IMPL,
-      /// \brief A FieldDecl record.
-      DECL_FIELD,
-      /// \brief A VarDecl record.
-      DECL_VAR,
-      /// \brief An ImplicitParamDecl record.
-      DECL_IMPLICIT_PARAM,
-      /// \brief A ParmVarDecl record.
-      DECL_PARM_VAR,
-      /// \brief A FileScopeAsmDecl record.
-      DECL_FILE_SCOPE_ASM,
-      /// \brief A BlockDecl record.
-      DECL_BLOCK,
-      /// \brief A record that stores the set of declarations that are
-      /// lexically stored within a given DeclContext.
-      ///
-      /// The record itself is a blob that is an array of declaration IDs,
-      /// in the order in which those declarations were added to the
-      /// declaration context. This data is used when iterating over
-      /// the contents of a DeclContext, e.g., via
-      /// DeclContext::decls_begin() and DeclContext::decls_end().
-      DECL_CONTEXT_LEXICAL,
-      /// \brief A record that stores the set of declarations that are
-      /// visible from a given DeclContext.
-      ///
-      /// The record itself stores a set of mappings, each of which
-      /// associates a declaration name with one or more declaration
-      /// IDs. This data is used when performing qualified name lookup
-      /// into a DeclContext via DeclContext::lookup.
-      DECL_CONTEXT_VISIBLE,
-      /// \brief A LabelDecl record.
-      DECL_LABEL,
-      /// \brief A NamespaceDecl record.
-      DECL_NAMESPACE,
-      /// \brief A NamespaceAliasDecl record.
-      DECL_NAMESPACE_ALIAS,
-      /// \brief A UsingDecl record.
-      DECL_USING,
-      /// \brief A UsingShadowDecl record.
-      DECL_USING_SHADOW,
-      /// \brief A UsingDirecitveDecl record.
-      DECL_USING_DIRECTIVE,
-      /// \brief An UnresolvedUsingValueDecl record.
-      DECL_UNRESOLVED_USING_VALUE,
-      /// \brief An UnresolvedUsingTypenameDecl record.
-      DECL_UNRESOLVED_USING_TYPENAME,
-      /// \brief A LinkageSpecDecl record.
-      DECL_LINKAGE_SPEC,
-      /// \brief A CXXRecordDecl record.
-      DECL_CXX_RECORD,
-      /// \brief A CXXMethodDecl record.
-      DECL_CXX_METHOD,
-      /// \brief A CXXConstructorDecl record.
-      DECL_CXX_CONSTRUCTOR,
-      /// \brief A CXXDestructorDecl record.
-      DECL_CXX_DESTRUCTOR,
-      /// \brief A CXXConversionDecl record.
-      DECL_CXX_CONVERSION,
-      /// \brief An AccessSpecDecl record.
-      DECL_ACCESS_SPEC,
-
-      /// \brief A FriendDecl record.
-      DECL_FRIEND,
-      /// \brief A FriendTemplateDecl record.
-      DECL_FRIEND_TEMPLATE,
-      /// \brief A ClassTemplateDecl record.
-      DECL_CLASS_TEMPLATE,
-      /// \brief A ClassTemplateSpecializationDecl record.
-      DECL_CLASS_TEMPLATE_SPECIALIZATION,
-      /// \brief A ClassTemplatePartialSpecializationDecl record.
-      DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
-      /// \brief A FunctionTemplateDecl record.
-      DECL_FUNCTION_TEMPLATE,
-      /// \brief A TemplateTypeParmDecl record.
-      DECL_TEMPLATE_TYPE_PARM,
-      /// \brief A NonTypeTemplateParmDecl record.
-      DECL_NON_TYPE_TEMPLATE_PARM,
-      /// \brief A TemplateTemplateParmDecl record.
-      DECL_TEMPLATE_TEMPLATE_PARM,
-      /// \brief A TypeAliasTemplateDecl record.
-      DECL_TYPE_ALIAS_TEMPLATE,
-      /// \brief A StaticAssertDecl record.
-      DECL_STATIC_ASSERT,
-      /// \brief A record containing CXXBaseSpecifiers.
-      DECL_CXX_BASE_SPECIFIERS,
-      /// \brief A IndirectFieldDecl record.
-      DECL_INDIRECTFIELD,
-      /// \brief A NonTypeTemplateParmDecl record that stores an expanded
-      /// non-type template parameter pack.
-      DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK,
-      /// \brief A TemplateTemplateParmDecl record that stores an expanded
-      /// template template parameter pack.
-      DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
-      /// \brief A ClassScopeFunctionSpecializationDecl record a class scope
-      /// function specialization. (Microsoft extension).
-      DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
-      /// \brief An ImportDecl recording a module import.
-      DECL_IMPORT
-    };
-
-    /// \brief Record codes for each kind of statement or expression.
-    ///
-    /// These constants describe the records that describe statements
-    /// or expressions. These records  occur within type and declarations
-    /// block, so they begin with record values of 100.  Each constant 
-    /// describes a record for a specific statement or expression class in the
-    /// AST.
-    enum StmtCode {
-      /// \brief A marker record that indicates that we are at the end
-      /// of an expression.
-      STMT_STOP = 100,
-      /// \brief A NULL expression.
-      STMT_NULL_PTR,
-      /// \brief A reference to a previously [de]serialized Stmt record.
-      STMT_REF_PTR,
-      /// \brief A NullStmt record.
-      STMT_NULL,
-      /// \brief A CompoundStmt record.
-      STMT_COMPOUND,
-      /// \brief A CaseStmt record.
-      STMT_CASE,
-      /// \brief A DefaultStmt record.
-      STMT_DEFAULT,
-      /// \brief A LabelStmt record.
-      STMT_LABEL,
-      /// \brief An AttributedStmt record.
-      STMT_ATTRIBUTED,
-      /// \brief An IfStmt record.
-      STMT_IF,
-      /// \brief A SwitchStmt record.
-      STMT_SWITCH,
-      /// \brief A WhileStmt record.
-      STMT_WHILE,
-      /// \brief A DoStmt record.
-      STMT_DO,
-      /// \brief A ForStmt record.
-      STMT_FOR,
-      /// \brief A GotoStmt record.
-      STMT_GOTO,
-      /// \brief An IndirectGotoStmt record.
-      STMT_INDIRECT_GOTO,
-      /// \brief A ContinueStmt record.
-      STMT_CONTINUE,
-      /// \brief A BreakStmt record.
-      STMT_BREAK,
-      /// \brief A ReturnStmt record.
-      STMT_RETURN,
-      /// \brief A DeclStmt record.
-      STMT_DECL,
-      /// \brief A GCC-style AsmStmt record.
-      STMT_GCCASM,
-      /// \brief A MS-style AsmStmt record.
-      STMT_MSASM,
-      /// \brief A PredefinedExpr record.
-      EXPR_PREDEFINED,
-      /// \brief A DeclRefExpr record.
-      EXPR_DECL_REF,
-      /// \brief An IntegerLiteral record.
-      EXPR_INTEGER_LITERAL,
-      /// \brief A FloatingLiteral record.
-      EXPR_FLOATING_LITERAL,
-      /// \brief An ImaginaryLiteral record.
-      EXPR_IMAGINARY_LITERAL,
-      /// \brief A StringLiteral record.
-      EXPR_STRING_LITERAL,
-      /// \brief A CharacterLiteral record.
-      EXPR_CHARACTER_LITERAL,
-      /// \brief A ParenExpr record.
-      EXPR_PAREN,
-      /// \brief A ParenListExpr record.
-      EXPR_PAREN_LIST,
-      /// \brief A UnaryOperator record.
-      EXPR_UNARY_OPERATOR,
-      /// \brief An OffsetOfExpr record.
-      EXPR_OFFSETOF,
-      /// \brief A SizefAlignOfExpr record.
-      EXPR_SIZEOF_ALIGN_OF,
-      /// \brief An ArraySubscriptExpr record.
-      EXPR_ARRAY_SUBSCRIPT,
-      /// \brief A CallExpr record.
-      EXPR_CALL,
-      /// \brief A MemberExpr record.
-      EXPR_MEMBER,
-      /// \brief A BinaryOperator record.
-      EXPR_BINARY_OPERATOR,
-      /// \brief A CompoundAssignOperator record.
-      EXPR_COMPOUND_ASSIGN_OPERATOR,
-      /// \brief A ConditionOperator record.
-      EXPR_CONDITIONAL_OPERATOR,
-      /// \brief An ImplicitCastExpr record.
-      EXPR_IMPLICIT_CAST,
-      /// \brief A CStyleCastExpr record.
-      EXPR_CSTYLE_CAST,
-      /// \brief A CompoundLiteralExpr record.
-      EXPR_COMPOUND_LITERAL,
-      /// \brief An ExtVectorElementExpr record.
-      EXPR_EXT_VECTOR_ELEMENT,
-      /// \brief An InitListExpr record.
-      EXPR_INIT_LIST,
-      /// \brief A DesignatedInitExpr record.
-      EXPR_DESIGNATED_INIT,
-      /// \brief An ImplicitValueInitExpr record.
-      EXPR_IMPLICIT_VALUE_INIT,
-      /// \brief A VAArgExpr record.
-      EXPR_VA_ARG,
-      /// \brief An AddrLabelExpr record.
-      EXPR_ADDR_LABEL,
-      /// \brief A StmtExpr record.
-      EXPR_STMT,
-      /// \brief A ChooseExpr record.
-      EXPR_CHOOSE,
-      /// \brief A GNUNullExpr record.
-      EXPR_GNU_NULL,
-      /// \brief A ShuffleVectorExpr record.
-      EXPR_SHUFFLE_VECTOR,
-      /// \brief BlockExpr
-      EXPR_BLOCK,
-      /// \brief A GenericSelectionExpr record.
-      EXPR_GENERIC_SELECTION,
-      /// \brief A PseudoObjectExpr record.
-      EXPR_PSEUDO_OBJECT,
-      /// \brief An AtomicExpr record.
-      EXPR_ATOMIC,
-
-      // Objective-C
-
-      /// \brief An ObjCStringLiteral record.
-      EXPR_OBJC_STRING_LITERAL,
-
-      EXPR_OBJC_BOXED_EXPRESSION,
-      EXPR_OBJC_ARRAY_LITERAL,
-      EXPR_OBJC_DICTIONARY_LITERAL,
-
-    
-      /// \brief An ObjCEncodeExpr record.
-      EXPR_OBJC_ENCODE,
-      /// \brief An ObjCSelectorExpr record.
-      EXPR_OBJC_SELECTOR_EXPR,
-      /// \brief An ObjCProtocolExpr record.
-      EXPR_OBJC_PROTOCOL_EXPR,
-      /// \brief An ObjCIvarRefExpr record.
-      EXPR_OBJC_IVAR_REF_EXPR,
-      /// \brief An ObjCPropertyRefExpr record.
-      EXPR_OBJC_PROPERTY_REF_EXPR,
-      /// \brief An ObjCSubscriptRefExpr record.
-      EXPR_OBJC_SUBSCRIPT_REF_EXPR,
-      /// \brief UNUSED
-      EXPR_OBJC_KVC_REF_EXPR,
-      /// \brief An ObjCMessageExpr record.
-      EXPR_OBJC_MESSAGE_EXPR,
-      /// \brief An ObjCIsa Expr record.
-      EXPR_OBJC_ISA,
-      /// \brief An ObjCIndirectCopyRestoreExpr record.
-      EXPR_OBJC_INDIRECT_COPY_RESTORE,
-
-      /// \brief An ObjCForCollectionStmt record.
-      STMT_OBJC_FOR_COLLECTION,
-      /// \brief An ObjCAtCatchStmt record.
-      STMT_OBJC_CATCH,
-      /// \brief An ObjCAtFinallyStmt record.
-      STMT_OBJC_FINALLY,
-      /// \brief An ObjCAtTryStmt record.
-      STMT_OBJC_AT_TRY,
-      /// \brief An ObjCAtSynchronizedStmt record.
-      STMT_OBJC_AT_SYNCHRONIZED,
-      /// \brief An ObjCAtThrowStmt record.
-      STMT_OBJC_AT_THROW,
-      /// \brief An ObjCAutoreleasePoolStmt record.
-      STMT_OBJC_AUTORELEASE_POOL,
-      /// \brief A ObjCBoolLiteralExpr record.
-      EXPR_OBJC_BOOL_LITERAL,
-
-      // C++
-      
-      /// \brief A CXXCatchStmt record.
-      STMT_CXX_CATCH,
-      /// \brief A CXXTryStmt record.
-      STMT_CXX_TRY,
-      /// \brief A CXXForRangeStmt record.
-      STMT_CXX_FOR_RANGE,
-
-      /// \brief A CXXOperatorCallExpr record.
-      EXPR_CXX_OPERATOR_CALL,
-      /// \brief A CXXMemberCallExpr record.
-      EXPR_CXX_MEMBER_CALL,
-      /// \brief A CXXConstructExpr record.
-      EXPR_CXX_CONSTRUCT,
-      /// \brief A CXXTemporaryObjectExpr record.
-      EXPR_CXX_TEMPORARY_OBJECT,
-      /// \brief A CXXStaticCastExpr record.
-      EXPR_CXX_STATIC_CAST,
-      /// \brief A CXXDynamicCastExpr record.
-      EXPR_CXX_DYNAMIC_CAST,
-      /// \brief A CXXReinterpretCastExpr record.
-      EXPR_CXX_REINTERPRET_CAST,
-      /// \brief A CXXConstCastExpr record.
-      EXPR_CXX_CONST_CAST,
-      /// \brief A CXXFunctionalCastExpr record.
-      EXPR_CXX_FUNCTIONAL_CAST,
-      /// \brief A UserDefinedLiteral record.
-      EXPR_USER_DEFINED_LITERAL,
-      /// \brief A CXXBoolLiteralExpr record.
-      EXPR_CXX_BOOL_LITERAL,
-      EXPR_CXX_NULL_PTR_LITERAL,  // CXXNullPtrLiteralExpr
-      EXPR_CXX_TYPEID_EXPR,       // CXXTypeidExpr (of expr).
-      EXPR_CXX_TYPEID_TYPE,       // CXXTypeidExpr (of type).
-      EXPR_CXX_THIS,              // CXXThisExpr
-      EXPR_CXX_THROW,             // CXXThrowExpr
-      EXPR_CXX_DEFAULT_ARG,       // CXXDefaultArgExpr
-      EXPR_CXX_BIND_TEMPORARY,    // CXXBindTemporaryExpr
-
-      EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
-      EXPR_CXX_NEW,               // CXXNewExpr
-      EXPR_CXX_DELETE,            // CXXDeleteExpr
-      EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
-      
-      EXPR_EXPR_WITH_CLEANUPS,    // ExprWithCleanups
-      
-      EXPR_CXX_DEPENDENT_SCOPE_MEMBER,   // CXXDependentScopeMemberExpr
-      EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr
-      EXPR_CXX_UNRESOLVED_CONSTRUCT,     // CXXUnresolvedConstructExpr
-      EXPR_CXX_UNRESOLVED_MEMBER,        // UnresolvedMemberExpr
-      EXPR_CXX_UNRESOLVED_LOOKUP,        // UnresolvedLookupExpr
-
-      EXPR_CXX_UNARY_TYPE_TRAIT,  // UnaryTypeTraitExpr
-      EXPR_CXX_EXPRESSION_TRAIT,  // ExpressionTraitExpr
-      EXPR_CXX_NOEXCEPT,          // CXXNoexceptExpr
-
-      EXPR_OPAQUE_VALUE,          // OpaqueValueExpr
-      EXPR_BINARY_CONDITIONAL_OPERATOR,  // BinaryConditionalOperator
-      EXPR_BINARY_TYPE_TRAIT,     // BinaryTypeTraitExpr
-      EXPR_TYPE_TRAIT,            // TypeTraitExpr
-      EXPR_ARRAY_TYPE_TRAIT,      // ArrayTypeTraitIntExpr
-      
-      EXPR_PACK_EXPANSION,        // PackExpansionExpr
-      EXPR_SIZEOF_PACK,           // SizeOfPackExpr
-      EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr
-      EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr
-      EXPR_FUNCTION_PARM_PACK,    // FunctionParmPackExpr
-      EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
-      
-      // CUDA
-      EXPR_CUDA_KERNEL_CALL,       // CUDAKernelCallExpr      
-
-      // OpenCL
-      EXPR_ASTYPE,                 // AsTypeExpr
-
-      // Microsoft
-      EXPR_CXX_UUIDOF_EXPR,       // CXXUuidofExpr (of expr).
-      EXPR_CXX_UUIDOF_TYPE,       // CXXUuidofExpr (of type).
-      STMT_SEH_EXCEPT,            // SEHExceptStmt
-      STMT_SEH_FINALLY,           // SEHFinallyStmt
-      STMT_SEH_TRY,               // SEHTryStmt
-      
-      // ARC
-      EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
-      
-      STMT_MS_DEPENDENT_EXISTS,   // MSDependentExistsStmt
-      EXPR_LAMBDA                 // LambdaExpr
-    };
-
-    /// \brief The kinds of designators that can occur in a
-    /// DesignatedInitExpr.
-    enum DesignatorTypes {
-      /// \brief Field designator where only the field name is known.
-      DESIG_FIELD_NAME  = 0,
-      /// \brief Field designator where the field has been resolved to
-      /// a declaration.
-      DESIG_FIELD_DECL  = 1,
-      /// \brief Array designator.
-      DESIG_ARRAY       = 2,
-      /// \brief GNU array range designator.
-      DESIG_ARRAY_RANGE = 3
-    };
-
-    /// \brief The different kinds of data that can occur in a
-    /// CtorInitializer.
-    enum CtorInitializerType {
-      CTOR_INITIALIZER_BASE,
-      CTOR_INITIALIZER_DELEGATING,
-      CTOR_INITIALIZER_MEMBER,
-      CTOR_INITIALIZER_INDIRECT_MEMBER
-    };
-
-    /// \brief Describes the redeclarations of a declaration.
-    struct LocalRedeclarationsInfo {
-      DeclID FirstID;      // The ID of the first declaration
-      unsigned Offset;     // Offset into the array of redeclaration chains.
-      
-      friend bool operator<(const LocalRedeclarationsInfo &X,
-                            const LocalRedeclarationsInfo &Y) {
-        return X.FirstID < Y.FirstID;
-      }
-      
-      friend bool operator>(const LocalRedeclarationsInfo &X,
-                            const LocalRedeclarationsInfo &Y) {
-        return X.FirstID > Y.FirstID;
-      }
-      
-      friend bool operator<=(const LocalRedeclarationsInfo &X,
-                             const LocalRedeclarationsInfo &Y) {
-        return X.FirstID <= Y.FirstID;
-      }
-      
-      friend bool operator>=(const LocalRedeclarationsInfo &X,
-                             const LocalRedeclarationsInfo &Y) {
-        return X.FirstID >= Y.FirstID;
-      }
-    };
-
-    /// \brief Describes the categories of an Objective-C class.
-    struct ObjCCategoriesInfo {
-      DeclID DefinitionID; // The ID of the definition
-      unsigned Offset;     // Offset into the array of category lists.
-      
-      friend bool operator<(const ObjCCategoriesInfo &X,
-                            const ObjCCategoriesInfo &Y) {
-        return X.DefinitionID < Y.DefinitionID;
-      }
-      
-      friend bool operator>(const ObjCCategoriesInfo &X,
-                            const ObjCCategoriesInfo &Y) {
-        return X.DefinitionID > Y.DefinitionID;
-      }
-      
-      friend bool operator<=(const ObjCCategoriesInfo &X,
-                             const ObjCCategoriesInfo &Y) {
-        return X.DefinitionID <= Y.DefinitionID;
-      }
-      
-      friend bool operator>=(const ObjCCategoriesInfo &X,
-                             const ObjCCategoriesInfo &Y) {
-        return X.DefinitionID >= Y.DefinitionID;
-      }
-    };
-
-    /// @}
-  }
-} // end namespace clang
-
-#endif
+//===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines Bitcode enum values for Clang serialized AST files.
+//
+// The enum values defined in this file should be considered permanent.  If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_PCHBITCODES_H
+#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
+
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+  namespace serialization {
+    /// \brief AST file major version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the AST file format changes in a way that makes it
+    /// incompatible with previous versions (such that a reader
+    /// designed for the previous version could not support reading
+    /// the new version), this number should be increased.
+    ///
+    /// Version 4 of AST files also requires that the version control branch and
+    /// revision match exactly, since there is no backward compatibility of
+    /// AST files at this time.
+    const unsigned VERSION_MAJOR = 5;
+
+    /// \brief AST file minor version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the AST format changes in a way that is still
+    /// compatible with previous versions (such that a reader designed
+    /// for the previous version could still support reading the new
+    /// version by ignoring new kinds of subblocks), this number
+    /// should be increased.
+    const unsigned VERSION_MINOR = 0;
+
+    /// \brief An ID number that refers to an identifier in an AST file.
+    /// 
+    /// The ID numbers of identifiers are consecutive (in order of discovery)
+    /// and start at 1. 0 is reserved for NULL.
+    typedef uint32_t IdentifierID;
+    
+    /// \brief An ID number that refers to a declaration in an AST file.
+    ///
+    /// The ID numbers of declarations are consecutive (in order of
+    /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. 
+    /// At the start of a chain of precompiled headers, declaration ID 1 is 
+    /// used for the translation unit declaration.
+    typedef uint32_t DeclID;
+
+    /// \brief a Decl::Kind/DeclID pair.
+    typedef std::pair<uint32_t, DeclID> KindDeclIDPair;
+
+    // FIXME: Turn these into classes so we can have some type safety when
+    // we go from local ID to global and vice-versa.
+    typedef DeclID LocalDeclID;
+    typedef DeclID GlobalDeclID;
+
+    /// \brief An ID number that refers to a type in an AST file.
+    ///
+    /// The ID of a type is partitioned into two parts: the lower
+    /// three bits are used to store the const/volatile/restrict
+    /// qualifiers (as with QualType) and the upper bits provide a
+    /// type index. The type index values are partitioned into two
+    /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type
+    /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a
+    /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are
+    /// other types that have serialized representations.
+    typedef uint32_t TypeID;
+
+    /// \brief A type index; the type ID with the qualifier bits removed.
+    class TypeIdx {
+      uint32_t Idx;
+    public:
+      TypeIdx() : Idx(0) { }
+      explicit TypeIdx(uint32_t index) : Idx(index) { }
+
+      uint32_t getIndex() const { return Idx; }
+      TypeID asTypeID(unsigned FastQuals) const {
+        if (Idx == uint32_t(-1))
+          return TypeID(-1);
+        
+        return (Idx << Qualifiers::FastWidth) | FastQuals;
+      }
+      static TypeIdx fromTypeID(TypeID ID) {
+        if (ID == TypeID(-1))
+          return TypeIdx(-1);
+        
+        return TypeIdx(ID >> Qualifiers::FastWidth);
+      }
+    };
+
+    /// A structure for putting "fast"-unqualified QualTypes into a
+    /// DenseMap.  This uses the standard pointer hash function.
+    struct UnsafeQualTypeDenseMapInfo {
+      static inline bool isEqual(QualType A, QualType B) { return A == B; }
+      static inline QualType getEmptyKey() {
+        return QualType::getFromOpaquePtr((void*) 1);
+      }
+      static inline QualType getTombstoneKey() {
+        return QualType::getFromOpaquePtr((void*) 2);
+      }
+      static inline unsigned getHashValue(QualType T) {
+        assert(!T.getLocalFastQualifiers() && 
+               "hash invalid for types with fast quals");
+        uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+        return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
+      }
+    };
+
+    /// \brief An ID number that refers to an identifier in an AST file.
+    typedef uint32_t IdentID;
+
+    /// \brief The number of predefined identifier IDs.
+    const unsigned int NUM_PREDEF_IDENT_IDS = 1;
+
+    /// \brief An ID number that refers to a macro in an AST file.
+    typedef uint32_t MacroID;
+    
+    /// \brief The number of predefined macro IDs.
+    const unsigned int NUM_PREDEF_MACRO_IDS = 1;
+
+    /// \brief An ID number that refers to an ObjC selector in an AST file.
+    typedef uint32_t SelectorID;
+
+    /// \brief The number of predefined selector IDs.
+    const unsigned int NUM_PREDEF_SELECTOR_IDS = 1;
+    
+    /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an 
+    /// AST file.
+    typedef uint32_t CXXBaseSpecifiersID;
+    
+    /// \brief An ID number that refers to an entity in the detailed
+    /// preprocessing record.
+    typedef uint32_t PreprocessedEntityID;
+
+    /// \brief An ID number that refers to a submodule in a module file.
+    typedef uint32_t SubmoduleID;
+    
+    /// \brief The number of predefined submodule IDs.
+    const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
+
+    /// \brief Source range/offset of a preprocessed entity.
+    struct PPEntityOffset {
+      /// \brief Raw source location of beginning of range.
+      unsigned Begin;
+      /// \brief Raw source location of end of range.
+      unsigned End;
+      /// \brief Offset in the AST file.
+      uint32_t BitOffset;
+
+      PPEntityOffset(SourceRange R, uint32_t BitOffset)
+        : Begin(R.getBegin().getRawEncoding()),
+          End(R.getEnd().getRawEncoding()),
+          BitOffset(BitOffset) { }
+    };
+
+    /// \brief Source range/offset of a preprocessed entity.
+    struct DeclOffset {
+      /// \brief Raw source location.
+      unsigned Loc;
+      /// \brief Offset in the AST file.
+      uint32_t BitOffset;
+
+      DeclOffset() : Loc(0), BitOffset(0) { }
+      DeclOffset(SourceLocation Loc, uint32_t BitOffset)
+        : Loc(Loc.getRawEncoding()),
+          BitOffset(BitOffset) { }
+      void setLocation(SourceLocation L) {
+        Loc = L.getRawEncoding();
+      }
+    };
+
+    /// \brief The number of predefined preprocessed entity IDs.
+    const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
+
+    /// \brief Describes the various kinds of blocks that occur within
+    /// an AST file.
+    enum BlockIDs {
+      /// \brief The AST block, which acts as a container around the
+      /// full AST block.
+      AST_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+      /// \brief The block containing information about the source
+      /// manager.
+      SOURCE_MANAGER_BLOCK_ID,
+
+      /// \brief The block containing information about the
+      /// preprocessor.
+      PREPROCESSOR_BLOCK_ID,
+
+      /// \brief The block containing the definitions of all of the
+      /// types and decls used within the AST file.
+      DECLTYPES_BLOCK_ID,
+
+      /// \brief The block containing DECL_UPDATES records.
+      DECL_UPDATES_BLOCK_ID,
+      
+      /// \brief The block containing the detailed preprocessing record.
+      PREPROCESSOR_DETAIL_BLOCK_ID,
+      
+      /// \brief The block containing the submodule structure.
+      SUBMODULE_BLOCK_ID,
+
+      /// \brief The block containing comments.
+      COMMENTS_BLOCK_ID,
+
+      /// \brief The control block, which contains all of the
+      /// information that needs to be validated prior to committing
+      /// to loading the AST file.
+      CONTROL_BLOCK_ID,
+
+      /// \brief The block of input files, which were used as inputs
+      /// to create this AST file.
+      ///
+      /// This block is part of the control block.
+      INPUT_FILES_BLOCK_ID
+    };
+
+    /// \brief Record types that occur within the control block.
+    enum ControlRecordTypes {
+      /// \brief AST file metadata, including the AST file version number
+      /// and information about the compiler used to build this AST file.
+      METADATA = 1,
+
+      /// \brief Record code for the list of other AST files imported by
+      /// this AST file.
+      IMPORTS = 2,
+
+      /// \brief Record code for the language options table.
+      ///
+      /// The record with this code contains the contents of the
+      /// LangOptions structure. We serialize the entire contents of
+      /// the structure, and let the reader decide which options are
+      /// actually important to check.
+      LANGUAGE_OPTIONS = 3,
+
+      /// \brief Record code for the target options table.
+      TARGET_OPTIONS = 4,
+
+      /// \brief Record code for the original file that was used to
+      /// generate the AST file, including both its file ID and its
+      /// name.
+      ORIGINAL_FILE = 5,
+      
+      /// \brief The directory that the PCH was originally created in.
+      ORIGINAL_PCH_DIR = 6,
+
+      /// \brief Record code for file ID of the file or buffer that was used to
+      /// generate the AST file.
+      ORIGINAL_FILE_ID = 7,
+
+      /// \brief Offsets into the input-files block where input files
+      /// reside.
+      INPUT_FILE_OFFSETS = 8,
+
+      /// \brief Record code for the diagnostic options table.
+      DIAGNOSTIC_OPTIONS = 9,
+
+      /// \brief Record code for the filesystem options table.
+      FILE_SYSTEM_OPTIONS = 10,
+
+      /// \brief Record code for the headers search options table.
+      HEADER_SEARCH_OPTIONS = 11,
+
+      /// \brief Record code for the preprocessor options table.
+      PREPROCESSOR_OPTIONS = 12
+    };
+
+    /// \brief Record types that occur within the input-files block
+    /// inside the control block.
+    enum InputFileRecordTypes {
+      /// \brief An input file.
+      INPUT_FILE = 1
+    };
+
+    /// \brief Record types that occur within the AST block itself.
+    enum ASTRecordTypes {
+      /// \brief Record code for the offsets of each type.
+      ///
+      /// The TYPE_OFFSET constant describes the record that occurs
+      /// within the AST block. The record itself is an array of offsets that
+      /// point into the declarations and types block (identified by 
+      /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
+      /// of a type. For a given type ID @c T, the lower three bits of
+      /// @c T are its qualifiers (const, volatile, restrict), as in
+      /// the QualType class. The upper bits, after being shifted and
+      /// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
+      /// TYPE_OFFSET block to determine the offset of that type's
+      /// corresponding record within the DECLTYPES_BLOCK_ID block.
+      TYPE_OFFSET = 1,
+
+      /// \brief Record code for the offsets of each decl.
+      ///
+      /// The DECL_OFFSET constant describes the record that occurs
+      /// within the block identified by DECL_OFFSETS_BLOCK_ID within
+      /// the AST block. The record itself is an array of offsets that
+      /// point into the declarations and types block (identified by
+      /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
+      /// record, after subtracting one to account for the use of
+      /// declaration ID 0 for a NULL declaration pointer. Index 0 is
+      /// reserved for the translation unit declaration.
+      DECL_OFFSET = 2,
+
+      /// \brief Record code for the table of offsets of each
+      /// identifier ID.
+      ///
+      /// The offset table contains offsets into the blob stored in
+      /// the IDENTIFIER_TABLE record. Each offset points to the
+      /// NULL-terminated string that corresponds to that identifier.
+      IDENTIFIER_OFFSET = 3,
+
+      /// \brief This is so that older clang versions, before the introduction
+      /// of the control block, can read and reject the newer PCH format.
+      /// *DON"T CHANGE THIS NUMBER*.
+      METADATA_OLD_FORMAT = 4,
+
+      /// \brief Record code for the identifier table.
+      ///
+      /// The identifier table is a simple blob that contains
+      /// NULL-terminated strings for all of the identifiers
+      /// referenced by the AST file. The IDENTIFIER_OFFSET table
+      /// contains the mapping from identifier IDs to the characters
+      /// in this blob. Note that the starting offsets of all of the
+      /// identifiers are odd, so that, when the identifier offset
+      /// table is loaded in, we can use the low bit to distinguish
+      /// between offsets (for unresolved identifier IDs) and
+      /// IdentifierInfo pointers (for already-resolved identifier
+      /// IDs).
+      IDENTIFIER_TABLE = 5,
+
+      /// \brief Record code for the array of external definitions.
+      ///
+      /// The AST file contains a list of all of the unnamed external
+      /// definitions present within the parsed headers, stored as an
+      /// array of declaration IDs. These external definitions will be
+      /// reported to the AST consumer after the AST file has been
+      /// read, since their presence can affect the semantics of the
+      /// program (e.g., for code generation).
+      EXTERNAL_DEFINITIONS = 6,
+
+      /// \brief Record code for the set of non-builtin, special
+      /// types.
+      ///
+      /// This record contains the type IDs for the various type nodes
+      /// that are constructed during semantic analysis (e.g.,
+      /// __builtin_va_list). The SPECIAL_TYPE_* constants provide
+      /// offsets into this record.
+      SPECIAL_TYPES = 7,
+
+      /// \brief Record code for the extra statistics we gather while
+      /// generating an AST file.
+      STATISTICS = 8,
+
+      /// \brief Record code for the array of tentative definitions.
+      TENTATIVE_DEFINITIONS = 9,
+
+      /// \brief Record code for the array of locally-scoped external
+      /// declarations.
+      LOCALLY_SCOPED_EXTERNAL_DECLS = 10,
+
+      /// \brief Record code for the table of offsets into the
+      /// Objective-C method pool.
+      SELECTOR_OFFSETS = 11,
+
+      /// \brief Record code for the Objective-C method pool,
+      METHOD_POOL = 12,
+
+      /// \brief The value of the next __COUNTER__ to dispense.
+      /// [PP_COUNTER_VALUE, Val]
+      PP_COUNTER_VALUE = 13,
+
+      /// \brief Record code for the table of offsets into the block
+      /// of source-location information.
+      SOURCE_LOCATION_OFFSETS = 14,
+
+      /// \brief Record code for the set of source location entries
+      /// that need to be preloaded by the AST reader.
+      ///
+      /// This set contains the source location entry for the
+      /// predefines buffer and for any file entries that need to be
+      /// preloaded.
+      SOURCE_LOCATION_PRELOADS = 15,
+
+      /// \brief Record code for the set of ext_vector type names.
+      EXT_VECTOR_DECLS = 16,
+      
+      /// \brief Record code for the array of unused file scoped decls.
+      UNUSED_FILESCOPED_DECLS = 17,
+      
+      /// \brief Record code for the table of offsets to entries in the
+      /// preprocessing record.
+      PPD_ENTITIES_OFFSETS = 18,
+
+      /// \brief Record code for the array of VTable uses.
+      VTABLE_USES = 19,
+
+      /// \brief Record code for the array of dynamic classes.
+      DYNAMIC_CLASSES = 20,
+
+      /// \brief Record code for referenced selector pool.
+      REFERENCED_SELECTOR_POOL = 21,
+
+      /// \brief Record code for an update to the TU's lexically contained
+      /// declarations.
+      TU_UPDATE_LEXICAL = 22,
+      
+      /// \brief Record code for the array describing the locations (in the
+      /// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by
+      /// the first known ID.
+      LOCAL_REDECLARATIONS_MAP = 23,
+
+      /// \brief Record code for declarations that Sema keeps references of.
+      SEMA_DECL_REFS = 24,
+
+      /// \brief Record code for weak undeclared identifiers.
+      WEAK_UNDECLARED_IDENTIFIERS = 25,
+
+      /// \brief Record code for pending implicit instantiations.
+      PENDING_IMPLICIT_INSTANTIATIONS = 26,
+
+      /// \brief Record code for a decl replacement block.
+      ///
+      /// If a declaration is modified after having been deserialized, and then
+      /// written to a dependent AST file, its ID and offset must be added to
+      /// the replacement block.
+      DECL_REPLACEMENTS = 27,
+
+      /// \brief Record code for an update to a decl context's lookup table.
+      ///
+      /// In practice, this should only be used for the TU and namespaces.
+      UPDATE_VISIBLE = 28,
+
+      /// \brief Record for offsets of DECL_UPDATES records for declarations
+      /// that were modified after being deserialized and need updates.
+      DECL_UPDATE_OFFSETS = 29,
+
+      /// \brief Record of updates for a declaration that was modified after
+      /// being deserialized.
+      DECL_UPDATES = 30,
+      
+      /// \brief Record code for the table of offsets to CXXBaseSpecifier
+      /// sets.
+      CXX_BASE_SPECIFIER_OFFSETS = 31,
+
+      /// \brief Record code for \#pragma diagnostic mappings.
+      DIAG_PRAGMA_MAPPINGS = 32,
+
+      /// \brief Record code for special CUDA declarations.
+      CUDA_SPECIAL_DECL_REFS = 33,
+      
+      /// \brief Record code for header search information.
+      HEADER_SEARCH_TABLE = 34,
+
+      /// \brief Record code for floating point \#pragma options.
+      FP_PRAGMA_OPTIONS = 35,
+
+      /// \brief Record code for enabled OpenCL extensions.
+      OPENCL_EXTENSIONS = 36,
+
+      /// \brief The list of delegating constructor declarations.
+      DELEGATING_CTORS = 37,
+
+      /// \brief Record code for the set of known namespaces, which are used
+      /// for typo correction.
+      KNOWN_NAMESPACES = 38,
+
+      /// \brief Record code for the remapping information used to relate
+      /// loaded modules to the various offsets and IDs(e.g., source location 
+      /// offests, declaration and type IDs) that are used in that module to
+      /// refer to other modules.
+      MODULE_OFFSET_MAP = 39,
+
+      /// \brief Record code for the source manager line table information,
+      /// which stores information about \#line directives.
+      SOURCE_MANAGER_LINE_TABLE = 40,
+
+      /// \brief Record code for map of Objective-C class definition IDs to the 
+      /// ObjC categories in a module that are attached to that class.
+      OBJC_CATEGORIES_MAP = 41,
+
+      /// \brief Record code for a file sorted array of DeclIDs in a module.
+      FILE_SORTED_DECLS = 42,
+      
+      /// \brief Record code for an array of all of the (sub)modules that were
+      /// imported by the AST file.
+      IMPORTED_MODULES = 43,
+      
+      /// \brief Record code for the set of merged declarations in an AST file.
+      MERGED_DECLARATIONS = 44,
+      
+      /// \brief Record code for the array of redeclaration chains.
+      ///
+      /// This array can only be interpreted properly using the local 
+      /// redeclarations map.
+      LOCAL_REDECLARATIONS = 45,
+      
+      /// \brief Record code for the array of Objective-C categories (including
+      /// extensions).
+      ///
+      /// This array can only be interpreted properly using the Objective-C
+      /// categories map.
+      OBJC_CATEGORIES = 46,
+
+      /// \brief Record code for the table of offsets of each macro ID.
+      ///
+      /// The offset table contains offsets into the blob stored in
+      /// the preprocessor block. Each offset points to the corresponding
+      /// macro definition.
+      MACRO_OFFSET = 47,
+
+      /// \brief Record of updates for a macro that was modified after
+      /// being deserialized.
+      MACRO_UPDATES = 48
+    };
+
+    /// \brief Record types used within a source manager block.
+    enum SourceManagerRecordTypes {
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// file.
+      SM_SLOC_FILE_ENTRY = 1,
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// buffer.
+      SM_SLOC_BUFFER_ENTRY = 2,
+      /// \brief Describes a blob that contains the data for a buffer
+      /// entry. This kind of record always directly follows a
+      /// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an
+      /// overridden buffer.
+      SM_SLOC_BUFFER_BLOB = 3,
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// macro expansion.
+      SM_SLOC_EXPANSION_ENTRY = 4
+    };
+
+    /// \brief Record types used within a preprocessor block.
+    enum PreprocessorRecordTypes {
+      // The macros in the PP section are a PP_MACRO_* instance followed by a
+      // list of PP_TOKEN instances for each token in the definition.
+
+      /// \brief An object-like macro definition.
+      /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed]
+      PP_MACRO_OBJECT_LIKE = 1,
+
+      /// \brief A function-like macro definition.
+      /// [PP_MACRO_FUNCTION_LIKE, \<ObjectLikeStuff>, IsC99Varargs,
+      /// IsGNUVarars, NumArgs, ArgIdentInfoID* ]
+      PP_MACRO_FUNCTION_LIKE = 2,
+
+      /// \brief Describes one token.
+      /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
+      PP_TOKEN = 3
+    };
+
+    /// \brief Record types used within a preprocessor detail block.
+    enum PreprocessorDetailRecordTypes {
+      /// \brief Describes a macro expansion within the preprocessing record.
+      PPD_MACRO_EXPANSION = 0,
+      
+      /// \brief Describes a macro definition within the preprocessing record.
+      PPD_MACRO_DEFINITION = 1,
+      
+      /// \brief Describes an inclusion directive within the preprocessing
+      /// record.
+      PPD_INCLUSION_DIRECTIVE = 2
+    };
+    
+    /// \brief Record types used within a submodule description block.
+    enum SubmoduleRecordTypes {
+      /// \brief Metadata for submodules as a whole.
+      SUBMODULE_METADATA = 0,
+      /// \brief Defines the major attributes of a submodule, including its
+      /// name and parent.
+      SUBMODULE_DEFINITION = 1,
+      /// \brief Specifies the umbrella header used to create this module,
+      /// if any.
+      SUBMODULE_UMBRELLA_HEADER = 2,
+      /// \brief Specifies a header that falls into this (sub)module.
+      SUBMODULE_HEADER = 3,
+      /// \brief Specifies a top-level header that falls into this (sub)module.
+      SUBMODULE_TOPHEADER = 4,
+      /// \brief Specifies an umbrella directory.
+      SUBMODULE_UMBRELLA_DIR = 5,
+      /// \brief Specifies the submodules that are imported by this 
+      /// submodule.
+      SUBMODULE_IMPORTS = 6,
+      /// \brief Specifies the submodules that are re-exported from this 
+      /// submodule.
+      SUBMODULE_EXPORTS = 7,
+      /// \brief Specifies a required feature.
+      SUBMODULE_REQUIRES = 8,
+      /// \brief Specifies a header that has been explicitly excluded
+      /// from this submodule.
+      SUBMODULE_EXCLUDED_HEADER = 9
+    };
+
+    /// \brief Record types used within a comments block.
+    enum CommentRecordTypes {
+      COMMENTS_RAW_COMMENT = 0
+    };
+
+    /// \defgroup ASTAST AST file AST constants
+    ///
+    /// The constants in this group describe various components of the
+    /// abstract syntax tree within an AST file.
+    ///
+    /// @{
+
+    /// \brief Predefined type IDs.
+    ///
+    /// These type IDs correspond to predefined types in the AST
+    /// context, such as built-in types (int) and special place-holder
+    /// types (the \<overload> and \<dependent> type markers). Such
+    /// types are never actually serialized, since they will be built
+    /// by the AST context when it is created.
+    enum PredefinedTypeIDs {
+      /// \brief The NULL type.
+      PREDEF_TYPE_NULL_ID       = 0,
+      /// \brief The void type.
+      PREDEF_TYPE_VOID_ID       = 1,
+      /// \brief The 'bool' or '_Bool' type.
+      PREDEF_TYPE_BOOL_ID       = 2,
+      /// \brief The 'char' type, when it is unsigned.
+      PREDEF_TYPE_CHAR_U_ID     = 3,
+      /// \brief The 'unsigned char' type.
+      PREDEF_TYPE_UCHAR_ID      = 4,
+      /// \brief The 'unsigned short' type.
+      PREDEF_TYPE_USHORT_ID     = 5,
+      /// \brief The 'unsigned int' type.
+      PREDEF_TYPE_UINT_ID       = 6,
+      /// \brief The 'unsigned long' type.
+      PREDEF_TYPE_ULONG_ID      = 7,
+      /// \brief The 'unsigned long long' type.
+      PREDEF_TYPE_ULONGLONG_ID  = 8,
+      /// \brief The 'char' type, when it is signed.
+      PREDEF_TYPE_CHAR_S_ID     = 9,
+      /// \brief The 'signed char' type.
+      PREDEF_TYPE_SCHAR_ID      = 10,
+      /// \brief The C++ 'wchar_t' type.
+      PREDEF_TYPE_WCHAR_ID      = 11,
+      /// \brief The (signed) 'short' type.
+      PREDEF_TYPE_SHORT_ID      = 12,
+      /// \brief The (signed) 'int' type.
+      PREDEF_TYPE_INT_ID        = 13,
+      /// \brief The (signed) 'long' type.
+      PREDEF_TYPE_LONG_ID       = 14,
+      /// \brief The (signed) 'long long' type.
+      PREDEF_TYPE_LONGLONG_ID   = 15,
+      /// \brief The 'float' type.
+      PREDEF_TYPE_FLOAT_ID      = 16,
+      /// \brief The 'double' type.
+      PREDEF_TYPE_DOUBLE_ID     = 17,
+      /// \brief The 'long double' type.
+      PREDEF_TYPE_LONGDOUBLE_ID = 18,
+      /// \brief The placeholder type for overloaded function sets.
+      PREDEF_TYPE_OVERLOAD_ID   = 19,
+      /// \brief The placeholder type for dependent types.
+      PREDEF_TYPE_DEPENDENT_ID  = 20,
+      /// \brief The '__uint128_t' type.
+      PREDEF_TYPE_UINT128_ID    = 21,
+      /// \brief The '__int128_t' type.
+      PREDEF_TYPE_INT128_ID     = 22,
+      /// \brief The type of 'nullptr'.
+      PREDEF_TYPE_NULLPTR_ID    = 23,
+      /// \brief The C++ 'char16_t' type.
+      PREDEF_TYPE_CHAR16_ID     = 24,
+      /// \brief The C++ 'char32_t' type.
+      PREDEF_TYPE_CHAR32_ID     = 25,
+      /// \brief The ObjC 'id' type.
+      PREDEF_TYPE_OBJC_ID       = 26,
+      /// \brief The ObjC 'Class' type.
+      PREDEF_TYPE_OBJC_CLASS    = 27,
+      /// \brief The ObjC 'SEL' type.
+      PREDEF_TYPE_OBJC_SEL      = 28,
+      /// \brief The 'unknown any' placeholder type.
+      PREDEF_TYPE_UNKNOWN_ANY   = 29,
+      /// \brief The placeholder type for bound member functions.
+      PREDEF_TYPE_BOUND_MEMBER  = 30,
+      /// \brief The "auto" deduction type.
+      PREDEF_TYPE_AUTO_DEDUCT   = 31,
+      /// \brief The "auto &&" deduction type.
+      PREDEF_TYPE_AUTO_RREF_DEDUCT = 32,
+      /// \brief The OpenCL 'half' / ARM NEON __fp16 type.
+      PREDEF_TYPE_HALF_ID       = 33,
+      /// \brief ARC's unbridged-cast placeholder type.
+      PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
+      /// \brief The pseudo-object placeholder type.
+      PREDEF_TYPE_PSEUDO_OBJECT = 35,
+      /// \brief The __va_list_tag placeholder type.
+      PREDEF_TYPE_VA_LIST_TAG = 36,
+      /// \brief The placeholder type for builtin functions.
+      PREDEF_TYPE_BUILTIN_FN = 37
+    };
+
+    /// \brief The number of predefined type IDs that are reserved for
+    /// the PREDEF_TYPE_* constants.
+    ///
+    /// Type IDs for non-predefined types will start at
+    /// NUM_PREDEF_TYPE_IDs.
+    const unsigned NUM_PREDEF_TYPE_IDS = 100;
+
+    /// \brief The number of allowed abbreviations in bits
+    const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4;
+
+    /// \brief Record codes for each kind of type.
+    ///
+    /// These constants describe the type records that can occur within a
+    /// block identified by DECLTYPES_BLOCK_ID in the AST file. Each
+    /// constant describes a record for a specific type class in the
+    /// AST.
+    enum TypeCode {
+      /// \brief An ExtQualType record.
+      TYPE_EXT_QUAL                 = 1,
+      /// \brief A ComplexType record.
+      TYPE_COMPLEX                  = 3,
+      /// \brief A PointerType record.
+      TYPE_POINTER                  = 4,
+      /// \brief A BlockPointerType record.
+      TYPE_BLOCK_POINTER            = 5,
+      /// \brief An LValueReferenceType record.
+      TYPE_LVALUE_REFERENCE         = 6,
+      /// \brief An RValueReferenceType record.
+      TYPE_RVALUE_REFERENCE         = 7,
+      /// \brief A MemberPointerType record.
+      TYPE_MEMBER_POINTER           = 8,
+      /// \brief A ConstantArrayType record.
+      TYPE_CONSTANT_ARRAY           = 9,
+      /// \brief An IncompleteArrayType record.
+      TYPE_INCOMPLETE_ARRAY         = 10,
+      /// \brief A VariableArrayType record.
+      TYPE_VARIABLE_ARRAY           = 11,
+      /// \brief A VectorType record.
+      TYPE_VECTOR                   = 12,
+      /// \brief An ExtVectorType record.
+      TYPE_EXT_VECTOR               = 13,
+      /// \brief A FunctionNoProtoType record.
+      TYPE_FUNCTION_NO_PROTO        = 14,
+      /// \brief A FunctionProtoType record.
+      TYPE_FUNCTION_PROTO           = 15,
+      /// \brief A TypedefType record.
+      TYPE_TYPEDEF                  = 16,
+      /// \brief A TypeOfExprType record.
+      TYPE_TYPEOF_EXPR              = 17,
+      /// \brief A TypeOfType record.
+      TYPE_TYPEOF                   = 18,
+      /// \brief A RecordType record.
+      TYPE_RECORD                   = 19,
+      /// \brief An EnumType record.
+      TYPE_ENUM                     = 20,
+      /// \brief An ObjCInterfaceType record.
+      TYPE_OBJC_INTERFACE           = 21,
+      /// \brief An ObjCObjectPointerType record.
+      TYPE_OBJC_OBJECT_POINTER      = 22,
+      /// \brief a DecltypeType record.
+      TYPE_DECLTYPE                 = 23,
+      /// \brief An ElaboratedType record.
+      TYPE_ELABORATED               = 24,
+      /// \brief A SubstTemplateTypeParmType record.
+      TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
+      /// \brief An UnresolvedUsingType record.
+      TYPE_UNRESOLVED_USING         = 26,
+      /// \brief An InjectedClassNameType record.
+      TYPE_INJECTED_CLASS_NAME      = 27,
+      /// \brief An ObjCObjectType record.
+      TYPE_OBJC_OBJECT              = 28,
+      /// \brief An TemplateTypeParmType record.
+      TYPE_TEMPLATE_TYPE_PARM       = 29,
+      /// \brief An TemplateSpecializationType record.
+      TYPE_TEMPLATE_SPECIALIZATION  = 30,
+      /// \brief A DependentNameType record.
+      TYPE_DEPENDENT_NAME           = 31,
+      /// \brief A DependentTemplateSpecializationType record.
+      TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
+      /// \brief A DependentSizedArrayType record.
+      TYPE_DEPENDENT_SIZED_ARRAY    = 33,
+      /// \brief A ParenType record.
+      TYPE_PAREN                    = 34,
+      /// \brief A PackExpansionType record.
+      TYPE_PACK_EXPANSION           = 35,
+      /// \brief An AttributedType record.
+      TYPE_ATTRIBUTED               = 36,
+      /// \brief A SubstTemplateTypeParmPackType record.
+      TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
+      /// \brief A AutoType record.
+      TYPE_AUTO                  = 38,
+      /// \brief A UnaryTransformType record.
+      TYPE_UNARY_TRANSFORM       = 39,
+      /// \brief An AtomicType record.
+      TYPE_ATOMIC                = 40
+    };
+
+    /// \brief The type IDs for special types constructed by semantic
+    /// analysis.
+    ///
+    /// The constants in this enumeration are indices into the
+    /// SPECIAL_TYPES record.
+    enum SpecialTypeIDs {
+      /// \brief CFConstantString type
+      SPECIAL_TYPE_CF_CONSTANT_STRING          = 0,
+      /// \brief C FILE typedef type
+      SPECIAL_TYPE_FILE                        = 1,
+      /// \brief C jmp_buf typedef type
+      SPECIAL_TYPE_JMP_BUF                     = 2,
+      /// \brief C sigjmp_buf typedef type
+      SPECIAL_TYPE_SIGJMP_BUF                  = 3,
+      /// \brief Objective-C "id" redefinition type
+      SPECIAL_TYPE_OBJC_ID_REDEFINITION        = 4,
+      /// \brief Objective-C "Class" redefinition type
+      SPECIAL_TYPE_OBJC_CLASS_REDEFINITION     = 5,
+      /// \brief Objective-C "SEL" redefinition type
+      SPECIAL_TYPE_OBJC_SEL_REDEFINITION       = 6,
+      /// \brief C ucontext_t typedef type
+      SPECIAL_TYPE_UCONTEXT_T                  = 7
+    };
+    
+    /// \brief The number of special type IDs.
+    const unsigned NumSpecialTypeIDs = 8;
+
+    /// \brief Predefined declaration IDs.
+    ///
+    /// These declaration IDs correspond to predefined declarations in the AST
+    /// context, such as the NULL declaration ID. Such declarations are never
+    /// actually serialized, since they will be built by the AST context when 
+    /// it is created.
+    enum PredefinedDeclIDs {
+      /// \brief The NULL declaration.
+      PREDEF_DECL_NULL_ID       = 0,
+      
+      /// \brief The translation unit.
+      PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
+      
+      /// \brief The Objective-C 'id' type.
+      PREDEF_DECL_OBJC_ID_ID = 2,
+      
+      /// \brief The Objective-C 'SEL' type.
+      PREDEF_DECL_OBJC_SEL_ID = 3,
+      
+      /// \brief The Objective-C 'Class' type.
+      PREDEF_DECL_OBJC_CLASS_ID = 4,
+            
+      /// \brief The Objective-C 'Protocol' type.
+      PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
+      
+      /// \brief The signed 128-bit integer type.
+      PREDEF_DECL_INT_128_ID = 6,
+
+      /// \brief The unsigned 128-bit integer type.
+      PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
+      
+      /// \brief The internal 'instancetype' typedef.
+      PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
+
+      /// \brief The internal '__builtin_va_list' typedef.
+      PREDEF_DECL_BUILTIN_VA_LIST_ID = 9
+    };
+
+    /// \brief The number of declaration IDs that are predefined.
+    ///
+    /// For more information about predefined declarations, see the
+    /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
+    const unsigned int NUM_PREDEF_DECL_IDS = 10;
+    
+    /// \brief Record codes for each kind of declaration.
+    ///
+    /// These constants describe the declaration records that can occur within
+    /// a declarations block (identified by DECLS_BLOCK_ID). Each
+    /// constant describes a record for a specific declaration class
+    /// in the AST.
+    enum DeclCode {
+      /// \brief A TypedefDecl record.
+      DECL_TYPEDEF = 51,
+      /// \brief A TypeAliasDecl record.
+      DECL_TYPEALIAS,
+      /// \brief An EnumDecl record.
+      DECL_ENUM,
+      /// \brief A RecordDecl record.
+      DECL_RECORD,
+      /// \brief An EnumConstantDecl record.
+      DECL_ENUM_CONSTANT,
+      /// \brief A FunctionDecl record.
+      DECL_FUNCTION,
+      /// \brief A ObjCMethodDecl record.
+      DECL_OBJC_METHOD,
+      /// \brief A ObjCInterfaceDecl record.
+      DECL_OBJC_INTERFACE,
+      /// \brief A ObjCProtocolDecl record.
+      DECL_OBJC_PROTOCOL,
+      /// \brief A ObjCIvarDecl record.
+      DECL_OBJC_IVAR,
+      /// \brief A ObjCAtDefsFieldDecl record.
+      DECL_OBJC_AT_DEFS_FIELD,
+      /// \brief A ObjCCategoryDecl record.
+      DECL_OBJC_CATEGORY,
+      /// \brief A ObjCCategoryImplDecl record.
+      DECL_OBJC_CATEGORY_IMPL,
+      /// \brief A ObjCImplementationDecl record.
+      DECL_OBJC_IMPLEMENTATION,
+      /// \brief A ObjCCompatibleAliasDecl record.
+      DECL_OBJC_COMPATIBLE_ALIAS,
+      /// \brief A ObjCPropertyDecl record.
+      DECL_OBJC_PROPERTY,
+      /// \brief A ObjCPropertyImplDecl record.
+      DECL_OBJC_PROPERTY_IMPL,
+      /// \brief A FieldDecl record.
+      DECL_FIELD,
+      /// \brief A VarDecl record.
+      DECL_VAR,
+      /// \brief An ImplicitParamDecl record.
+      DECL_IMPLICIT_PARAM,
+      /// \brief A ParmVarDecl record.
+      DECL_PARM_VAR,
+      /// \brief A FileScopeAsmDecl record.
+      DECL_FILE_SCOPE_ASM,
+      /// \brief A BlockDecl record.
+      DECL_BLOCK,
+      /// \brief A record that stores the set of declarations that are
+      /// lexically stored within a given DeclContext.
+      ///
+      /// The record itself is a blob that is an array of declaration IDs,
+      /// in the order in which those declarations were added to the
+      /// declaration context. This data is used when iterating over
+      /// the contents of a DeclContext, e.g., via
+      /// DeclContext::decls_begin() and DeclContext::decls_end().
+      DECL_CONTEXT_LEXICAL,
+      /// \brief A record that stores the set of declarations that are
+      /// visible from a given DeclContext.
+      ///
+      /// The record itself stores a set of mappings, each of which
+      /// associates a declaration name with one or more declaration
+      /// IDs. This data is used when performing qualified name lookup
+      /// into a DeclContext via DeclContext::lookup.
+      DECL_CONTEXT_VISIBLE,
+      /// \brief A LabelDecl record.
+      DECL_LABEL,
+      /// \brief A NamespaceDecl record.
+      DECL_NAMESPACE,
+      /// \brief A NamespaceAliasDecl record.
+      DECL_NAMESPACE_ALIAS,
+      /// \brief A UsingDecl record.
+      DECL_USING,
+      /// \brief A UsingShadowDecl record.
+      DECL_USING_SHADOW,
+      /// \brief A UsingDirecitveDecl record.
+      DECL_USING_DIRECTIVE,
+      /// \brief An UnresolvedUsingValueDecl record.
+      DECL_UNRESOLVED_USING_VALUE,
+      /// \brief An UnresolvedUsingTypenameDecl record.
+      DECL_UNRESOLVED_USING_TYPENAME,
+      /// \brief A LinkageSpecDecl record.
+      DECL_LINKAGE_SPEC,
+      /// \brief A CXXRecordDecl record.
+      DECL_CXX_RECORD,
+      /// \brief A CXXMethodDecl record.
+      DECL_CXX_METHOD,
+      /// \brief A CXXConstructorDecl record.
+      DECL_CXX_CONSTRUCTOR,
+      /// \brief A CXXDestructorDecl record.
+      DECL_CXX_DESTRUCTOR,
+      /// \brief A CXXConversionDecl record.
+      DECL_CXX_CONVERSION,
+      /// \brief An AccessSpecDecl record.
+      DECL_ACCESS_SPEC,
+
+      /// \brief A FriendDecl record.
+      DECL_FRIEND,
+      /// \brief A FriendTemplateDecl record.
+      DECL_FRIEND_TEMPLATE,
+      /// \brief A ClassTemplateDecl record.
+      DECL_CLASS_TEMPLATE,
+      /// \brief A ClassTemplateSpecializationDecl record.
+      DECL_CLASS_TEMPLATE_SPECIALIZATION,
+      /// \brief A ClassTemplatePartialSpecializationDecl record.
+      DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+      /// \brief A FunctionTemplateDecl record.
+      DECL_FUNCTION_TEMPLATE,
+      /// \brief A TemplateTypeParmDecl record.
+      DECL_TEMPLATE_TYPE_PARM,
+      /// \brief A NonTypeTemplateParmDecl record.
+      DECL_NON_TYPE_TEMPLATE_PARM,
+      /// \brief A TemplateTemplateParmDecl record.
+      DECL_TEMPLATE_TEMPLATE_PARM,
+      /// \brief A TypeAliasTemplateDecl record.
+      DECL_TYPE_ALIAS_TEMPLATE,
+      /// \brief A StaticAssertDecl record.
+      DECL_STATIC_ASSERT,
+      /// \brief A record containing CXXBaseSpecifiers.
+      DECL_CXX_BASE_SPECIFIERS,
+      /// \brief A IndirectFieldDecl record.
+      DECL_INDIRECTFIELD,
+      /// \brief A NonTypeTemplateParmDecl record that stores an expanded
+      /// non-type template parameter pack.
+      DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK,
+      /// \brief A TemplateTemplateParmDecl record that stores an expanded
+      /// template template parameter pack.
+      DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
+      /// \brief A ClassScopeFunctionSpecializationDecl record a class scope
+      /// function specialization. (Microsoft extension).
+      DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
+      /// \brief An ImportDecl recording a module import.
+      DECL_IMPORT
+    };
+
+    /// \brief Record codes for each kind of statement or expression.
+    ///
+    /// These constants describe the records that describe statements
+    /// or expressions. These records  occur within type and declarations
+    /// block, so they begin with record values of 100.  Each constant 
+    /// describes a record for a specific statement or expression class in the
+    /// AST.
+    enum StmtCode {
+      /// \brief A marker record that indicates that we are at the end
+      /// of an expression.
+      STMT_STOP = 100,
+      /// \brief A NULL expression.
+      STMT_NULL_PTR,
+      /// \brief A reference to a previously [de]serialized Stmt record.
+      STMT_REF_PTR,
+      /// \brief A NullStmt record.
+      STMT_NULL,
+      /// \brief A CompoundStmt record.
+      STMT_COMPOUND,
+      /// \brief A CaseStmt record.
+      STMT_CASE,
+      /// \brief A DefaultStmt record.
+      STMT_DEFAULT,
+      /// \brief A LabelStmt record.
+      STMT_LABEL,
+      /// \brief An AttributedStmt record.
+      STMT_ATTRIBUTED,
+      /// \brief An IfStmt record.
+      STMT_IF,
+      /// \brief A SwitchStmt record.
+      STMT_SWITCH,
+      /// \brief A WhileStmt record.
+      STMT_WHILE,
+      /// \brief A DoStmt record.
+      STMT_DO,
+      /// \brief A ForStmt record.
+      STMT_FOR,
+      /// \brief A GotoStmt record.
+      STMT_GOTO,
+      /// \brief An IndirectGotoStmt record.
+      STMT_INDIRECT_GOTO,
+      /// \brief A ContinueStmt record.
+      STMT_CONTINUE,
+      /// \brief A BreakStmt record.
+      STMT_BREAK,
+      /// \brief A ReturnStmt record.
+      STMT_RETURN,
+      /// \brief A DeclStmt record.
+      STMT_DECL,
+      /// \brief A GCC-style AsmStmt record.
+      STMT_GCCASM,
+      /// \brief A MS-style AsmStmt record.
+      STMT_MSASM,
+      /// \brief A PredefinedExpr record.
+      EXPR_PREDEFINED,
+      /// \brief A DeclRefExpr record.
+      EXPR_DECL_REF,
+      /// \brief An IntegerLiteral record.
+      EXPR_INTEGER_LITERAL,
+      /// \brief A FloatingLiteral record.
+      EXPR_FLOATING_LITERAL,
+      /// \brief An ImaginaryLiteral record.
+      EXPR_IMAGINARY_LITERAL,
+      /// \brief A StringLiteral record.
+      EXPR_STRING_LITERAL,
+      /// \brief A CharacterLiteral record.
+      EXPR_CHARACTER_LITERAL,
+      /// \brief A ParenExpr record.
+      EXPR_PAREN,
+      /// \brief A ParenListExpr record.
+      EXPR_PAREN_LIST,
+      /// \brief A UnaryOperator record.
+      EXPR_UNARY_OPERATOR,
+      /// \brief An OffsetOfExpr record.
+      EXPR_OFFSETOF,
+      /// \brief A SizefAlignOfExpr record.
+      EXPR_SIZEOF_ALIGN_OF,
+      /// \brief An ArraySubscriptExpr record.
+      EXPR_ARRAY_SUBSCRIPT,
+      /// \brief A CallExpr record.
+      EXPR_CALL,
+      /// \brief A MemberExpr record.
+      EXPR_MEMBER,
+      /// \brief A BinaryOperator record.
+      EXPR_BINARY_OPERATOR,
+      /// \brief A CompoundAssignOperator record.
+      EXPR_COMPOUND_ASSIGN_OPERATOR,
+      /// \brief A ConditionOperator record.
+      EXPR_CONDITIONAL_OPERATOR,
+      /// \brief An ImplicitCastExpr record.
+      EXPR_IMPLICIT_CAST,
+      /// \brief A CStyleCastExpr record.
+      EXPR_CSTYLE_CAST,
+      /// \brief A CompoundLiteralExpr record.
+      EXPR_COMPOUND_LITERAL,
+      /// \brief An ExtVectorElementExpr record.
+      EXPR_EXT_VECTOR_ELEMENT,
+      /// \brief An InitListExpr record.
+      EXPR_INIT_LIST,
+      /// \brief A DesignatedInitExpr record.
+      EXPR_DESIGNATED_INIT,
+      /// \brief An ImplicitValueInitExpr record.
+      EXPR_IMPLICIT_VALUE_INIT,
+      /// \brief A VAArgExpr record.
+      EXPR_VA_ARG,
+      /// \brief An AddrLabelExpr record.
+      EXPR_ADDR_LABEL,
+      /// \brief A StmtExpr record.
+      EXPR_STMT,
+      /// \brief A ChooseExpr record.
+      EXPR_CHOOSE,
+      /// \brief A GNUNullExpr record.
+      EXPR_GNU_NULL,
+      /// \brief A ShuffleVectorExpr record.
+      EXPR_SHUFFLE_VECTOR,
+      /// \brief BlockExpr
+      EXPR_BLOCK,
+      /// \brief A GenericSelectionExpr record.
+      EXPR_GENERIC_SELECTION,
+      /// \brief A PseudoObjectExpr record.
+      EXPR_PSEUDO_OBJECT,
+      /// \brief An AtomicExpr record.
+      EXPR_ATOMIC,
+
+      // Objective-C
+
+      /// \brief An ObjCStringLiteral record.
+      EXPR_OBJC_STRING_LITERAL,
+
+      EXPR_OBJC_BOXED_EXPRESSION,
+      EXPR_OBJC_ARRAY_LITERAL,
+      EXPR_OBJC_DICTIONARY_LITERAL,
+
+    
+      /// \brief An ObjCEncodeExpr record.
+      EXPR_OBJC_ENCODE,
+      /// \brief An ObjCSelectorExpr record.
+      EXPR_OBJC_SELECTOR_EXPR,
+      /// \brief An ObjCProtocolExpr record.
+      EXPR_OBJC_PROTOCOL_EXPR,
+      /// \brief An ObjCIvarRefExpr record.
+      EXPR_OBJC_IVAR_REF_EXPR,
+      /// \brief An ObjCPropertyRefExpr record.
+      EXPR_OBJC_PROPERTY_REF_EXPR,
+      /// \brief An ObjCSubscriptRefExpr record.
+      EXPR_OBJC_SUBSCRIPT_REF_EXPR,
+      /// \brief UNUSED
+      EXPR_OBJC_KVC_REF_EXPR,
+      /// \brief An ObjCMessageExpr record.
+      EXPR_OBJC_MESSAGE_EXPR,
+      /// \brief An ObjCIsa Expr record.
+      EXPR_OBJC_ISA,
+      /// \brief An ObjCIndirectCopyRestoreExpr record.
+      EXPR_OBJC_INDIRECT_COPY_RESTORE,
+
+      /// \brief An ObjCForCollectionStmt record.
+      STMT_OBJC_FOR_COLLECTION,
+      /// \brief An ObjCAtCatchStmt record.
+      STMT_OBJC_CATCH,
+      /// \brief An ObjCAtFinallyStmt record.
+      STMT_OBJC_FINALLY,
+      /// \brief An ObjCAtTryStmt record.
+      STMT_OBJC_AT_TRY,
+      /// \brief An ObjCAtSynchronizedStmt record.
+      STMT_OBJC_AT_SYNCHRONIZED,
+      /// \brief An ObjCAtThrowStmt record.
+      STMT_OBJC_AT_THROW,
+      /// \brief An ObjCAutoreleasePoolStmt record.
+      STMT_OBJC_AUTORELEASE_POOL,
+      /// \brief A ObjCBoolLiteralExpr record.
+      EXPR_OBJC_BOOL_LITERAL,
+
+      // C++
+      
+      /// \brief A CXXCatchStmt record.
+      STMT_CXX_CATCH,
+      /// \brief A CXXTryStmt record.
+      STMT_CXX_TRY,
+      /// \brief A CXXForRangeStmt record.
+      STMT_CXX_FOR_RANGE,
+
+      /// \brief A CXXOperatorCallExpr record.
+      EXPR_CXX_OPERATOR_CALL,
+      /// \brief A CXXMemberCallExpr record.
+      EXPR_CXX_MEMBER_CALL,
+      /// \brief A CXXConstructExpr record.
+      EXPR_CXX_CONSTRUCT,
+      /// \brief A CXXTemporaryObjectExpr record.
+      EXPR_CXX_TEMPORARY_OBJECT,
+      /// \brief A CXXStaticCastExpr record.
+      EXPR_CXX_STATIC_CAST,
+      /// \brief A CXXDynamicCastExpr record.
+      EXPR_CXX_DYNAMIC_CAST,
+      /// \brief A CXXReinterpretCastExpr record.
+      EXPR_CXX_REINTERPRET_CAST,
+      /// \brief A CXXConstCastExpr record.
+      EXPR_CXX_CONST_CAST,
+      /// \brief A CXXFunctionalCastExpr record.
+      EXPR_CXX_FUNCTIONAL_CAST,
+      /// \brief A UserDefinedLiteral record.
+      EXPR_USER_DEFINED_LITERAL,
+      /// \brief A CXXBoolLiteralExpr record.
+      EXPR_CXX_BOOL_LITERAL,
+      EXPR_CXX_NULL_PTR_LITERAL,  // CXXNullPtrLiteralExpr
+      EXPR_CXX_TYPEID_EXPR,       // CXXTypeidExpr (of expr).
+      EXPR_CXX_TYPEID_TYPE,       // CXXTypeidExpr (of type).
+      EXPR_CXX_THIS,              // CXXThisExpr
+      EXPR_CXX_THROW,             // CXXThrowExpr
+      EXPR_CXX_DEFAULT_ARG,       // CXXDefaultArgExpr
+      EXPR_CXX_BIND_TEMPORARY,    // CXXBindTemporaryExpr
+
+      EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
+      EXPR_CXX_NEW,               // CXXNewExpr
+      EXPR_CXX_DELETE,            // CXXDeleteExpr
+      EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
+      
+      EXPR_EXPR_WITH_CLEANUPS,    // ExprWithCleanups
+      
+      EXPR_CXX_DEPENDENT_SCOPE_MEMBER,   // CXXDependentScopeMemberExpr
+      EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr
+      EXPR_CXX_UNRESOLVED_CONSTRUCT,     // CXXUnresolvedConstructExpr
+      EXPR_CXX_UNRESOLVED_MEMBER,        // UnresolvedMemberExpr
+      EXPR_CXX_UNRESOLVED_LOOKUP,        // UnresolvedLookupExpr
+
+      EXPR_CXX_UNARY_TYPE_TRAIT,  // UnaryTypeTraitExpr
+      EXPR_CXX_EXPRESSION_TRAIT,  // ExpressionTraitExpr
+      EXPR_CXX_NOEXCEPT,          // CXXNoexceptExpr
+
+      EXPR_OPAQUE_VALUE,          // OpaqueValueExpr
+      EXPR_BINARY_CONDITIONAL_OPERATOR,  // BinaryConditionalOperator
+      EXPR_BINARY_TYPE_TRAIT,     // BinaryTypeTraitExpr
+      EXPR_TYPE_TRAIT,            // TypeTraitExpr
+      EXPR_ARRAY_TYPE_TRAIT,      // ArrayTypeTraitIntExpr
+      
+      EXPR_PACK_EXPANSION,        // PackExpansionExpr
+      EXPR_SIZEOF_PACK,           // SizeOfPackExpr
+      EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr
+      EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr
+      EXPR_FUNCTION_PARM_PACK,    // FunctionParmPackExpr
+      EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
+      
+      // CUDA
+      EXPR_CUDA_KERNEL_CALL,       // CUDAKernelCallExpr      
+
+      // OpenCL
+      EXPR_ASTYPE,                 // AsTypeExpr
+
+      // Microsoft
+      EXPR_CXX_UUIDOF_EXPR,       // CXXUuidofExpr (of expr).
+      EXPR_CXX_UUIDOF_TYPE,       // CXXUuidofExpr (of type).
+      STMT_SEH_EXCEPT,            // SEHExceptStmt
+      STMT_SEH_FINALLY,           // SEHFinallyStmt
+      STMT_SEH_TRY,               // SEHTryStmt
+      
+      // ARC
+      EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
+      
+      STMT_MS_DEPENDENT_EXISTS,   // MSDependentExistsStmt
+      EXPR_LAMBDA                 // LambdaExpr
+    };
+
+    /// \brief The kinds of designators that can occur in a
+    /// DesignatedInitExpr.
+    enum DesignatorTypes {
+      /// \brief Field designator where only the field name is known.
+      DESIG_FIELD_NAME  = 0,
+      /// \brief Field designator where the field has been resolved to
+      /// a declaration.
+      DESIG_FIELD_DECL  = 1,
+      /// \brief Array designator.
+      DESIG_ARRAY       = 2,
+      /// \brief GNU array range designator.
+      DESIG_ARRAY_RANGE = 3
+    };
+
+    /// \brief The different kinds of data that can occur in a
+    /// CtorInitializer.
+    enum CtorInitializerType {
+      CTOR_INITIALIZER_BASE,
+      CTOR_INITIALIZER_DELEGATING,
+      CTOR_INITIALIZER_MEMBER,
+      CTOR_INITIALIZER_INDIRECT_MEMBER
+    };
+
+    /// \brief Describes the redeclarations of a declaration.
+    struct LocalRedeclarationsInfo {
+      DeclID FirstID;      // The ID of the first declaration
+      unsigned Offset;     // Offset into the array of redeclaration chains.
+      
+      friend bool operator<(const LocalRedeclarationsInfo &X,
+                            const LocalRedeclarationsInfo &Y) {
+        return X.FirstID < Y.FirstID;
+      }
+      
+      friend bool operator>(const LocalRedeclarationsInfo &X,
+                            const LocalRedeclarationsInfo &Y) {
+        return X.FirstID > Y.FirstID;
+      }
+      
+      friend bool operator<=(const LocalRedeclarationsInfo &X,
+                             const LocalRedeclarationsInfo &Y) {
+        return X.FirstID <= Y.FirstID;
+      }
+      
+      friend bool operator>=(const LocalRedeclarationsInfo &X,
+                             const LocalRedeclarationsInfo &Y) {
+        return X.FirstID >= Y.FirstID;
+      }
+    };
+
+    /// \brief Describes the categories of an Objective-C class.
+    struct ObjCCategoriesInfo {
+      DeclID DefinitionID; // The ID of the definition
+      unsigned Offset;     // Offset into the array of category lists.
+      
+      friend bool operator<(const ObjCCategoriesInfo &X,
+                            const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID < Y.DefinitionID;
+      }
+      
+      friend bool operator>(const ObjCCategoriesInfo &X,
+                            const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID > Y.DefinitionID;
+      }
+      
+      friend bool operator<=(const ObjCCategoriesInfo &X,
+                             const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID <= Y.DefinitionID;
+      }
+      
+      friend bool operator>=(const ObjCCategoriesInfo &X,
+                             const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID >= Y.DefinitionID;
+      }
+    };
+
+    /// @}
+  }
+} // end namespace clang
+
+#endif
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index b04b830..f3fa135 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -874,15 +874,6 @@
   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() ?
@@ -1421,16 +1412,6 @@
       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 65907f9..566a389 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1,3580 +1,3574 @@
-//===--- 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);
-}
+//===--- 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);
+}
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index a8737e7..0da7f51 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -1,1725 +1,1718 @@
-//===--- 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);
-}
+//===--- 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);
+}
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index 6218da2..0837509 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -1,420 +1,414 @@
-//===--- 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;
-}
+//===--- 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;
+}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 26eee2d..97448ee 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1512,12 +1512,6 @@
   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 b86d226..c021cf8 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -1,367 +1,361 @@
-//===--- 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;
-    }
-  }
-}
+//===--- 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;
+    }
+  }
+}
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index c16081f..844514b 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1,2834 +1,2802 @@
-//===--- 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();
-}
+//===--- 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();
+}
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 5a3b122..cb9ce8b 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -1,330 +1,325 @@
-//===--- 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
+//===--- 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
diff --git a/lib/CodeGen/CGOpenCLRuntime.cpp b/lib/CodeGen/CGOpenCLRuntime.cpp
index 61d6286..3a0e116 100644
--- a/lib/CodeGen/CGOpenCLRuntime.cpp
+++ b/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -1,59 +1,28 @@
-//===----- 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);
-  }
-}
+//===----- 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);
+}
diff --git a/lib/CodeGen/CGOpenCLRuntime.h b/lib/CodeGen/CGOpenCLRuntime.h
index 7b33951..9a8430f 100644
--- a/lib/CodeGen/CGOpenCLRuntime.h
+++ b/lib/CodeGen/CGOpenCLRuntime.h
@@ -1,52 +1,46 @@
-//===----- 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
+//===----- 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
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index 0a1fb4b..53716a0 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -1,1017 +1,1011 @@
-//===--- 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]);
-}
+//===--- 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]);
+}
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 8cb6dd0..a0effa8 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -14,7 +14,6 @@
 #include "CodeGenTypes.h"
 #include "CGCXXABI.h"
 #include "CGCall.h"
-#include "CGOpenCLRuntime.h"
 #include "CGRecordLayout.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -367,15 +366,6 @@
     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 390fd34..518c8a07 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2753,30 +2753,6 @@
     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);
@@ -3620,14 +3596,6 @@
   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:
@@ -3700,14 +3668,6 @@
   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:
@@ -3852,14 +3812,6 @@
   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 b7705f8..14980ee 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1078,13 +1078,7 @@
   case tok::kw_void:
   case tok::kw_typename:
   case tok::kw_typeof:
-  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: {
+  case tok::kw___vector: {
     if (!getLangOpts().CPlusPlus) {
       Diag(Tok, diag::err_expected_expression);
       return ExprError();
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index e411899..b26181f 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -1,1580 +1,1574 @@
-//===--- 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();
-}
+//===--- 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();
+}
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index b34b953..040e638 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -280,12 +280,6 @@
     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:
@@ -420,12 +414,6 @@
   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 6c70320..f797825 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -731,12 +731,6 @@
   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 1afc8c7..2c7b7c1 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -903,30 +903,6 @@
     }
     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 91eec73..aec8a81 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -1,86 +1,80 @@
-//===--- 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;
-}
+//===--- 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;
+}
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 88b5614..c0976ee 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1,6998 +1,6992 @@
-//===--- 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;
-  }
-}
+//===--- 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;
+  }
+}
diff --git a/test/CodeGenOpenCL/opencl_types.cl b/test/CodeGenOpenCL/opencl_types.cl
deleted file mode 100644
index 5bebc5e..0000000
--- a/test/CodeGenOpenCL/opencl_types.cl
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 | FileCheck %s
-
-void fnc1(image1d_t img) {}
-// CHECK: @fnc1(%opencl.image1d_t*
-
-void fnc1arr(image1d_array_t img) {}
-// CHECK: @fnc1arr(%opencl.image1d_array_t*
-
-void fnc1buff(image1d_buffer_t img) {}
-// CHECK: @fnc1buff(%opencl.image1d_buffer_t*
-
-void fnc2(image2d_t img) {}
-// CHECK: @fnc2(%opencl.image2d_t*
-
-void fnc2arr(image2d_array_t img) {}
-// CHECK: @fnc2arr(%opencl.image2d_array_t*
-
-void fnc3(image3d_t img) {}
-// CHECK: @fnc3(%opencl.image3d_t*
-
-kernel void foo(image1d_t img) {
-}
diff --git a/test/PCH/ocl_types.cl b/test/PCH/ocl_types.cl
deleted file mode 100644
index d5c4428..0000000
--- a/test/PCH/ocl_types.cl
+++ /dev/null
@@ -1,18 +0,0 @@
-// Test this without pch.
-// RUN: %clang_cc1 -include %S/ocl_types.h -fsyntax-only %s
-
-// Test with pch.
-// RUN: %clang_cc1 -x cl -emit-pch -o %t %S/ocl_types.h
-// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s -ast-print
-
-void foo1(img1d_t img);
-
-void foo2(img1darr_t img);
-
-void foo3(img1dbuff_t img);
-
-void foo4(img2d_t img);
-
-void foo5(img2darr_t img);
-
-void foo6(img3d_t img);
diff --git a/test/PCH/ocl_types.h b/test/PCH/ocl_types.h
deleted file mode 100644
index 6afa016..0000000
--- a/test/PCH/ocl_types.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Used with the ocl_types.cl test */
-
-// image1d_t
-typedef image1d_t img1d_t;
-
-// image1d_array_t
-typedef image1d_array_t img1darr_t;
-
-// image1d_buffer_t
-typedef image1d_buffer_t img1dbuff_t;
-
-// image2d_t
-typedef image2d_t img2d_t;
-
-// image2d_array_t
-typedef image2d_array_t img2darr_t;
-
-// image3d_t
-typedef image3d_t img3d_t;
diff --git a/test/Parser/opencl-image-access.cl b/test/Parser/opencl-image-access.cl
index 3496d12..313587c 100644
--- a/test/Parser/opencl-image-access.cl
+++ b/test/Parser/opencl-image-access.cl
@@ -1,14 +1,16 @@
-// RUN: %clang_cc1 %s -fsyntax-only
-
-__kernel void f__ro(__read_only image2d_t a) { }
-
-__kernel void f__wo(__write_only image2d_t a) { }
-
-__kernel void f__rw(__read_write image2d_t a) { }
-
-
-__kernel void fro(read_only image2d_t a) { }
-
-__kernel void fwo(write_only image2d_t a) { }
-
-__kernel void frw(read_write image2d_t a) { }
+// RUN: %clang_cc1 %s -fsyntax-only
+
+typedef void* image2d_t;
+
+__kernel void f__ro(__read_only image2d_t a) { }
+
+__kernel void f__wo(__write_only image2d_t a) { }
+
+__kernel void f__rw(__read_write image2d_t a) { }
+
+
+__kernel void fro(read_only image2d_t a) { }
+
+__kernel void fwo(write_only image2d_t a) { }
+
+__kernel void frw(read_write image2d_t a) { }
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index c28c181..1fb9a70 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1,6175 +1,6169 @@
-//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
-//
-//                     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 main API hooks in the Clang-C Source Indexing
-// library.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CIndexer.h"
-#include "CIndexDiagnostic.h"
-#include "CXComment.h"
-#include "CXCursor.h"
-#include "CXSourceLocation.h"
-#include "CXString.h"
-#include "CXTranslationUnit.h"
-#include "CXType.h"
-#include "CursorVisitor.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/Version.h"
-#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/CrashRecoveryContext.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Program.h"
-#include "llvm/Support/SaveAndRestore.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/Support/Threading.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace clang::cxcursor;
-using namespace clang::cxstring;
-using namespace clang::cxtu;
-using namespace clang::cxindex;
-
-CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU) {
-  if (!TU)
-    return 0;
-  CXTranslationUnit D = new CXTranslationUnitImpl();
-  D->CIdx = CIdx;
-  D->TUData = TU;
-  D->StringPool = createCXStringPool();
-  D->Diagnostics = 0;
-  D->OverridenCursorsPool = createOverridenCXCursorsPool();
-  return D;
-}
-
-cxtu::CXTUOwner::~CXTUOwner() {
-  if (TU)
-    clang_disposeTranslationUnit(TU);
-}
-
-/// \brief Compare two source ranges to determine their relative position in
-/// the translation unit.
-static RangeComparisonResult RangeCompare(SourceManager &SM,
-                                          SourceRange R1,
-                                          SourceRange R2) {
-  assert(R1.isValid() && "First range is invalid?");
-  assert(R2.isValid() && "Second range is invalid?");
-  if (R1.getEnd() != R2.getBegin() &&
-      SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
-    return RangeBefore;
-  if (R2.getEnd() != R1.getBegin() &&
-      SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
-    return RangeAfter;
-  return RangeOverlap;
-}
-
-/// \brief Determine if a source location falls within, before, or after a
-///   a given source range.
-static RangeComparisonResult LocationCompare(SourceManager &SM,
-                                             SourceLocation L, SourceRange R) {
-  assert(R.isValid() && "First range is invalid?");
-  assert(L.isValid() && "Second range is invalid?");
-  if (L == R.getBegin() || L == R.getEnd())
-    return RangeOverlap;
-  if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
-    return RangeBefore;
-  if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
-    return RangeAfter;
-  return RangeOverlap;
-}
-
-/// \brief Translate a Clang source range into a CIndex source range.
-///
-/// Clang internally represents ranges where the end location points to the
-/// start of the token at the end. However, for external clients it is more
-/// useful to have a CXSourceRange be a proper half-open interval. This routine
-/// does the appropriate translation.
-CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
-                                          const LangOptions &LangOpts,
-                                          const CharSourceRange &R) {
-  // We want the last character in this location, so we will adjust the
-  // location accordingly.
-  SourceLocation EndLoc = R.getEnd();
-  if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
-    EndLoc = SM.getExpansionRange(EndLoc).second;
-  if (R.isTokenRange() && !EndLoc.isInvalid()) {
-    unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
-                                                SM, LangOpts);
-    EndLoc = EndLoc.getLocWithOffset(Length);
-  }
-
-  CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
-                           R.getBegin().getRawEncoding(),
-                           EndLoc.getRawEncoding() };
-  return Result;
-}
-
-//===----------------------------------------------------------------------===//
-// Cursor visitor.
-//===----------------------------------------------------------------------===//
-
-static SourceRange getRawCursorExtent(CXCursor C);
-static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
-
-
-RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
-  return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
-}
-
-/// \brief Visit the given cursor and, if requested by the visitor,
-/// its children.
-///
-/// \param Cursor the cursor to visit.
-///
-/// \param CheckedRegionOfInterest if true, then the caller already checked
-/// that this cursor is within the region of interest.
-///
-/// \returns true if the visitation should be aborted, false if it
-/// should continue.
-bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
-  if (clang_isInvalid(Cursor.kind))
-    return false;
-
-  if (clang_isDeclaration(Cursor.kind)) {
-    Decl *D = getCursorDecl(Cursor);
-    if (!D) {
-      assert(0 && "Invalid declaration cursor");
-      return true; // abort.
-    }
-    
-    // Ignore implicit declarations, unless it's an objc method because
-    // currently we should report implicit methods for properties when indexing.
-    if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
-      return false;
-  }
-
-  // If we have a range of interest, and this cursor doesn't intersect with it,
-  // we're done.
-  if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
-    SourceRange Range = getRawCursorExtent(Cursor);
-    if (Range.isInvalid() || CompareRegionOfInterest(Range))
-      return false;
-  }
-
-  switch (Visitor(Cursor, Parent, ClientData)) {
-  case CXChildVisit_Break:
-    return true;
-
-  case CXChildVisit_Continue:
-    return false;
-
-  case CXChildVisit_Recurse: {
-    bool ret = VisitChildren(Cursor);
-    if (PostChildrenVisitor)
-      if (PostChildrenVisitor(Cursor, ClientData))
-        return true;
-    return ret;
-  }
-  }
-
-  llvm_unreachable("Invalid CXChildVisitResult!");
-}
-
-static bool visitPreprocessedEntitiesInRange(SourceRange R,
-                                             PreprocessingRecord &PPRec,
-                                             CursorVisitor &Visitor) {
-  SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
-  FileID FID;
-  
-  if (!Visitor.shouldVisitIncludedEntities()) {
-    // If the begin/end of the range lie in the same FileID, do the optimization
-    // where we skip preprocessed entities that do not come from the same FileID.
-    FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
-    if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
-      FID = FileID();
-  }
-
-  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
-    Entities = PPRec.getPreprocessedEntitiesInRange(R);
-  return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
-                                           PPRec, FID);
-}
-
-void CursorVisitor::visitFileRegion() {
-  if (RegionOfInterest.isInvalid())
-    return;
-
-  ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
-  SourceManager &SM = Unit->getSourceManager();
-  
-  std::pair<FileID, unsigned>
-    Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())), 
-    End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd())); 
-
-  if (End.first != Begin.first) {
-    // If the end does not reside in the same file, try to recover by
-    // picking the end of the file of begin location.
-    End.first = Begin.first;
-    End.second = SM.getFileIDSize(Begin.first);
-  }
-
-  assert(Begin.first == End.first);
-  if (Begin.second > End.second)
-    return;
-  
-  FileID File = Begin.first;
-  unsigned Offset = Begin.second;
-  unsigned Length = End.second - Begin.second;
-
-  if (!VisitDeclsOnly && !VisitPreprocessorLast)
-    if (visitPreprocessedEntitiesInRegion())
-      return; // visitation break.
-
-  visitDeclsFromFileRegion(File, Offset, Length);
-
-  if (!VisitDeclsOnly && VisitPreprocessorLast)
-    visitPreprocessedEntitiesInRegion();
-}
-
-static bool isInLexicalContext(Decl *D, DeclContext *DC) {
-  if (!DC)
-    return false;
-
-  for (DeclContext *DeclDC = D->getLexicalDeclContext();
-         DeclDC; DeclDC = DeclDC->getLexicalParent()) {
-    if (DeclDC == DC)
-      return true;
-  }
-  return false;
-}
-
-void CursorVisitor::visitDeclsFromFileRegion(FileID File,
-                                             unsigned Offset, unsigned Length) {
-  ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
-  SourceManager &SM = Unit->getSourceManager();
-  SourceRange Range = RegionOfInterest;
-
-  SmallVector<Decl *, 16> Decls;
-  Unit->findFileRegionDecls(File, Offset, Length, Decls);
-
-  // If we didn't find any file level decls for the file, try looking at the
-  // file that it was included from.
-  while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
-    bool Invalid = false;
-    const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
-    if (Invalid)
-      return;
-
-    SourceLocation Outer;
-    if (SLEntry.isFile())
-      Outer = SLEntry.getFile().getIncludeLoc();
-    else
-      Outer = SLEntry.getExpansion().getExpansionLocStart();
-    if (Outer.isInvalid())
-      return;
-
-    llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
-    Length = 0;
-    Unit->findFileRegionDecls(File, Offset, Length, Decls);
-  }
-
-  assert(!Decls.empty());
-
-  bool VisitedAtLeastOnce = false;
-  DeclContext *CurDC = 0;
-  SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
-  for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
-    Decl *D = *DIt;
-    if (D->getSourceRange().isInvalid())
-      continue;
-
-    if (isInLexicalContext(D, CurDC))
-      continue;
-
-    CurDC = dyn_cast<DeclContext>(D);
-
-    if (TagDecl *TD = dyn_cast<TagDecl>(D))
-      if (!TD->isFreeStanding())
-        continue;
-
-    RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
-    if (CompRes == RangeBefore)
-      continue;
-    if (CompRes == RangeAfter)
-      break;
-
-    assert(CompRes == RangeOverlap);
-    VisitedAtLeastOnce = true;
-
-    if (isa<ObjCContainerDecl>(D)) {
-      FileDI_current = &DIt;
-      FileDE_current = DE;
-    } else {
-      FileDI_current = 0;
-    }
-
-    if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
-      break;
-  }
-
-  if (VisitedAtLeastOnce)
-    return;
-
-  // No Decls overlapped with the range. Move up the lexical context until there
-  // is a context that contains the range or we reach the translation unit
-  // level.
-  DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
-                                         : (*(DIt-1))->getLexicalDeclContext();
-
-  while (DC && !DC->isTranslationUnit()) {
-    Decl *D = cast<Decl>(DC);
-    SourceRange CurDeclRange = D->getSourceRange();
-    if (CurDeclRange.isInvalid())
-      break;
-
-    if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
-      Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true);
-      break;
-    }
-
-    DC = D->getLexicalDeclContext();
-  }
-}
-
-bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
-  if (!AU->getPreprocessor().getPreprocessingRecord())
-    return false;
-
-  PreprocessingRecord &PPRec
-    = *AU->getPreprocessor().getPreprocessingRecord();
-  SourceManager &SM = AU->getSourceManager();
-  
-  if (RegionOfInterest.isValid()) {
-    SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
-    SourceLocation B = MappedRange.getBegin();
-    SourceLocation E = MappedRange.getEnd();
-
-    if (AU->isInPreambleFileID(B)) {
-      if (SM.isLoadedSourceLocation(E))
-        return visitPreprocessedEntitiesInRange(SourceRange(B, E),
-                                                 PPRec, *this);
-
-      // Beginning of range lies in the preamble but it also extends beyond
-      // it into the main file. Split the range into 2 parts, one covering
-      // the preamble and another covering the main file. This allows subsequent
-      // calls to visitPreprocessedEntitiesInRange to accept a source range that
-      // lies in the same FileID, allowing it to skip preprocessed entities that
-      // do not come from the same FileID.
-      bool breaked =
-        visitPreprocessedEntitiesInRange(
-                                   SourceRange(B, AU->getEndOfPreambleFileID()),
-                                          PPRec, *this);
-      if (breaked) return true;
-      return visitPreprocessedEntitiesInRange(
-                                    SourceRange(AU->getStartOfMainFileID(), E),
-                                        PPRec, *this);
-    }
-
-    return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
-  }
-
-  bool OnlyLocalDecls
-    = !AU->isMainFileAST() && AU->getOnlyLocalDecls(); 
-  
-  if (OnlyLocalDecls)
-    return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
-                                     PPRec);
-
-  return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
-}
-
-template<typename InputIterator>
-bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
-                                              InputIterator Last,
-                                              PreprocessingRecord &PPRec,
-                                              FileID FID) {
-  for (; First != Last; ++First) {
-    if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
-      continue;
-
-    PreprocessedEntity *PPE = *First;
-    if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
-      if (Visit(MakeMacroExpansionCursor(ME, TU)))
-        return true;
-      
-      continue;
-    }
-    
-    if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
-      if (Visit(MakeMacroDefinitionCursor(MD, TU)))
-        return true;
-      
-      continue;
-    }
-    
-    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
-      if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
-        return true;
-      
-      continue;
-    }
-  }
-
-  return false;
-}
-
-/// \brief Visit the children of the given cursor.
-/// 
-/// \returns true if the visitation should be aborted, false if it
-/// should continue.
-bool CursorVisitor::VisitChildren(CXCursor Cursor) {
-  if (clang_isReference(Cursor.kind) && 
-      Cursor.kind != CXCursor_CXXBaseSpecifier) {
-    // By definition, references have no children.
-    return false;
-  }
-
-  // Set the Parent field to Cursor, then back to its old value once we're
-  // done.
-  SetParentRAII SetParent(Parent, StmtParent, Cursor);
-
-  if (clang_isDeclaration(Cursor.kind)) {
-    Decl *D = getCursorDecl(Cursor);
-    if (!D)
-      return false;
-
-    return VisitAttributes(D) || Visit(D);
-  }
-
-  if (clang_isStatement(Cursor.kind)) {
-    if (Stmt *S = getCursorStmt(Cursor))
-      return Visit(S);
-
-    return false;
-  }
-
-  if (clang_isExpression(Cursor.kind)) {
-    if (Expr *E = getCursorExpr(Cursor))
-      return Visit(E);
-
-    return false;
-  }
-
-  if (clang_isTranslationUnit(Cursor.kind)) {
-    CXTranslationUnit tu = getCursorTU(Cursor);
-    ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
-    
-    int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
-    for (unsigned I = 0; I != 2; ++I) {
-      if (VisitOrder[I]) {
-        if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
-            RegionOfInterest.isInvalid()) {
-          for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
-                                        TLEnd = CXXUnit->top_level_end();
-               TL != TLEnd; ++TL) {
-            if (Visit(MakeCXCursor(*TL, tu, RegionOfInterest), true))
-              return true;
-          }
-        } else if (VisitDeclContext(
-                                CXXUnit->getASTContext().getTranslationUnitDecl()))
-          return true;
-        continue;
-      }
-
-      // Walk the preprocessing record.
-      if (CXXUnit->getPreprocessor().getPreprocessingRecord())
-        visitPreprocessedEntitiesInRegion();
-    }
-    
-    return false;
-  }
-
-  if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
-    if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
-      if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
-        return Visit(BaseTSInfo->getTypeLoc());
-      }
-    }
-  }
-
-  if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
-    IBOutletCollectionAttr *A =
-      cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
-    if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
-      return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
-                                                    A->getInterfaceLoc(), TU));
-  }
-
-  // Nothing to visit at the moment.
-  return false;
-}
-
-bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
-  if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
-    if (Visit(TSInfo->getTypeLoc()))
-        return true;
-
-  if (Stmt *Body = B->getBody())
-    return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
-
-  return false;
-}
-
-llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
-  if (RegionOfInterest.isValid()) {
-    SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
-    if (Range.isInvalid())
-      return llvm::Optional<bool>();
-    
-    switch (CompareRegionOfInterest(Range)) {
-    case RangeBefore:
-      // This declaration comes before the region of interest; skip it.
-      return llvm::Optional<bool>();
-
-    case RangeAfter:
-      // This declaration comes after the region of interest; we're done.
-      return false;
-
-    case RangeOverlap:
-      // This declaration overlaps the region of interest; visit it.
-      break;
-    }
-  }
-  return true;
-}
-
-bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
-  DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
-
-  // FIXME: Eventually remove.  This part of a hack to support proper
-  // iteration over all Decls contained lexically within an ObjC container.
-  SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
-  SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
-
-  for ( ; I != E; ++I) {
-    Decl *D = *I;
-    if (D->getLexicalDeclContext() != DC)
-      continue;
-    CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
-
-    // Ignore synthesized ivars here, otherwise if we have something like:
-    //   @synthesize prop = _prop;
-    // and '_prop' is not declared, we will encounter a '_prop' ivar before
-    // encountering the 'prop' synthesize declaration and we will think that
-    // we passed the region-of-interest.
-    if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
-      if (ivarD->getSynthesize())
-        continue;
-    }
-
-    // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
-    // declarations is a mismatch with the compiler semantics.
-    if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
-      ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
-      if (!ID->isThisDeclarationADefinition())
-        Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
-
-    } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
-      ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
-      if (!PD->isThisDeclarationADefinition())
-        Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
-    }
-
-    const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
-    if (!V.hasValue())
-      continue;
-    if (!V.getValue())
-      return false;
-    if (Visit(Cursor, true))
-      return true;
-  }
-  return false;
-}
-
-bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
-  llvm_unreachable("Translation units are visited directly by Visit()");
-}
-
-bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
-  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
-    return Visit(TSInfo->getTypeLoc());
-
-  return false;
-}
-
-bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
-  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
-    return Visit(TSInfo->getTypeLoc());
-
-  return false;
-}
-
-bool CursorVisitor::VisitTagDecl(TagDecl *D) {
-  return VisitDeclContext(D);
-}
-
-bool CursorVisitor::VisitClassTemplateSpecializationDecl(
-                                          ClassTemplateSpecializationDecl *D) {
-  bool ShouldVisitBody = false;
-  switch (D->getSpecializationKind()) {
-  case TSK_Undeclared:
-  case TSK_ImplicitInstantiation:
-    // Nothing to visit
-    return false;
-      
-  case TSK_ExplicitInstantiationDeclaration:
-  case TSK_ExplicitInstantiationDefinition:
-    break;
-      
-  case TSK_ExplicitSpecialization:
-    ShouldVisitBody = true;
-    break;
-  }
-  
-  // Visit the template arguments used in the specialization.
-  if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
-    TypeLoc TL = SpecType->getTypeLoc();
-    if (TemplateSpecializationTypeLoc *TSTLoc
-          = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
-      for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
-        if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
-          return true;
-    }
-  }
-  
-  if (ShouldVisitBody && VisitCXXRecordDecl(D))
-    return true;
-  
-  return false;
-}
-
-bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
-                                   ClassTemplatePartialSpecializationDecl *D) {
-  // FIXME: Visit the "outer" template parameter lists on the TagDecl
-  // before visiting these template parameters.
-  if (VisitTemplateParameters(D->getTemplateParameters()))
-    return true;
-
-  // Visit the partial specialization arguments.
-  const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
-  for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
-    if (VisitTemplateArgumentLoc(TemplateArgs[I]))
-      return true;
-  
-  return VisitCXXRecordDecl(D);
-}
-
-bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
-  // Visit the default argument.
-  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
-    if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
-      if (Visit(DefArg->getTypeLoc()))
-        return true;
-  
-  return false;
-}
-
-bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
-  if (Expr *Init = D->getInitExpr())
-    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
-  return false;
-}
-
-bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
-  if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
-    if (Visit(TSInfo->getTypeLoc()))
-      return true;
-
-  // Visit the nested-name-specifier, if present.
-  if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-
-  return false;
-}
-
-/// \brief Compare two base or member initializers based on their source order.
-static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
-  CXXCtorInitializer const * const *X
-    = static_cast<CXXCtorInitializer const * const *>(Xp);
-  CXXCtorInitializer const * const *Y
-    = static_cast<CXXCtorInitializer const * const *>(Yp);
-  
-  if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
-    return -1;
-  else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
-    return 1;
-  else
-    return 0;
-}
-
-bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
-  if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
-    // Visit the function declaration's syntactic components in the order
-    // written. This requires a bit of work.
-    TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
-    FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
-    
-    // If we have a function declared directly (without the use of a typedef),
-    // visit just the return type. Otherwise, just visit the function's type
-    // now.
-    if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
-        (!FTL && Visit(TL)))
-      return true;
-    
-    // Visit the nested-name-specifier, if present.
-    if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
-      if (VisitNestedNameSpecifierLoc(QualifierLoc))
-        return true;
-    
-    // Visit the declaration name.
-    if (VisitDeclarationNameInfo(ND->getNameInfo()))
-      return true;
-    
-    // FIXME: Visit explicitly-specified template arguments!
-    
-    // Visit the function parameters, if we have a function type.
-    if (FTL && VisitFunctionTypeLoc(*FTL, true))
-      return true;
-    
-    // FIXME: Attributes?
-  }
-  
-  if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
-    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
-      // Find the initializers that were written in the source.
-      SmallVector<CXXCtorInitializer *, 4> WrittenInits;
-      for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
-                                          IEnd = Constructor->init_end();
-           I != IEnd; ++I) {
-        if (!(*I)->isWritten())
-          continue;
-      
-        WrittenInits.push_back(*I);
-      }
-      
-      // Sort the initializers in source order
-      llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
-                           &CompareCXXCtorInitializers);
-      
-      // Visit the initializers in source order
-      for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
-        CXXCtorInitializer *Init = WrittenInits[I];
-        if (Init->isAnyMemberInitializer()) {
-          if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
-                                        Init->getMemberLocation(), TU)))
-            return true;
-        } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
-          if (Visit(TInfo->getTypeLoc()))
-            return true;
-        }
-        
-        // Visit the initializer value.
-        if (Expr *Initializer = Init->getInit())
-          if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
-            return true;
-      } 
-    }
-    
-    if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
-      return true;
-  }
-
-  return false;
-}
-
-bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
-  if (VisitDeclaratorDecl(D))
-    return true;
-
-  if (Expr *BitWidth = D->getBitWidth())
-    return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
-
-  return false;
-}
-
-bool CursorVisitor::VisitVarDecl(VarDecl *D) {
-  if (VisitDeclaratorDecl(D))
-    return true;
-
-  if (Expr *Init = D->getInit())
-    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
-
-  return false;
-}
-
-bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
-  if (VisitDeclaratorDecl(D))
-    return true;
-  
-  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
-    if (Expr *DefArg = D->getDefaultArgument())
-      return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
-  
-  return false;  
-}
-
-bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
-  // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
-  // before visiting these template parameters.
-  if (VisitTemplateParameters(D->getTemplateParameters()))
-    return true;
-  
-  return VisitFunctionDecl(D->getTemplatedDecl());
-}
-
-bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
-  // FIXME: Visit the "outer" template parameter lists on the TagDecl
-  // before visiting these template parameters.
-  if (VisitTemplateParameters(D->getTemplateParameters()))
-    return true;
-  
-  return VisitCXXRecordDecl(D->getTemplatedDecl());
-}
-
-bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
-  if (VisitTemplateParameters(D->getTemplateParameters()))
-    return true;
-  
-  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
-      VisitTemplateArgumentLoc(D->getDefaultArgument()))
-    return true;
-  
-  return false;
-}
-
-bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
-  if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
-    if (Visit(TSInfo->getTypeLoc()))
-      return true;
-
-  for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
-       PEnd = ND->param_end();
-       P != PEnd; ++P) {
-    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
-      return true;
-  }
-
-  if (ND->isThisDeclarationADefinition() &&
-      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
-    return true;
-
-  return false;
-}
-
-template <typename DeclIt>
-static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
-                                      SourceManager &SM, SourceLocation EndLoc,
-                                      SmallVectorImpl<Decl *> &Decls) {
-  DeclIt next = *DI_current;
-  while (++next != DE_current) {
-    Decl *D_next = *next;
-    if (!D_next)
-      break;
-    SourceLocation L = D_next->getLocStart();
-    if (!L.isValid())
-      break;
-    if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
-      *DI_current = next;
-      Decls.push_back(D_next);
-      continue;
-    }
-    break;
-  }
-}
-
-namespace {
-  struct ContainerDeclsSort {
-    SourceManager &SM;
-    ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
-    bool operator()(Decl *A, Decl *B) {
-      SourceLocation L_A = A->getLocStart();
-      SourceLocation L_B = B->getLocStart();
-      assert(L_A.isValid() && L_B.isValid());
-      return SM.isBeforeInTranslationUnit(L_A, L_B);
-    }
-  };
-}
-
-bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
-  // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
-  // an @implementation can lexically contain Decls that are not properly
-  // nested in the AST.  When we identify such cases, we need to retrofit
-  // this nesting here.
-  if (!DI_current && !FileDI_current)
-    return VisitDeclContext(D);
-
-  // Scan the Decls that immediately come after the container
-  // in the current DeclContext.  If any fall within the
-  // container's lexical region, stash them into a vector
-  // for later processing.
-  SmallVector<Decl *, 24> DeclsInContainer;
-  SourceLocation EndLoc = D->getSourceRange().getEnd();
-  SourceManager &SM = AU->getSourceManager();
-  if (EndLoc.isValid()) {
-    if (DI_current) {
-      addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
-                                DeclsInContainer);
-    } else {
-      addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
-                                DeclsInContainer);
-    }
-  }
-
-  // The common case.
-  if (DeclsInContainer.empty())
-    return VisitDeclContext(D);
-
-  // Get all the Decls in the DeclContext, and sort them with the
-  // additional ones we've collected.  Then visit them.
-  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
-       I!=E; ++I) {
-    Decl *subDecl = *I;
-    if (!subDecl || subDecl->getLexicalDeclContext() != D ||
-        subDecl->getLocStart().isInvalid())
-      continue;
-    DeclsInContainer.push_back(subDecl);
-  }
-
-  // Now sort the Decls so that they appear in lexical order.
-  std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
-            ContainerDeclsSort(SM));
-
-  // Now visit the decls.
-  for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
-         E = DeclsInContainer.end(); I != E; ++I) {
-    CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
-    const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
-    if (!V.hasValue())
-      continue;
-    if (!V.getValue())
-      return false;
-    if (Visit(Cursor, true))
-      return true;
-  }
-  return false;
-}
-
-bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
-  if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
-                                   TU)))
-    return true;
-
-  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
-  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
-         E = ND->protocol_end(); I != E; ++I, ++PL)
-    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
-      return true;
-
-  return VisitObjCContainerDecl(ND);
-}
-
-bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
-  if (!PID->isThisDeclarationADefinition())
-    return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
-  
-  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
-  for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
-       E = PID->protocol_end(); I != E; ++I, ++PL)
-    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
-      return true;
-
-  return VisitObjCContainerDecl(PID);
-}
-
-bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
-  if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
-    return true;
-
-  // FIXME: This implements a workaround with @property declarations also being
-  // installed in the DeclContext for the @interface.  Eventually this code
-  // should be removed.
-  ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
-  if (!CDecl || !CDecl->IsClassExtension())
-    return false;
-
-  ObjCInterfaceDecl *ID = CDecl->getClassInterface();
-  if (!ID)
-    return false;
-
-  IdentifierInfo *PropertyId = PD->getIdentifier();
-  ObjCPropertyDecl *prevDecl =
-    ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
-
-  if (!prevDecl)
-    return false;
-
-  // Visit synthesized methods since they will be skipped when visiting
-  // the @interface.
-  if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
-    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
-      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
-        return true;
-
-  if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
-    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
-      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
-        return true;
-
-  return false;
-}
-
-bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
-  if (!D->isThisDeclarationADefinition()) {
-    // Forward declaration is treated like a reference.
-    return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
-  }
-
-  // Issue callbacks for super class.
-  if (D->getSuperClass() &&
-      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
-                                        D->getSuperClassLoc(),
-                                        TU)))
-    return true;
-
-  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
-  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
-         E = D->protocol_end(); I != E; ++I, ++PL)
-    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
-      return true;
-
-  return VisitObjCContainerDecl(D);
-}
-
-bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
-  return VisitObjCContainerDecl(D);
-}
-
-bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
-  // 'ID' could be null when dealing with invalid code.
-  if (ObjCInterfaceDecl *ID = D->getClassInterface())
-    if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
-      return true;
-
-  return VisitObjCImplDecl(D);
-}
-
-bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
-#if 0
-  // Issue callbacks for super class.
-  // FIXME: No source location information!
-  if (D->getSuperClass() &&
-      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
-                                        D->getSuperClassLoc(),
-                                        TU)))
-    return true;
-#endif
-
-  return VisitObjCImplDecl(D);
-}
-
-bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
-  if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
-    if (PD->isIvarNameSpecified())
-      return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
-  
-  return false;
-}
-
-bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
-  return VisitDeclContext(D);
-}
-
-bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
-  // Visit nested-name-specifier.
-  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-  
-  return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), 
-                                      D->getTargetNameLoc(), TU));
-}
-
-bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
-  // Visit nested-name-specifier.
-  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-  }
-  
-  if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
-    return true;
-    
-  return VisitDeclarationNameInfo(D->getNameInfo());
-}
-
-bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
-  // Visit nested-name-specifier.
-  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-
-  return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
-                                      D->getIdentLocation(), TU));
-}
-
-bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
-  // Visit nested-name-specifier.
-  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-  }
-
-  return VisitDeclarationNameInfo(D->getNameInfo());
-}
-
-bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
-                                               UnresolvedUsingTypenameDecl *D) {
-  // Visit nested-name-specifier.
-  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-  
-  return false;
-}
-
-bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
-  switch (Name.getName().getNameKind()) {
-  case clang::DeclarationName::Identifier:
-  case clang::DeclarationName::CXXLiteralOperatorName:
-  case clang::DeclarationName::CXXOperatorName:
-  case clang::DeclarationName::CXXUsingDirective:
-    return false;
-      
-  case clang::DeclarationName::CXXConstructorName:
-  case clang::DeclarationName::CXXDestructorName:
-  case clang::DeclarationName::CXXConversionFunctionName:
-    if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
-      return Visit(TSInfo->getTypeLoc());
-    return false;
-
-  case clang::DeclarationName::ObjCZeroArgSelector:
-  case clang::DeclarationName::ObjCOneArgSelector:
-  case clang::DeclarationName::ObjCMultiArgSelector:
-    // FIXME: Per-identifier location info?
-    return false;
-  }
-
-  llvm_unreachable("Invalid DeclarationName::Kind!");
-}
-
-bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, 
-                                             SourceRange Range) {
-  // FIXME: This whole routine is a hack to work around the lack of proper
-  // source information in nested-name-specifiers (PR5791). Since we do have
-  // a beginning source location, we can visit the first component of the
-  // nested-name-specifier, if it's a single-token component.
-  if (!NNS)
-    return false;
-  
-  // Get the first component in the nested-name-specifier.
-  while (NestedNameSpecifier *Prefix = NNS->getPrefix())
-    NNS = Prefix;
-  
-  switch (NNS->getKind()) {
-  case NestedNameSpecifier::Namespace:
-    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
-                                        TU));
-
-  case NestedNameSpecifier::NamespaceAlias:
-    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
-                                        Range.getBegin(), TU));
-
-  case NestedNameSpecifier::TypeSpec: {
-    // If the type has a form where we know that the beginning of the source
-    // range matches up with a reference cursor. Visit the appropriate reference
-    // cursor.
-    const Type *T = NNS->getAsType();
-    if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
-      return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
-    if (const TagType *Tag = dyn_cast<TagType>(T))
-      return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
-    if (const TemplateSpecializationType *TST
-                                      = dyn_cast<TemplateSpecializationType>(T))
-      return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
-    break;
-  }
-      
-  case NestedNameSpecifier::TypeSpecWithTemplate:
-  case NestedNameSpecifier::Global:
-  case NestedNameSpecifier::Identifier:
-    break;      
-  }
-  
-  return false;
-}
-
-bool 
-CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
-  SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
-  for (; Qualifier; Qualifier = Qualifier.getPrefix())
-    Qualifiers.push_back(Qualifier);
-  
-  while (!Qualifiers.empty()) {
-    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
-    NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
-    switch (NNS->getKind()) {
-    case NestedNameSpecifier::Namespace:
-      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), 
-                                       Q.getLocalBeginLoc(),
-                                       TU)))
-        return true;
-        
-      break;
-      
-    case NestedNameSpecifier::NamespaceAlias:
-      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
-                                       Q.getLocalBeginLoc(),
-                                       TU)))
-        return true;
-        
-      break;
-        
-    case NestedNameSpecifier::TypeSpec:
-    case NestedNameSpecifier::TypeSpecWithTemplate:
-      if (Visit(Q.getTypeLoc()))
-        return true;
-        
-      break;
-        
-    case NestedNameSpecifier::Global:
-    case NestedNameSpecifier::Identifier:
-      break;              
-    }
-  }
-  
-  return false;
-}
-
-bool CursorVisitor::VisitTemplateParameters(
-                                          const TemplateParameterList *Params) {
-  if (!Params)
-    return false;
-  
-  for (TemplateParameterList::const_iterator P = Params->begin(),
-                                          PEnd = Params->end();
-       P != PEnd; ++P) {
-    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
-      return true;
-  }
-  
-  return false;
-}
-
-bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
-  switch (Name.getKind()) {
-  case TemplateName::Template:
-    return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
-
-  case TemplateName::OverloadedTemplate:
-    // Visit the overloaded template set.
-    if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
-      return true;
-
-    return false;
-
-  case TemplateName::DependentTemplate:
-    // FIXME: Visit nested-name-specifier.
-    return false;
-      
-  case TemplateName::QualifiedTemplate:
-    // FIXME: Visit nested-name-specifier.
-    return Visit(MakeCursorTemplateRef(
-                                  Name.getAsQualifiedTemplateName()->getDecl(), 
-                                       Loc, TU));
-
-  case TemplateName::SubstTemplateTemplateParm:
-    return Visit(MakeCursorTemplateRef(
-                         Name.getAsSubstTemplateTemplateParm()->getParameter(),
-                                       Loc, TU));
-      
-  case TemplateName::SubstTemplateTemplateParmPack:
-    return Visit(MakeCursorTemplateRef(
-                  Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
-                                       Loc, TU));
-  }
-
-  llvm_unreachable("Invalid TemplateName::Kind!");
-}
-
-bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
-  switch (TAL.getArgument().getKind()) {
-  case TemplateArgument::Null:
-  case TemplateArgument::Integral:
-  case TemplateArgument::Pack:
-    return false;
-      
-  case TemplateArgument::Type:
-    if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
-      return Visit(TSInfo->getTypeLoc());
-    return false;
-      
-  case TemplateArgument::Declaration:
-    if (Expr *E = TAL.getSourceDeclExpression())
-      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
-    return false;
-
-  case TemplateArgument::NullPtr:
-    if (Expr *E = TAL.getSourceNullPtrExpression())
-      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
-    return false;
-
-  case TemplateArgument::Expression:
-    if (Expr *E = TAL.getSourceExpression())
-      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
-    return false;
-  
-  case TemplateArgument::Template:
-  case TemplateArgument::TemplateExpansion:
-    if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
-      return true;
-      
-    return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(), 
-                             TAL.getTemplateNameLoc());
-  }
-
-  llvm_unreachable("Invalid TemplateArgument::Kind!");
-}
-
-bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
-  return VisitDeclContext(D);
-}
-
-bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
-  return Visit(TL.getUnqualifiedLoc());
-}
-
-bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
-  ASTContext &Context = AU->getASTContext();
-
-  // Some builtin types (such as Objective-C's "id", "sel", and
-  // "Class") have associated declarations. Create cursors for those.
-  QualType VisitType;
-  switch (TL.getTypePtr()->getKind()) {
-
-  case BuiltinType::Void:
-  case BuiltinType::NullPtr:
-  case BuiltinType::Dependent:
-  case BuiltinType::OCLImage1d:
-  case BuiltinType::OCLImage1dArray:
-  case BuiltinType::OCLImage1dBuffer:
-  case BuiltinType::OCLImage2d:
-  case BuiltinType::OCLImage2dArray:
-  case BuiltinType::OCLImage3d:
-#define BUILTIN_TYPE(Id, SingletonId)
-#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
-#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
-#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
-#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-    break;
-
-  case BuiltinType::ObjCId:
-    VisitType = Context.getObjCIdType();
-    break;
-
-  case BuiltinType::ObjCClass:
-    VisitType = Context.getObjCClassType();
-    break;
-
-  case BuiltinType::ObjCSel:
-    VisitType = Context.getObjCSelType();
-    break;
-  }
-
-  if (!VisitType.isNull()) {
-    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
-      return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
-                                     TU));
-  }
-
-  return false;
-}
-
-bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-  return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
-}
-
-bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
-  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
-}
-
-bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
-  if (TL.isDefinition())
-    return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
-
-  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
-}
-
-bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
-  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
-}
-
-bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
-  if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
-    return true;
-
-  return false;
-}
-
-bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
-  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
-    return true;
-
-  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
-    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
-                                        TU)))
-      return true;
-  }
-
-  return false;
-}
-
-bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
-  return Visit(TL.getPointeeLoc());
-}
-
-bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
-  return Visit(TL.getInnerLoc());
-}
-
-bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
-  return Visit(TL.getPointeeLoc());
-}
-
-bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
-  return Visit(TL.getPointeeLoc());
-}
-
-bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
-  return Visit(TL.getPointeeLoc());
-}
-
-bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
-  return Visit(TL.getPointeeLoc());
-}
-
-bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
-  return Visit(TL.getPointeeLoc());
-}
-
-bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
-  return Visit(TL.getModifiedLoc());
-}
-
-bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 
-                                         bool SkipResultType) {
-  if (!SkipResultType && Visit(TL.getResultLoc()))
-    return true;
-
-  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
-    if (Decl *D = TL.getArg(I))
-      if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
-        return true;
-
-  return false;
-}
-
-bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
-  if (Visit(TL.getElementLoc()))
-    return true;
-
-  if (Expr *Size = TL.getSizeExpr())
-    return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
-
-  return false;
-}
-
-bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
-                                             TemplateSpecializationTypeLoc TL) {
-  // Visit the template name.
-  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 
-                        TL.getTemplateNameLoc()))
-    return true;
-  
-  // Visit the template arguments.
-  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
-    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
-      return true;
-  
-  return false;
-}
-
-bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
-  return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
-}
-
-bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
-  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
-    return Visit(TSInfo->getTypeLoc());
-
-  return false;
-}
-
-bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
-  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
-    return Visit(TSInfo->getTypeLoc());
-
-  return false;
-}
-
-bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
-  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
-    return true;
-  
-  return false;
-}
-
-bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
-                                    DependentTemplateSpecializationTypeLoc TL) {
-  // Visit the nested-name-specifier, if there is one.
-  if (TL.getQualifierLoc() &&
-      VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
-    return true;
-  
-  // Visit the template arguments.
-  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
-    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
-      return true;
-
-  return false;
-}
-
-bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
-  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
-    return true;
-  
-  return Visit(TL.getNamedTypeLoc());
-}
-
-bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
-  return Visit(TL.getPatternLoc());
-}
-
-bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
-  if (Expr *E = TL.getUnderlyingExpr())
-    return Visit(MakeCXCursor(E, StmtParent, TU));
-
-  return false;
-}
-
-bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
-  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
-}
-
-bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
-  return Visit(TL.getValueLoc());
-}
-
-#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
-bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
-  return Visit##PARENT##Loc(TL); \
-}
-
-DEFAULT_TYPELOC_IMPL(Complex, Type)
-DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
-DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
-DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
-DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
-DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
-DEFAULT_TYPELOC_IMPL(Vector, Type)
-DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
-DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
-DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
-DEFAULT_TYPELOC_IMPL(Record, TagType)
-DEFAULT_TYPELOC_IMPL(Enum, TagType)
-DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
-DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
-DEFAULT_TYPELOC_IMPL(Auto, Type)
-
-bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
-  // Visit the nested-name-specifier, if present.
-  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
-    if (VisitNestedNameSpecifierLoc(QualifierLoc))
-      return true;
-
-  if (D->isCompleteDefinition()) {
-    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
-         E = D->bases_end(); I != E; ++I) {
-      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
-        return true;
-    }
-  }
-
-  return VisitTagDecl(D);
-}
-
-bool CursorVisitor::VisitAttributes(Decl *D) {
-  for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
-       i != e; ++i)
-    if (Visit(MakeCXCursor(*i, D, TU)))
-        return true;
-
-  return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Data-recursive visitor methods.
-//===----------------------------------------------------------------------===//
-
-namespace {
-#define DEF_JOB(NAME, DATA, KIND)\
-class NAME : public VisitorJob {\
-public:\
-  NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
-  static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
-  DATA *get() const { return static_cast<DATA*>(data[0]); }\
-};
-
-DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
-DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
-DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
-DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
-DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo, 
-        ExplicitTemplateArgsVisitKind)
-DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
-DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
-DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
-#undef DEF_JOB
-
-class DeclVisit : public VisitorJob {
-public:
-  DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
-    VisitorJob(parent, VisitorJob::DeclVisitKind,
-               d, isFirst ? (void*) 1 : (void*) 0) {}
-  static bool classof(const VisitorJob *VJ) {
-    return VJ->getKind() == DeclVisitKind;
-  }
-  Decl *get() const { return static_cast<Decl*>(data[0]); }
-  bool isFirst() const { return data[1] ? true : false; }
-};
-class TypeLocVisit : public VisitorJob {
-public:
-  TypeLocVisit(TypeLoc tl, CXCursor parent) :
-    VisitorJob(parent, VisitorJob::TypeLocVisitKind,
-               tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
-
-  static bool classof(const VisitorJob *VJ) {
-    return VJ->getKind() == TypeLocVisitKind;
-  }
-
-  TypeLoc get() const { 
-    QualType T = QualType::getFromOpaquePtr(data[0]);
-    return TypeLoc(T, data[1]);
-  }
-};
-
-class LabelRefVisit : public VisitorJob {
-public:
-  LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
-    : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
-                 labelLoc.getPtrEncoding()) {}
-  
-  static bool classof(const VisitorJob *VJ) {
-    return VJ->getKind() == VisitorJob::LabelRefVisitKind;
-  }
-  LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
-  SourceLocation getLoc() const { 
-    return SourceLocation::getFromPtrEncoding(data[1]); }
-};
-  
-class NestedNameSpecifierLocVisit : public VisitorJob {
-public:
-  NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
-    : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
-                 Qualifier.getNestedNameSpecifier(),
-                 Qualifier.getOpaqueData()) { }
-  
-  static bool classof(const VisitorJob *VJ) {
-    return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
-  }
-  
-  NestedNameSpecifierLoc get() const {
-    return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]), 
-                                  data[1]);
-  }
-};
-  
-class DeclarationNameInfoVisit : public VisitorJob {
-public:
-  DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
-    : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
-  static bool classof(const VisitorJob *VJ) {
-    return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
-  }
-  DeclarationNameInfo get() const {
-    Stmt *S = static_cast<Stmt*>(data[0]);
-    switch (S->getStmtClass()) {
-    default:
-      llvm_unreachable("Unhandled Stmt");
-    case clang::Stmt::MSDependentExistsStmtClass:
-      return cast<MSDependentExistsStmt>(S)->getNameInfo();
-    case Stmt::CXXDependentScopeMemberExprClass:
-      return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
-    case Stmt::DependentScopeDeclRefExprClass:
-      return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
-    }
-  }
-};
-class MemberRefVisit : public VisitorJob {
-public:
-  MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
-    : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
-                 L.getPtrEncoding()) {}
-  static bool classof(const VisitorJob *VJ) {
-    return VJ->getKind() == VisitorJob::MemberRefVisitKind;
-  }
-  FieldDecl *get() const {
-    return static_cast<FieldDecl*>(data[0]);
-  }
-  SourceLocation getLoc() const {
-    return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
-  }
-};
-class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
-  VisitorWorkList &WL;
-  CXCursor Parent;
-public:
-  EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
-    : WL(wl), Parent(parent) {}
-
-  void VisitAddrLabelExpr(AddrLabelExpr *E);
-  void VisitBlockExpr(BlockExpr *B);
-  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
-  void VisitCompoundStmt(CompoundStmt *S);
-  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
-  void VisitMSDependentExistsStmt(MSDependentExistsStmt *S);
-  void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
-  void VisitCXXNewExpr(CXXNewExpr *E);
-  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
-  void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
-  void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
-  void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
-  void VisitCXXTypeidExpr(CXXTypeidExpr *E);
-  void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
-  void VisitCXXUuidofExpr(CXXUuidofExpr *E);
-  void VisitCXXCatchStmt(CXXCatchStmt *S);
-  void VisitDeclRefExpr(DeclRefExpr *D);
-  void VisitDeclStmt(DeclStmt *S);
-  void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
-  void VisitDesignatedInitExpr(DesignatedInitExpr *E);
-  void VisitExplicitCastExpr(ExplicitCastExpr *E);
-  void VisitForStmt(ForStmt *FS);
-  void VisitGotoStmt(GotoStmt *GS);
-  void VisitIfStmt(IfStmt *If);
-  void VisitInitListExpr(InitListExpr *IE);
-  void VisitMemberExpr(MemberExpr *M);
-  void VisitOffsetOfExpr(OffsetOfExpr *E);
-  void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
-  void VisitObjCMessageExpr(ObjCMessageExpr *M);
-  void VisitOverloadExpr(OverloadExpr *E);
-  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
-  void VisitStmt(Stmt *S);
-  void VisitSwitchStmt(SwitchStmt *S);
-  void VisitWhileStmt(WhileStmt *W);
-  void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
-  void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
-  void VisitTypeTraitExpr(TypeTraitExpr *E);
-  void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
-  void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
-  void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
-  void VisitVAArgExpr(VAArgExpr *E);
-  void VisitSizeOfPackExpr(SizeOfPackExpr *E);
-  void VisitPseudoObjectExpr(PseudoObjectExpr *E);
-  void VisitOpaqueValueExpr(OpaqueValueExpr *E);
-  void VisitLambdaExpr(LambdaExpr *E);
-  
-private:
-  void AddDeclarationNameInfo(Stmt *S);
-  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
-  void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
-  void AddMemberRef(FieldDecl *D, SourceLocation L);
-  void AddStmt(Stmt *S);
-  void AddDecl(Decl *D, bool isFirst = true);
-  void AddTypeLoc(TypeSourceInfo *TI);
-  void EnqueueChildren(Stmt *S);
-};
-} // end anonyous namespace
-
-void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
-  // 'S' should always be non-null, since it comes from the
-  // statement we are visiting.
-  WL.push_back(DeclarationNameInfoVisit(S, Parent));
-}
-
-void 
-EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
-  if (Qualifier)
-    WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
-}
-
-void EnqueueVisitor::AddStmt(Stmt *S) {
-  if (S)
-    WL.push_back(StmtVisit(S, Parent));
-}
-void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
-  if (D)
-    WL.push_back(DeclVisit(D, Parent, isFirst));
-}
-void EnqueueVisitor::
-  AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
-  if (A)
-    WL.push_back(ExplicitTemplateArgsVisit(
-                        const_cast<ASTTemplateArgumentListInfo*>(A), Parent));
-}
-void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
-  if (D)
-    WL.push_back(MemberRefVisit(D, L, Parent));
-}
-void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
-  if (TI)
-    WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
- }
-void EnqueueVisitor::EnqueueChildren(Stmt *S) {
-  unsigned size = WL.size();
-  for (Stmt::child_range Child = S->children(); Child; ++Child) {
-    AddStmt(*Child);
-  }
-  if (size == WL.size())
-    return;
-  // Now reverse the entries we just added.  This will match the DFS
-  // ordering performed by the worklist.
-  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
-  std::reverse(I, E);
-}
-void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
-  WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
-}
-void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
-  AddDecl(B->getBlockDecl());
-}
-void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-  EnqueueChildren(E);
-  AddTypeLoc(E->getTypeSourceInfo());
-}
-void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
-  for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
-        E = S->body_rend(); I != E; ++I) {
-    AddStmt(*I);
-  }
-}
-void EnqueueVisitor::
-VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
-  AddStmt(S->getSubStmt());
-  AddDeclarationNameInfo(S);
-  if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
-    AddNestedNameSpecifierLoc(QualifierLoc);
-}
-
-void EnqueueVisitor::
-VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
-  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
-  AddDeclarationNameInfo(E);
-  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
-    AddNestedNameSpecifierLoc(QualifierLoc);
-  if (!E->isImplicitAccess())
-    AddStmt(E->getBase());
-}
-void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
-  // Enqueue the initializer , if any.
-  AddStmt(E->getInitializer());
-  // Enqueue the array size, if any.
-  AddStmt(E->getArraySize());
-  // Enqueue the allocated type.
-  AddTypeLoc(E->getAllocatedTypeSourceInfo());
-  // Enqueue the placement arguments.
-  for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
-    AddStmt(E->getPlacementArg(I-1));
-}
-void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
-  for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
-    AddStmt(CE->getArg(I-1));
-  AddStmt(CE->getCallee());
-  AddStmt(CE->getArg(0));
-}
-void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
-  // Visit the name of the type being destroyed.
-  AddTypeLoc(E->getDestroyedTypeInfo());
-  // Visit the scope type that looks disturbingly like the nested-name-specifier
-  // but isn't.
-  AddTypeLoc(E->getScopeTypeInfo());
-  // Visit the nested-name-specifier.
-  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
-    AddNestedNameSpecifierLoc(QualifierLoc);
-  // Visit base expression.
-  AddStmt(E->getBase());
-}
-void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
-  AddTypeLoc(E->getTypeSourceInfo());
-}
-void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
-  EnqueueChildren(E);
-  AddTypeLoc(E->getTypeSourceInfo());
-}
-void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
-  EnqueueChildren(E);
-  if (E->isTypeOperand())
-    AddTypeLoc(E->getTypeOperandSourceInfo());
-}
-
-void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr 
-                                                     *E) {
-  EnqueueChildren(E);
-  AddTypeLoc(E->getTypeSourceInfo());
-}
-void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
-  EnqueueChildren(E);
-  if (E->isTypeOperand())
-    AddTypeLoc(E->getTypeOperandSourceInfo());
-}
-
-void EnqueueVisitor::VisitCXXCatchStmt(CXXCatchStmt *S) {
-  EnqueueChildren(S);
-  AddDecl(S->getExceptionDecl());
-}
-
-void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
-  if (DR->hasExplicitTemplateArgs()) {
-    AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
-  }
-  WL.push_back(DeclRefExprParts(DR, Parent));
-}
-void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
-  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
-  AddDeclarationNameInfo(E);
-  AddNestedNameSpecifierLoc(E->getQualifierLoc());
-}
-void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
-  unsigned size = WL.size();
-  bool isFirst = true;
-  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
-       D != DEnd; ++D) {
-    AddDecl(*D, isFirst);
-    isFirst = false;
-  }
-  if (size == WL.size())
-    return;
-  // Now reverse the entries we just added.  This will match the DFS
-  // ordering performed by the worklist.
-  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
-  std::reverse(I, E);
-}
-void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
-  AddStmt(E->getInit());
-  typedef DesignatedInitExpr::Designator Designator;
-  for (DesignatedInitExpr::reverse_designators_iterator
-         D = E->designators_rbegin(), DEnd = E->designators_rend();
-         D != DEnd; ++D) {
-    if (D->isFieldDesignator()) {
-      if (FieldDecl *Field = D->getField())
-        AddMemberRef(Field, D->getFieldLoc());
-      continue;
-    }
-    if (D->isArrayDesignator()) {
-      AddStmt(E->getArrayIndex(*D));
-      continue;
-    }
-    assert(D->isArrayRangeDesignator() && "Unknown designator kind");
-    AddStmt(E->getArrayRangeEnd(*D));
-    AddStmt(E->getArrayRangeStart(*D));
-  }
-}
-void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
-  EnqueueChildren(E);
-  AddTypeLoc(E->getTypeInfoAsWritten());
-}
-void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
-  AddStmt(FS->getBody());
-  AddStmt(FS->getInc());
-  AddStmt(FS->getCond());
-  AddDecl(FS->getConditionVariable());
-  AddStmt(FS->getInit());
-}
-void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
-  WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
-}
-void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
-  AddStmt(If->getElse());
-  AddStmt(If->getThen());
-  AddStmt(If->getCond());
-  AddDecl(If->getConditionVariable());
-}
-void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
-  // We care about the syntactic form of the initializer list, only.
-  if (InitListExpr *Syntactic = IE->getSyntacticForm())
-    IE = Syntactic;
-  EnqueueChildren(IE);
-}
-void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
-  WL.push_back(MemberExprParts(M, Parent));
-  
-  // If the base of the member access expression is an implicit 'this', don't
-  // visit it.
-  // FIXME: If we ever want to show these implicit accesses, this will be
-  // unfortunate. However, clang_getCursor() relies on this behavior.
-  if (!M->isImplicitAccess())
-    AddStmt(M->getBase());
-}
-void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
-  AddTypeLoc(E->getEncodedTypeSourceInfo());
-}
-void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
-  EnqueueChildren(M);
-  AddTypeLoc(M->getClassReceiverTypeInfo());
-}
-void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
-  // Visit the components of the offsetof expression.
-  for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
-    typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
-    const OffsetOfNode &Node = E->getComponent(I-1);
-    switch (Node.getKind()) {
-    case OffsetOfNode::Array:
-      AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
-      break;
-    case OffsetOfNode::Field:
-      AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
-      break;
-    case OffsetOfNode::Identifier:
-    case OffsetOfNode::Base:
-      continue;
-    }
-  }
-  // Visit the type into which we're computing the offset.
-  AddTypeLoc(E->getTypeSourceInfo());
-}
-void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
-  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
-  WL.push_back(OverloadExprParts(E, Parent));
-}
-void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
-                                              UnaryExprOrTypeTraitExpr *E) {
-  EnqueueChildren(E);
-  if (E->isArgumentType())
-    AddTypeLoc(E->getArgumentTypeInfo());
-}
-void EnqueueVisitor::VisitStmt(Stmt *S) {
-  EnqueueChildren(S);
-}
-void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
-  AddStmt(S->getBody());
-  AddStmt(S->getCond());
-  AddDecl(S->getConditionVariable());
-}
-
-void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
-  AddStmt(W->getBody());
-  AddStmt(W->getCond());
-  AddDecl(W->getConditionVariable());
-}
-
-void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
-  AddTypeLoc(E->getQueriedTypeSourceInfo());
-}
-
-void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
-  AddTypeLoc(E->getRhsTypeSourceInfo());
-  AddTypeLoc(E->getLhsTypeSourceInfo());
-}
-
-void EnqueueVisitor::VisitTypeTraitExpr(TypeTraitExpr *E) {
-  for (unsigned I = E->getNumArgs(); I > 0; --I)
-    AddTypeLoc(E->getArg(I-1));
-}
-
-void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
-  AddTypeLoc(E->getQueriedTypeSourceInfo());
-}
-
-void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
-  EnqueueChildren(E);
-}
-
-void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
-  VisitOverloadExpr(U);
-  if (!U->isImplicitAccess())
-    AddStmt(U->getBase());
-}
-void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
-  AddStmt(E->getSubExpr());
-  AddTypeLoc(E->getWrittenTypeInfo());
-}
-void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
-  WL.push_back(SizeOfPackExprParts(E, Parent));
-}
-void EnqueueVisitor::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
-  // If the opaque value has a source expression, just transparently
-  // visit that.  This is useful for (e.g.) pseudo-object expressions.
-  if (Expr *SourceExpr = E->getSourceExpr())
-    return Visit(SourceExpr);
-}
-void EnqueueVisitor::VisitLambdaExpr(LambdaExpr *E) {
-  AddStmt(E->getBody());
-  WL.push_back(LambdaExprParts(E, Parent));
-}
-void EnqueueVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
-  // Treat the expression like its syntactic form.
-  Visit(E->getSyntacticForm());
-}
-
-void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
-  EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
-}
-
-bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
-  if (RegionOfInterest.isValid()) {
-    SourceRange Range = getRawCursorExtent(C);
-    if (Range.isInvalid() || CompareRegionOfInterest(Range))
-      return false;
-  }
-  return true;
-}
-
-bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
-  while (!WL.empty()) {
-    // Dequeue the worklist item.
-    VisitorJob LI = WL.back();
-    WL.pop_back();
-
-    // Set the Parent field, then back to its old value once we're done.
-    SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
-  
-    switch (LI.getKind()) {
-      case VisitorJob::DeclVisitKind: {
-        Decl *D = cast<DeclVisit>(&LI)->get();
-        if (!D)
-          continue;
-
-        // For now, perform default visitation for Decls.
-        if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
-                               cast<DeclVisit>(&LI)->isFirst())))
-            return true;
-
-        continue;
-      }
-      case VisitorJob::ExplicitTemplateArgsVisitKind: {
-        const ASTTemplateArgumentListInfo *ArgList =
-          cast<ExplicitTemplateArgsVisit>(&LI)->get();
-        for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
-               *ArgEnd = Arg + ArgList->NumTemplateArgs;
-               Arg != ArgEnd; ++Arg) {
-          if (VisitTemplateArgumentLoc(*Arg))
-            return true;
-        }
-        continue;
-      }
-      case VisitorJob::TypeLocVisitKind: {
-        // Perform default visitation for TypeLocs.
-        if (Visit(cast<TypeLocVisit>(&LI)->get()))
-          return true;
-        continue;
-      }
-      case VisitorJob::LabelRefVisitKind: {
-        LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
-        if (LabelStmt *stmt = LS->getStmt()) {
-          if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
-                                       TU))) {
-            return true;
-          }
-        }
-        continue;
-      }
-
-      case VisitorJob::NestedNameSpecifierLocVisitKind: {
-        NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
-        if (VisitNestedNameSpecifierLoc(V->get()))
-          return true;
-        continue;
-      }
-        
-      case VisitorJob::DeclarationNameInfoVisitKind: {
-        if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
-                                     ->get()))
-          return true;
-        continue;
-      }
-      case VisitorJob::MemberRefVisitKind: {
-        MemberRefVisit *V = cast<MemberRefVisit>(&LI);
-        if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
-          return true;
-        continue;
-      }
-      case VisitorJob::StmtVisitKind: {
-        Stmt *S = cast<StmtVisit>(&LI)->get();
-        if (!S)
-          continue;
-
-        // Update the current cursor.
-        CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
-        if (!IsInRegionOfInterest(Cursor))
-          continue;
-        switch (Visitor(Cursor, Parent, ClientData)) {
-          case CXChildVisit_Break: return true;
-          case CXChildVisit_Continue: break;
-          case CXChildVisit_Recurse:
-            if (PostChildrenVisitor)
-              WL.push_back(PostChildrenVisit(0, Cursor));
-            EnqueueWorkList(WL, S);
-            break;
-        }
-        continue;
-      }
-      case VisitorJob::MemberExprPartsKind: {
-        // Handle the other pieces in the MemberExpr besides the base.
-        MemberExpr *M = cast<MemberExprParts>(&LI)->get();
-        
-        // Visit the nested-name-specifier
-        if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
-          if (VisitNestedNameSpecifierLoc(QualifierLoc))
-            return true;
-        
-        // Visit the declaration name.
-        if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
-          return true;
-        
-        // Visit the explicitly-specified template arguments, if any.
-        if (M->hasExplicitTemplateArgs()) {
-          for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
-               *ArgEnd = Arg + M->getNumTemplateArgs();
-               Arg != ArgEnd; ++Arg) {
-            if (VisitTemplateArgumentLoc(*Arg))
-              return true;
-          }
-        }
-        continue;
-      }
-      case VisitorJob::DeclRefExprPartsKind: {
-        DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
-        // Visit nested-name-specifier, if present.
-        if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
-          if (VisitNestedNameSpecifierLoc(QualifierLoc))
-            return true;
-        // Visit declaration name.
-        if (VisitDeclarationNameInfo(DR->getNameInfo()))
-          return true;
-        continue;
-      }
-      case VisitorJob::OverloadExprPartsKind: {
-        OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
-        // Visit the nested-name-specifier.
-        if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
-          if (VisitNestedNameSpecifierLoc(QualifierLoc))
-            return true;
-        // Visit the declaration name.
-        if (VisitDeclarationNameInfo(O->getNameInfo()))
-          return true;
-        // Visit the overloaded declaration reference.
-        if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
-          return true;
-        continue;
-      }
-      case VisitorJob::SizeOfPackExprPartsKind: {
-        SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
-        NamedDecl *Pack = E->getPack();
-        if (isa<TemplateTypeParmDecl>(Pack)) {
-          if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
-                                      E->getPackLoc(), TU)))
-            return true;
-          
-          continue;
-        }
-          
-        if (isa<TemplateTemplateParmDecl>(Pack)) {
-          if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
-                                          E->getPackLoc(), TU)))
-            return true;
-          
-          continue;
-        }
-        
-        // Non-type template parameter packs and function parameter packs are
-        // treated like DeclRefExpr cursors.
-        continue;
-      }
-        
-      case VisitorJob::LambdaExprPartsKind: {
-        // Visit captures.
-        LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
-        for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
-                                       CEnd = E->explicit_capture_end();
-             C != CEnd; ++C) {
-          if (C->capturesThis())
-            continue;
-          
-          if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
-                                          C->getLocation(),
-                                          TU)))
-            return true;
-        }
-        
-        // Visit parameters and return type, if present.
-        if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
-          TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
-          if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
-            // Visit the whole type.
-            if (Visit(TL))
-              return true;
-          } else if (isa<FunctionProtoTypeLoc>(TL)) {
-            FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
-            if (E->hasExplicitParameters()) {
-              // Visit parameters.
-              for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
-                if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
-                  return true;
-            } else {
-              // Visit result type.
-              if (Visit(Proto.getResultLoc()))
-                return true;
-            }
-          }
-        }
-        break;
-      }
-
-      case VisitorJob::PostChildrenVisitKind:
-        if (PostChildrenVisitor(Parent, ClientData))
-          return true;
-        break;
-    }
-  }
-  return false;
-}
-
-bool CursorVisitor::Visit(Stmt *S) {
-  VisitorWorkList *WL = 0;
-  if (!WorkListFreeList.empty()) {
-    WL = WorkListFreeList.back();
-    WL->clear();
-    WorkListFreeList.pop_back();
-  }
-  else {
-    WL = new VisitorWorkList();
-    WorkListCache.push_back(WL);
-  }
-  EnqueueWorkList(*WL, S);
-  bool result = RunVisitorWorkList(*WL);
-  WorkListFreeList.push_back(WL);
-  return result;
-}
-
-namespace {
-typedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
-RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, 
-                          const DeclarationNameInfo &NI, 
-                          const SourceRange &QLoc, 
-                          const ASTTemplateArgumentListInfo *TemplateArgs = 0){
-  const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
-  const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
-  const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
-  
-  const DeclarationName::NameKind Kind = NI.getName().getNameKind();
-  
-  RefNamePieces Pieces;
-
-  if (WantQualifier && QLoc.isValid())
-    Pieces.push_back(QLoc);
-  
-  if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
-    Pieces.push_back(NI.getLoc());
-  
-  if (WantTemplateArgs && TemplateArgs)
-    Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
-                                 TemplateArgs->RAngleLoc));
-  
-  if (Kind == DeclarationName::CXXOperatorName) {
-    Pieces.push_back(SourceLocation::getFromRawEncoding(
-                       NI.getInfo().CXXOperatorName.BeginOpNameLoc));
-    Pieces.push_back(SourceLocation::getFromRawEncoding(
-                       NI.getInfo().CXXOperatorName.EndOpNameLoc));
-  }
-  
-  if (WantSinglePiece) {
-    SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
-    Pieces.clear();
-    Pieces.push_back(R);
-  }  
-
-  return Pieces;  
-}
-}
-
-//===----------------------------------------------------------------------===//
-// Misc. API hooks.
-//===----------------------------------------------------------------------===//               
-
-static llvm::sys::Mutex EnableMultithreadingMutex;
-static bool EnabledMultithreading;
-
-static void fatal_error_handler(void *user_data, const std::string& reason) {
-  // Write the result out to stderr avoiding errs() because raw_ostreams can
-  // call report_fatal_error.
-  fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
-  ::abort();
-}
-
-extern "C" {
-CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
-                          int displayDiagnostics) {
-  // Disable pretty stack trace functionality, which will otherwise be a very
-  // poor citizen of the world and set up all sorts of signal handlers.
-  llvm::DisablePrettyStackTrace = true;
-
-  // We use crash recovery to make some of our APIs more reliable, implicitly
-  // enable it.
-  llvm::CrashRecoveryContext::Enable();
-
-  // Enable support for multithreading in LLVM.
-  {
-    llvm::sys::ScopedLock L(EnableMultithreadingMutex);
-    if (!EnabledMultithreading) {
-      llvm::install_fatal_error_handler(fatal_error_handler, 0);
-      llvm::llvm_start_multithreaded();
-      EnabledMultithreading = true;
-    }
-  }
-
-  CIndexer *CIdxr = new CIndexer();
-  if (excludeDeclarationsFromPCH)
-    CIdxr->setOnlyLocalDecls();
-  if (displayDiagnostics)
-    CIdxr->setDisplayDiagnostics();
-
-  if (getenv("LIBCLANG_BGPRIO_INDEX"))
-    CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
-                               CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
-  if (getenv("LIBCLANG_BGPRIO_EDIT"))
-    CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
-                               CXGlobalOpt_ThreadBackgroundPriorityForEditing);
-
-  return CIdxr;
-}
-
-void clang_disposeIndex(CXIndex CIdx) {
-  if (CIdx)
-    delete static_cast<CIndexer *>(CIdx);
-}
-
-void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
-  if (CIdx)
-    static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
-}
-
-unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
-  if (CIdx)
-    return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
-  return 0;
-}
-
-void clang_toggleCrashRecovery(unsigned isEnabled) {
-  if (isEnabled)
-    llvm::CrashRecoveryContext::Enable();
-  else
-    llvm::CrashRecoveryContext::Disable();
-}
-  
-CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
-                                              const char *ast_filename) {
-  if (!CIdx)
-    return 0;
-
-  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
-  FileSystemOptions FileSystemOpts;
-
-  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
-  ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
-                                  CXXIdx->getOnlyLocalDecls(),
-                                  0, 0,
-                                  /*CaptureDiagnostics=*/true,
-                                  /*AllowPCHWithCompilerErrors=*/true,
-                                  /*UserFilesAreVolatile=*/true);
-  return MakeCXTranslationUnit(CXXIdx, TU);
-}
-
-unsigned clang_defaultEditingTranslationUnitOptions() {
-  return CXTranslationUnit_PrecompiledPreamble | 
-         CXTranslationUnit_CacheCompletionResults;
-}
-  
-CXTranslationUnit
-clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
-                                          const char *source_filename,
-                                          int num_command_line_args,
-                                          const char * const *command_line_args,
-                                          unsigned num_unsaved_files,
-                                          struct CXUnsavedFile *unsaved_files) {
-  unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
-  return clang_parseTranslationUnit(CIdx, source_filename,
-                                    command_line_args, num_command_line_args,
-                                    unsaved_files, num_unsaved_files,
-                                    Options);
-}
-
-struct ParseTranslationUnitInfo {
-  CXIndex CIdx;
-  const char *source_filename;
-  const char *const *command_line_args;
-  int num_command_line_args;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
-  unsigned options;
-  CXTranslationUnit result;
-};
-static void clang_parseTranslationUnit_Impl(void *UserData) {
-  ParseTranslationUnitInfo *PTUI =
-    static_cast<ParseTranslationUnitInfo*>(UserData);
-  CXIndex CIdx = PTUI->CIdx;
-  const char *source_filename = PTUI->source_filename;
-  const char * const *command_line_args = PTUI->command_line_args;
-  int num_command_line_args = PTUI->num_command_line_args;
-  struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
-  unsigned num_unsaved_files = PTUI->num_unsaved_files;
-  unsigned options = PTUI->options;
-  PTUI->result = 0;
-
-  if (!CIdx)
-    return;
-
-  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
-
-  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
-    setThreadBackgroundPriority();
-
-  bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
-  // FIXME: Add a flag for modules.
-  TranslationUnitKind TUKind
-    = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
-  bool CacheCodeCompetionResults
-    = options & CXTranslationUnit_CacheCompletionResults;
-  bool IncludeBriefCommentsInCodeCompletion
-    = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
-  bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
-  bool ForSerialization = options & CXTranslationUnit_ForSerialization;
-
-  // Configure the diagnostics.
-  IntrusiveRefCntPtr<DiagnosticsEngine>
-    Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
-                                              num_command_line_args,
-                                              command_line_args));
-
-  // Recover resources if we crash before exiting this function.
-  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
-    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
-
-  OwningPtr<std::vector<ASTUnit::RemappedFile> >
-    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
-
-  // Recover resources if we crash before exiting this function.
-  llvm::CrashRecoveryContextCleanupRegistrar<
-    std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
-
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
-                                            Buffer));
-  }
-
-  OwningPtr<std::vector<const char *> >
-    Args(new std::vector<const char*>());
-
-  // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
-    ArgsCleanup(Args.get());
-
-  // Since the Clang C library is primarily used by batch tools dealing with
-  // (often very broken) source code, where spell-checking can have a
-  // significant negative impact on performance (particularly when 
-  // precompiled headers are involved), we disable it by default.
-  // Only do this if we haven't found a spell-checking-related argument.
-  bool FoundSpellCheckingArgument = false;
-  for (int I = 0; I != num_command_line_args; ++I) {
-    if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
-        strcmp(command_line_args[I], "-fspell-checking") == 0) {
-      FoundSpellCheckingArgument = true;
-      break;
-    }
-  }
-  if (!FoundSpellCheckingArgument)
-    Args->push_back("-fno-spell-checking");
-  
-  Args->insert(Args->end(), command_line_args,
-               command_line_args + num_command_line_args);
-
-  // The 'source_filename' argument is optional.  If the caller does not
-  // specify it then it is assumed that the source file is specified
-  // in the actual argument list.
-  // Put the source file after command_line_args otherwise if '-x' flag is
-  // present it will be unused.
-  if (source_filename)
-    Args->push_back(source_filename);
-
-  // Do we need the detailed preprocessing record?
-  if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
-    Args->push_back("-Xclang");
-    Args->push_back("-detailed-preprocessing-record");
-  }
-  
-  unsigned NumErrors = Diags->getClient()->getNumErrors();
-  OwningPtr<ASTUnit> ErrUnit;
-  OwningPtr<ASTUnit> Unit(
-    ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0 
-                                 /* vector::data() not portable */,
-                                 Args->size() ? (&(*Args)[0] + Args->size()) :0,
-                                 Diags,
-                                 CXXIdx->getClangResourcesPath(),
-                                 CXXIdx->getOnlyLocalDecls(),
-                                 /*CaptureDiagnostics=*/true,
-                                 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
-                                 RemappedFiles->size(),
-                                 /*RemappedFilesKeepOriginalName=*/true,
-                                 PrecompilePreamble,
-                                 TUKind,
-                                 CacheCodeCompetionResults,
-                                 IncludeBriefCommentsInCodeCompletion,
-                                 /*AllowPCHWithCompilerErrors=*/true,
-                                 SkipFunctionBodies,
-                                 /*UserFilesAreVolatile=*/true,
-                                 ForSerialization,
-                                 &ErrUnit));
-
-  if (NumErrors != Diags->getClient()->getNumErrors()) {
-    // Make sure to check that 'Unit' is non-NULL.
-    if (CXXIdx->getDisplayDiagnostics())
-      printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
-  }
-
-  PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
-}
-CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
-                                             const char *source_filename,
-                                         const char * const *command_line_args,
-                                             int num_command_line_args,
-                                            struct CXUnsavedFile *unsaved_files,
-                                             unsigned num_unsaved_files,
-                                             unsigned options) {
-  ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
-                                    num_command_line_args, unsaved_files,
-                                    num_unsaved_files, options, 0 };
-  llvm::CrashRecoveryContext CRC;
-
-  if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
-    fprintf(stderr, "libclang: crash detected during parsing: {\n");
-    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
-    fprintf(stderr, "  'command_line_args' : [");
-    for (int i = 0; i != num_command_line_args; ++i) {
-      if (i)
-        fprintf(stderr, ", ");
-      fprintf(stderr, "'%s'", command_line_args[i]);
-    }
-    fprintf(stderr, "],\n");
-    fprintf(stderr, "  'unsaved_files' : [");
-    for (unsigned i = 0; i != num_unsaved_files; ++i) {
-      if (i)
-        fprintf(stderr, ", ");
-      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
-              unsaved_files[i].Length);
-    }
-    fprintf(stderr, "],\n");
-    fprintf(stderr, "  'options' : %d,\n", options);
-    fprintf(stderr, "}\n");
-    
-    return 0;
-  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
-    PrintLibclangResourceUsage(PTUI.result);
-  }
-  
-  return PTUI.result;
-}
-
-unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
-  return CXSaveTranslationUnit_None;
-}  
-
-namespace {
-
-struct SaveTranslationUnitInfo {
-  CXTranslationUnit TU;
-  const char *FileName;
-  unsigned options;
-  CXSaveError result;
-};
-
-}
-
-static void clang_saveTranslationUnit_Impl(void *UserData) {
-  SaveTranslationUnitInfo *STUI =
-    static_cast<SaveTranslationUnitInfo*>(UserData);
-
-  CIndexer *CXXIdx = (CIndexer*)STUI->TU->CIdx;
-  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
-    setThreadBackgroundPriority();
-
-  bool hadError = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName);
-  STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
-}
-
-int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
-                              unsigned options) {
-  if (!TU)
-    return CXSaveError_InvalidTU;
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-  if (!CXXUnit->hasSema())
-    return CXSaveError_InvalidTU;
-
-  SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
-
-  if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
-      getenv("LIBCLANG_NOTHREADS")) {
-    clang_saveTranslationUnit_Impl(&STUI);
-
-    if (getenv("LIBCLANG_RESOURCE_USAGE"))
-      PrintLibclangResourceUsage(TU);
-
-    return STUI.result;
-  }
-
-  // We have an AST that has invalid nodes due to compiler errors.
-  // Use a crash recovery thread for protection.
-
-  llvm::CrashRecoveryContext CRC;
-
-  if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
-    fprintf(stderr, "libclang: crash detected during AST saving: {\n");
-    fprintf(stderr, "  'filename' : '%s'\n", FileName);
-    fprintf(stderr, "  'options' : %d,\n", options);
-    fprintf(stderr, "}\n");
-
-    return CXSaveError_Unknown;
-
-  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
-    PrintLibclangResourceUsage(TU);
-  }
-
-  return STUI.result;
-}
-
-void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
-  if (CTUnit) {
-    // If the translation unit has been marked as unsafe to free, just discard
-    // it.
-    if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
-      return;
-
-    delete static_cast<ASTUnit *>(CTUnit->TUData);
-    disposeCXStringPool(CTUnit->StringPool);
-    delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
-    disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
-    delete CTUnit;
-  }
-}
-
-unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
-  return CXReparse_None;
-}
-
-struct ReparseTranslationUnitInfo {
-  CXTranslationUnit TU;
-  unsigned num_unsaved_files;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned options;
-  int result;
-};
-
-static void clang_reparseTranslationUnit_Impl(void *UserData) {
-  ReparseTranslationUnitInfo *RTUI =
-    static_cast<ReparseTranslationUnitInfo*>(UserData);
-  CXTranslationUnit TU = RTUI->TU;
-
-  // Reset the associated diagnostics.
-  delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
-  TU->Diagnostics = 0;
-
-  unsigned num_unsaved_files = RTUI->num_unsaved_files;
-  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
-  unsigned options = RTUI->options;
-  (void) options;
-  RTUI->result = 1;
-
-  if (!TU)
-    return;
-
-  CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
-  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
-    setThreadBackgroundPriority();
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-  
-  OwningPtr<std::vector<ASTUnit::RemappedFile> >
-    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
-  
-  // Recover resources if we crash before exiting this function.
-  llvm::CrashRecoveryContextCleanupRegistrar<
-    std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
-  
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
-                                            Buffer));
-  }
-  
-  if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
-                        RemappedFiles->size()))
-    RTUI->result = 0;
-}
-
-int clang_reparseTranslationUnit(CXTranslationUnit TU,
-                                 unsigned num_unsaved_files,
-                                 struct CXUnsavedFile *unsaved_files,
-                                 unsigned options) {
-  ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
-                                      options, 0 };
-
-  if (getenv("LIBCLANG_NOTHREADS")) {
-    clang_reparseTranslationUnit_Impl(&RTUI);
-    return RTUI.result;
-  }
-
-  llvm::CrashRecoveryContext CRC;
-
-  if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
-    fprintf(stderr, "libclang: crash detected during reparsing\n");
-    static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
-    return 1;
-  } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
-    PrintLibclangResourceUsage(TU);
-
-  return RTUI.result;
-}
-
-
-CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
-  if (!CTUnit)
-    return createCXString("");
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
-  return createCXString(CXXUnit->getOriginalSourceFileName(), true);
-}
-
-CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
-  ASTUnit *CXXUnit = static_cast<ASTUnit*>(TU->TUData);
-  return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
-}
-
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// CXFile Operations.
-//===----------------------------------------------------------------------===//
-
-extern "C" {
-CXString clang_getFileName(CXFile SFile) {
-  if (!SFile)
-    return createCXString((const char*)NULL);
-
-  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
-  return createCXString(FEnt->getName());
-}
-
-time_t clang_getFileTime(CXFile SFile) {
-  if (!SFile)
-    return 0;
-
-  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
-  return FEnt->getModificationTime();
-}
-
-CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
-  if (!tu)
-    return 0;
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
-
-  FileManager &FMgr = CXXUnit->getFileManager();
-  return const_cast<FileEntry *>(FMgr.getFile(file_name));
-}
-
-unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
-  if (!tu || !file)
-    return 0;
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
-  FileEntry *FEnt = static_cast<FileEntry *>(file);
-  return CXXUnit->getPreprocessor().getHeaderSearchInfo()
-                                          .isFileMultipleIncludeGuarded(FEnt);
-}
-
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// CXCursor Operations.
-//===----------------------------------------------------------------------===//
-
-static Decl *getDeclFromExpr(Stmt *E) {
-  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
-    return getDeclFromExpr(CE->getSubExpr());
-
-  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
-    return RefExpr->getDecl();
-  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
-    return ME->getMemberDecl();
-  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
-    return RE->getDecl();
-  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
-    if (PRE->isExplicitProperty())
-      return PRE->getExplicitProperty();
-    // It could be messaging both getter and setter as in:
-    // ++myobj.myprop;
-    // in which case prefer to associate the setter since it is less obvious
-    // from inspecting the source that the setter is going to get called.
-    if (PRE->isMessagingSetter())
-      return PRE->getImplicitPropertySetter();
-    return PRE->getImplicitPropertyGetter();
-  }
-  if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
-    return getDeclFromExpr(POE->getSyntacticForm());
-  if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
-    if (Expr *Src = OVE->getSourceExpr())
-      return getDeclFromExpr(Src);
-      
-  if (CallExpr *CE = dyn_cast<CallExpr>(E))
-    return getDeclFromExpr(CE->getCallee());
-  if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
-    if (!CE->isElidable())
-    return CE->getConstructor();
-  if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
-    return OME->getMethodDecl();
-
-  if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
-    return PE->getProtocol();
-  if (SubstNonTypeTemplateParmPackExpr *NTTP 
-                              = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
-    return NTTP->getParameterPack();
-  if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
-    if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || 
-        isa<ParmVarDecl>(SizeOfPack->getPack()))
-      return SizeOfPack->getPack();
-  
-  return 0;
-}
-
-static SourceLocation getLocationFromExpr(Expr *E) {
-  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
-    return getLocationFromExpr(CE->getSubExpr());
-
-  if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
-    return /*FIXME:*/Msg->getLeftLoc();
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    return DRE->getLocation();
-  if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
-    return Member->getMemberLoc();
-  if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
-    return Ivar->getLocation();
-  if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
-    return SizeOfPack->getPackLoc();
-  if (ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
-    return PropRef->getLocation();
-  
-  return E->getLocStart();
-}
-
-extern "C" {
-
-unsigned clang_visitChildren(CXCursor parent,
-                             CXCursorVisitor visitor,
-                             CXClientData client_data) {
-  CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
-                          /*VisitPreprocessorLast=*/false);
-  return CursorVis.VisitChildren(parent);
-}
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-#if __has_feature(blocks)
-typedef enum CXChildVisitResult 
-     (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
-
-static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
-    CXClientData client_data) {
-  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
-  return block(cursor, parent);
-}
-#else
-// If we are compiled with a compiler that doesn't have native blocks support,
-// define and call the block manually, so the 
-typedef struct _CXChildVisitResult
-{
-	void *isa;
-	int flags;
-	int reserved;
-	enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
-                                         CXCursor);
-} *CXCursorVisitorBlock;
-
-static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
-    CXClientData client_data) {
-  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
-  return block->invoke(block, cursor, parent);
-}
-#endif
-
-
-unsigned clang_visitChildrenWithBlock(CXCursor parent,
-                                      CXCursorVisitorBlock block) {
-  return clang_visitChildren(parent, visitWithBlock, block);
-}
-
-static CXString getDeclSpelling(Decl *D) {
-  if (!D)
-    return createCXString("");
-
-  NamedDecl *ND = dyn_cast<NamedDecl>(D);
-  if (!ND) {
-    if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
-      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
-        return createCXString(Property->getIdentifier()->getName());
-    
-    if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
-      if (Module *Mod = ImportD->getImportedModule())
-        return createCXString(Mod->getFullModuleName());
-
-    return createCXString("");
-  }
-  
-  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
-    return createCXString(OMD->getSelector().getAsString());
-
-  if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
-    // No, this isn't the same as the code below. getIdentifier() is non-virtual
-    // and returns different names. NamedDecl returns the class name and
-    // ObjCCategoryImplDecl returns the category name.
-    return createCXString(CIMP->getIdentifier()->getNameStart());
-
-  if (isa<UsingDirectiveDecl>(D))
-    return createCXString("");
-  
-  SmallString<1024> S;
-  llvm::raw_svector_ostream os(S);
-  ND->printName(os);
-  
-  return createCXString(os.str());
-}
-
-CXString clang_getCursorSpelling(CXCursor C) {
-  if (clang_isTranslationUnit(C.kind))
-    return clang_getTranslationUnitSpelling(
-                            static_cast<CXTranslationUnit>(C.data[2]));
-
-  if (clang_isReference(C.kind)) {
-    switch (C.kind) {
-    case CXCursor_ObjCSuperClassRef: {
-      ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
-      return createCXString(Super->getIdentifier()->getNameStart());
-    }
-    case CXCursor_ObjCClassRef: {
-      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
-      return createCXString(Class->getIdentifier()->getNameStart());
-    }
-    case CXCursor_ObjCProtocolRef: {
-      ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
-      assert(OID && "getCursorSpelling(): Missing protocol decl");
-      return createCXString(OID->getIdentifier()->getNameStart());
-    }
-    case CXCursor_CXXBaseSpecifier: {
-      CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
-      return createCXString(B->getType().getAsString());
-    }
-    case CXCursor_TypeRef: {
-      TypeDecl *Type = getCursorTypeRef(C).first;
-      assert(Type && "Missing type decl");
-
-      return createCXString(getCursorContext(C).getTypeDeclType(Type).
-                              getAsString());
-    }
-    case CXCursor_TemplateRef: {
-      TemplateDecl *Template = getCursorTemplateRef(C).first;
-      assert(Template && "Missing template decl");
-      
-      return createCXString(Template->getNameAsString());
-    }
-        
-    case CXCursor_NamespaceRef: {
-      NamedDecl *NS = getCursorNamespaceRef(C).first;
-      assert(NS && "Missing namespace decl");
-      
-      return createCXString(NS->getNameAsString());
-    }
-
-    case CXCursor_MemberRef: {
-      FieldDecl *Field = getCursorMemberRef(C).first;
-      assert(Field && "Missing member decl");
-      
-      return createCXString(Field->getNameAsString());
-    }
-
-    case CXCursor_LabelRef: {
-      LabelStmt *Label = getCursorLabelRef(C).first;
-      assert(Label && "Missing label");
-      
-      return createCXString(Label->getName());
-    }
-
-    case CXCursor_OverloadedDeclRef: {
-      OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
-      if (Decl *D = Storage.dyn_cast<Decl *>()) {
-        if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
-          return createCXString(ND->getNameAsString());
-        return createCXString("");
-      }
-      if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
-        return createCXString(E->getName().getAsString());
-      OverloadedTemplateStorage *Ovl
-        = Storage.get<OverloadedTemplateStorage*>();
-      if (Ovl->size() == 0)
-        return createCXString("");
-      return createCXString((*Ovl->begin())->getNameAsString());
-    }
-        
-    case CXCursor_VariableRef: {
-      VarDecl *Var = getCursorVariableRef(C).first;
-      assert(Var && "Missing variable decl");
-      
-      return createCXString(Var->getNameAsString());
-    }
-        
-    default:
-      return createCXString("<not implemented>");
-    }
-  }
-
-  if (clang_isExpression(C.kind)) {
-    Decl *D = getDeclFromExpr(getCursorExpr(C));
-    if (D)
-      return getDeclSpelling(D);
-    return createCXString("");
-  }
-
-  if (clang_isStatement(C.kind)) {
-    Stmt *S = getCursorStmt(C);
-    if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
-      return createCXString(Label->getName());
-
-    return createCXString("");
-  }
-  
-  if (C.kind == CXCursor_MacroExpansion)
-    return createCXString(getCursorMacroExpansion(C)->getName()
-                                                           ->getNameStart());
-
-  if (C.kind == CXCursor_MacroDefinition)
-    return createCXString(getCursorMacroDefinition(C)->getName()
-                                                           ->getNameStart());
-
-  if (C.kind == CXCursor_InclusionDirective)
-    return createCXString(getCursorInclusionDirective(C)->getFileName());
-      
-  if (clang_isDeclaration(C.kind))
-    return getDeclSpelling(getCursorDecl(C));
-
-  if (C.kind == CXCursor_AnnotateAttr) {
-    AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
-    return createCXString(AA->getAnnotation());
-  }
-
-  if (C.kind == CXCursor_AsmLabelAttr) {
-    AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
-    return createCXString(AA->getLabel());
-  }
-
-  return createCXString("");
-}
-
-CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
-                                                unsigned pieceIndex,
-                                                unsigned options) {
-  if (clang_Cursor_isNull(C))
-    return clang_getNullRange();
-
-  ASTContext &Ctx = getCursorContext(C);
-
-  if (clang_isStatement(C.kind)) {
-    Stmt *S = getCursorStmt(C);
-    if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
-      if (pieceIndex > 0)
-        return clang_getNullRange();
-      return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
-    }
-
-    return clang_getNullRange();
-  }
-
-  if (C.kind == CXCursor_ObjCMessageExpr) {
-    if (ObjCMessageExpr *
-          ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
-      if (pieceIndex >= ME->getNumSelectorLocs())
-        return clang_getNullRange();
-      return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
-    }
-  }
-
-  if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
-      C.kind == CXCursor_ObjCClassMethodDecl) {
-    if (ObjCMethodDecl *
-          MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
-      if (pieceIndex >= MD->getNumSelectorLocs())
-        return clang_getNullRange();
-      return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
-    }
-  }
-
-  if (C.kind == CXCursor_ObjCCategoryDecl ||
-      C.kind == CXCursor_ObjCCategoryImplDecl) {
-    if (pieceIndex > 0)
-      return clang_getNullRange();
-    if (ObjCCategoryDecl *
-          CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
-      return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
-    if (ObjCCategoryImplDecl *
-          CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
-      return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
-  }
-
-  if (C.kind == CXCursor_ModuleImportDecl) {
-    if (pieceIndex > 0)
-      return clang_getNullRange();
-    if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
-      ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
-      if (!Locs.empty())
-        return cxloc::translateSourceRange(Ctx,
-                                         SourceRange(Locs.front(), Locs.back()));
-    }
-    return clang_getNullRange();
-  }
-
-  // FIXME: A CXCursor_InclusionDirective should give the location of the
-  // filename, but we don't keep track of this.
-
-  // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
-  // but we don't keep track of this.
-
-  // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
-  // but we don't keep track of this.
-
-  // Default handling, give the location of the cursor.
-
-  if (pieceIndex > 0)
-    return clang_getNullRange();
-
-  CXSourceLocation CXLoc = clang_getCursorLocation(C);
-  SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
-  return cxloc::translateSourceRange(Ctx, Loc);
-}
-
-CXString clang_getCursorDisplayName(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return clang_getCursorSpelling(C);
-  
-  Decl *D = getCursorDecl(C);
-  if (!D)
-    return createCXString("");
-
-  PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
-    D = FunTmpl->getTemplatedDecl();
-  
-  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
-    SmallString<64> Str;
-    llvm::raw_svector_ostream OS(Str);
-    OS << *Function;
-    if (Function->getPrimaryTemplate())
-      OS << "<>";
-    OS << "(";
-    for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
-      if (I)
-        OS << ", ";
-      OS << Function->getParamDecl(I)->getType().getAsString(Policy);
-    }
-    
-    if (Function->isVariadic()) {
-      if (Function->getNumParams())
-        OS << ", ";
-      OS << "...";
-    }
-    OS << ")";
-    return createCXString(OS.str());
-  }
-  
-  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
-    SmallString<64> Str;
-    llvm::raw_svector_ostream OS(Str);
-    OS << *ClassTemplate;
-    OS << "<";
-    TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
-    for (unsigned I = 0, N = Params->size(); I != N; ++I) {
-      if (I)
-        OS << ", ";
-      
-      NamedDecl *Param = Params->getParam(I);
-      if (Param->getIdentifier()) {
-        OS << Param->getIdentifier()->getName();
-        continue;
-      }
-      
-      // There is no parameter name, which makes this tricky. Try to come up
-      // with something useful that isn't too long.
-      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
-        OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
-      else if (NonTypeTemplateParmDecl *NTTP
-                                    = dyn_cast<NonTypeTemplateParmDecl>(Param))
-        OS << NTTP->getType().getAsString(Policy);
-      else
-        OS << "template<...> class";
-    }
-    
-    OS << ">";
-    return createCXString(OS.str());
-  }
-  
-  if (ClassTemplateSpecializationDecl *ClassSpec
-                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
-    // If the type was explicitly written, use that.
-    if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
-      return createCXString(TSInfo->getType().getAsString(Policy));
-    
-    SmallString<64> Str;
-    llvm::raw_svector_ostream OS(Str);
-    OS << *ClassSpec;
-    OS << TemplateSpecializationType::PrintTemplateArgumentList(
-                                      ClassSpec->getTemplateArgs().data(),
-                                      ClassSpec->getTemplateArgs().size(),
-                                                                Policy);
-    return createCXString(OS.str());
-  }
-  
-  return clang_getCursorSpelling(C);
-}
-  
-CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
-  switch (Kind) {
-  case CXCursor_FunctionDecl:
-      return createCXString("FunctionDecl");
-  case CXCursor_TypedefDecl:
-      return createCXString("TypedefDecl");
-  case CXCursor_EnumDecl:
-      return createCXString("EnumDecl");
-  case CXCursor_EnumConstantDecl:
-      return createCXString("EnumConstantDecl");
-  case CXCursor_StructDecl:
-      return createCXString("StructDecl");
-  case CXCursor_UnionDecl:
-      return createCXString("UnionDecl");
-  case CXCursor_ClassDecl:
-      return createCXString("ClassDecl");
-  case CXCursor_FieldDecl:
-      return createCXString("FieldDecl");
-  case CXCursor_VarDecl:
-      return createCXString("VarDecl");
-  case CXCursor_ParmDecl:
-      return createCXString("ParmDecl");
-  case CXCursor_ObjCInterfaceDecl:
-      return createCXString("ObjCInterfaceDecl");
-  case CXCursor_ObjCCategoryDecl:
-      return createCXString("ObjCCategoryDecl");
-  case CXCursor_ObjCProtocolDecl:
-      return createCXString("ObjCProtocolDecl");
-  case CXCursor_ObjCPropertyDecl:
-      return createCXString("ObjCPropertyDecl");
-  case CXCursor_ObjCIvarDecl:
-      return createCXString("ObjCIvarDecl");
-  case CXCursor_ObjCInstanceMethodDecl:
-      return createCXString("ObjCInstanceMethodDecl");
-  case CXCursor_ObjCClassMethodDecl:
-      return createCXString("ObjCClassMethodDecl");
-  case CXCursor_ObjCImplementationDecl:
-      return createCXString("ObjCImplementationDecl");
-  case CXCursor_ObjCCategoryImplDecl:
-      return createCXString("ObjCCategoryImplDecl");
-  case CXCursor_CXXMethod:
-      return createCXString("CXXMethod");
-  case CXCursor_UnexposedDecl:
-      return createCXString("UnexposedDecl");
-  case CXCursor_ObjCSuperClassRef:
-      return createCXString("ObjCSuperClassRef");
-  case CXCursor_ObjCProtocolRef:
-      return createCXString("ObjCProtocolRef");
-  case CXCursor_ObjCClassRef:
-      return createCXString("ObjCClassRef");
-  case CXCursor_TypeRef:
-      return createCXString("TypeRef");
-  case CXCursor_TemplateRef:
-      return createCXString("TemplateRef");
-  case CXCursor_NamespaceRef:
-    return createCXString("NamespaceRef");
-  case CXCursor_MemberRef:
-    return createCXString("MemberRef");
-  case CXCursor_LabelRef:
-    return createCXString("LabelRef");
-  case CXCursor_OverloadedDeclRef:
-    return createCXString("OverloadedDeclRef");
-  case CXCursor_VariableRef:
-    return createCXString("VariableRef");
-  case CXCursor_IntegerLiteral:
-      return createCXString("IntegerLiteral");
-  case CXCursor_FloatingLiteral:
-      return createCXString("FloatingLiteral");
-  case CXCursor_ImaginaryLiteral:
-      return createCXString("ImaginaryLiteral");
-  case CXCursor_StringLiteral:
-      return createCXString("StringLiteral");
-  case CXCursor_CharacterLiteral:
-      return createCXString("CharacterLiteral");
-  case CXCursor_ParenExpr:
-      return createCXString("ParenExpr");
-  case CXCursor_UnaryOperator:
-      return createCXString("UnaryOperator");
-  case CXCursor_ArraySubscriptExpr:
-      return createCXString("ArraySubscriptExpr");
-  case CXCursor_BinaryOperator:
-      return createCXString("BinaryOperator");
-  case CXCursor_CompoundAssignOperator:
-      return createCXString("CompoundAssignOperator");
-  case CXCursor_ConditionalOperator:
-      return createCXString("ConditionalOperator");
-  case CXCursor_CStyleCastExpr:
-      return createCXString("CStyleCastExpr");
-  case CXCursor_CompoundLiteralExpr:
-      return createCXString("CompoundLiteralExpr");
-  case CXCursor_InitListExpr:
-      return createCXString("InitListExpr");
-  case CXCursor_AddrLabelExpr:
-      return createCXString("AddrLabelExpr");
-  case CXCursor_StmtExpr:
-      return createCXString("StmtExpr");
-  case CXCursor_GenericSelectionExpr:
-      return createCXString("GenericSelectionExpr");
-  case CXCursor_GNUNullExpr:
-      return createCXString("GNUNullExpr");
-  case CXCursor_CXXStaticCastExpr:
-      return createCXString("CXXStaticCastExpr");
-  case CXCursor_CXXDynamicCastExpr:
-      return createCXString("CXXDynamicCastExpr");
-  case CXCursor_CXXReinterpretCastExpr:
-      return createCXString("CXXReinterpretCastExpr");
-  case CXCursor_CXXConstCastExpr:
-      return createCXString("CXXConstCastExpr");
-  case CXCursor_CXXFunctionalCastExpr:
-      return createCXString("CXXFunctionalCastExpr");
-  case CXCursor_CXXTypeidExpr:
-      return createCXString("CXXTypeidExpr");
-  case CXCursor_CXXBoolLiteralExpr:
-      return createCXString("CXXBoolLiteralExpr");
-  case CXCursor_CXXNullPtrLiteralExpr:
-      return createCXString("CXXNullPtrLiteralExpr");
-  case CXCursor_CXXThisExpr:
-      return createCXString("CXXThisExpr");
-  case CXCursor_CXXThrowExpr:
-      return createCXString("CXXThrowExpr");
-  case CXCursor_CXXNewExpr:
-      return createCXString("CXXNewExpr");
-  case CXCursor_CXXDeleteExpr:
-      return createCXString("CXXDeleteExpr");
-  case CXCursor_UnaryExpr:
-      return createCXString("UnaryExpr");
-  case CXCursor_ObjCStringLiteral:
-      return createCXString("ObjCStringLiteral");
-  case CXCursor_ObjCBoolLiteralExpr:
-      return createCXString("ObjCBoolLiteralExpr");
-  case CXCursor_ObjCEncodeExpr:
-      return createCXString("ObjCEncodeExpr");
-  case CXCursor_ObjCSelectorExpr:
-      return createCXString("ObjCSelectorExpr");
-  case CXCursor_ObjCProtocolExpr:
-      return createCXString("ObjCProtocolExpr");
-  case CXCursor_ObjCBridgedCastExpr:
-      return createCXString("ObjCBridgedCastExpr");
-  case CXCursor_BlockExpr:
-      return createCXString("BlockExpr");
-  case CXCursor_PackExpansionExpr:
-      return createCXString("PackExpansionExpr");
-  case CXCursor_SizeOfPackExpr:
-      return createCXString("SizeOfPackExpr");
-  case CXCursor_LambdaExpr:
-    return createCXString("LambdaExpr");
-  case CXCursor_UnexposedExpr:
-      return createCXString("UnexposedExpr");
-  case CXCursor_DeclRefExpr:
-      return createCXString("DeclRefExpr");
-  case CXCursor_MemberRefExpr:
-      return createCXString("MemberRefExpr");
-  case CXCursor_CallExpr:
-      return createCXString("CallExpr");
-  case CXCursor_ObjCMessageExpr:
-      return createCXString("ObjCMessageExpr");
-  case CXCursor_UnexposedStmt:
-      return createCXString("UnexposedStmt");
-  case CXCursor_DeclStmt:
-      return createCXString("DeclStmt");
-  case CXCursor_LabelStmt:
-      return createCXString("LabelStmt");
-  case CXCursor_CompoundStmt:
-      return createCXString("CompoundStmt");
-  case CXCursor_CaseStmt:
-      return createCXString("CaseStmt");
-  case CXCursor_DefaultStmt:
-      return createCXString("DefaultStmt");
-  case CXCursor_IfStmt:
-      return createCXString("IfStmt");
-  case CXCursor_SwitchStmt:
-      return createCXString("SwitchStmt");
-  case CXCursor_WhileStmt:
-      return createCXString("WhileStmt");
-  case CXCursor_DoStmt:
-      return createCXString("DoStmt");
-  case CXCursor_ForStmt:
-      return createCXString("ForStmt");
-  case CXCursor_GotoStmt:
-      return createCXString("GotoStmt");
-  case CXCursor_IndirectGotoStmt:
-      return createCXString("IndirectGotoStmt");
-  case CXCursor_ContinueStmt:
-      return createCXString("ContinueStmt");
-  case CXCursor_BreakStmt:
-      return createCXString("BreakStmt");
-  case CXCursor_ReturnStmt:
-      return createCXString("ReturnStmt");
-  case CXCursor_GCCAsmStmt:
-      return createCXString("GCCAsmStmt");
-  case CXCursor_MSAsmStmt:
-      return createCXString("MSAsmStmt");
-  case CXCursor_ObjCAtTryStmt:
-      return createCXString("ObjCAtTryStmt");
-  case CXCursor_ObjCAtCatchStmt:
-      return createCXString("ObjCAtCatchStmt");
-  case CXCursor_ObjCAtFinallyStmt:
-      return createCXString("ObjCAtFinallyStmt");
-  case CXCursor_ObjCAtThrowStmt:
-      return createCXString("ObjCAtThrowStmt");
-  case CXCursor_ObjCAtSynchronizedStmt:
-      return createCXString("ObjCAtSynchronizedStmt");
-  case CXCursor_ObjCAutoreleasePoolStmt:
-      return createCXString("ObjCAutoreleasePoolStmt");
-  case CXCursor_ObjCForCollectionStmt:
-      return createCXString("ObjCForCollectionStmt");
-  case CXCursor_CXXCatchStmt:
-      return createCXString("CXXCatchStmt");
-  case CXCursor_CXXTryStmt:
-      return createCXString("CXXTryStmt");
-  case CXCursor_CXXForRangeStmt:
-      return createCXString("CXXForRangeStmt");
-  case CXCursor_SEHTryStmt:
-      return createCXString("SEHTryStmt");
-  case CXCursor_SEHExceptStmt:
-      return createCXString("SEHExceptStmt");
-  case CXCursor_SEHFinallyStmt:
-      return createCXString("SEHFinallyStmt");
-  case CXCursor_NullStmt:
-      return createCXString("NullStmt");
-  case CXCursor_InvalidFile:
-      return createCXString("InvalidFile");
-  case CXCursor_InvalidCode:
-    return createCXString("InvalidCode");
-  case CXCursor_NoDeclFound:
-      return createCXString("NoDeclFound");
-  case CXCursor_NotImplemented:
-      return createCXString("NotImplemented");
-  case CXCursor_TranslationUnit:
-      return createCXString("TranslationUnit");
-  case CXCursor_UnexposedAttr:
-      return createCXString("UnexposedAttr");
-  case CXCursor_IBActionAttr:
-      return createCXString("attribute(ibaction)");
-  case CXCursor_IBOutletAttr:
-     return createCXString("attribute(iboutlet)");
-  case CXCursor_IBOutletCollectionAttr:
-      return createCXString("attribute(iboutletcollection)");
-  case CXCursor_CXXFinalAttr:
-      return createCXString("attribute(final)");
-  case CXCursor_CXXOverrideAttr:
-      return createCXString("attribute(override)");
-  case CXCursor_AnnotateAttr:
-    return createCXString("attribute(annotate)");
-  case CXCursor_AsmLabelAttr:
-    return createCXString("asm label");
-  case CXCursor_PreprocessingDirective:
-    return createCXString("preprocessing directive");
-  case CXCursor_MacroDefinition:
-    return createCXString("macro definition");
-  case CXCursor_MacroExpansion:
-    return createCXString("macro expansion");
-  case CXCursor_InclusionDirective:
-    return createCXString("inclusion directive");
-  case CXCursor_Namespace:
-    return createCXString("Namespace");
-  case CXCursor_LinkageSpec:
-    return createCXString("LinkageSpec");
-  case CXCursor_CXXBaseSpecifier:
-    return createCXString("C++ base class specifier");  
-  case CXCursor_Constructor:
-    return createCXString("CXXConstructor");
-  case CXCursor_Destructor:
-    return createCXString("CXXDestructor");
-  case CXCursor_ConversionFunction:
-    return createCXString("CXXConversion");
-  case CXCursor_TemplateTypeParameter:
-    return createCXString("TemplateTypeParameter");
-  case CXCursor_NonTypeTemplateParameter:
-    return createCXString("NonTypeTemplateParameter");
-  case CXCursor_TemplateTemplateParameter:
-    return createCXString("TemplateTemplateParameter");
-  case CXCursor_FunctionTemplate:
-    return createCXString("FunctionTemplate");
-  case CXCursor_ClassTemplate:
-    return createCXString("ClassTemplate");
-  case CXCursor_ClassTemplatePartialSpecialization:
-    return createCXString("ClassTemplatePartialSpecialization");
-  case CXCursor_NamespaceAlias:
-    return createCXString("NamespaceAlias");
-  case CXCursor_UsingDirective:
-    return createCXString("UsingDirective");
-  case CXCursor_UsingDeclaration:
-    return createCXString("UsingDeclaration");
-  case CXCursor_TypeAliasDecl:
-    return createCXString("TypeAliasDecl");
-  case CXCursor_ObjCSynthesizeDecl:
-    return createCXString("ObjCSynthesizeDecl");
-  case CXCursor_ObjCDynamicDecl:
-    return createCXString("ObjCDynamicDecl");
-  case CXCursor_CXXAccessSpecifier:
-    return createCXString("CXXAccessSpecifier");
-  case CXCursor_ModuleImportDecl:
-    return createCXString("ModuleImport");
-  }
-
-  llvm_unreachable("Unhandled CXCursorKind");
-}
-
-struct GetCursorData {
-  SourceLocation TokenBeginLoc;
-  bool PointsAtMacroArgExpansion;
-  bool VisitedObjCPropertyImplDecl;
-  SourceLocation VisitedDeclaratorDeclStartLoc;
-  CXCursor &BestCursor;
-
-  GetCursorData(SourceManager &SM,
-                SourceLocation tokenBegin, CXCursor &outputCursor)
-    : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
-    PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
-    VisitedObjCPropertyImplDecl = false;
-  }
-};
-
-static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
-                                                CXCursor parent,
-                                                CXClientData client_data) {
-  GetCursorData *Data = static_cast<GetCursorData *>(client_data);
-  CXCursor *BestCursor = &Data->BestCursor;
-
-  // If we point inside a macro argument we should provide info of what the
-  // token is so use the actual cursor, don't replace it with a macro expansion
-  // cursor.
-  if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
-    return CXChildVisit_Recurse;
-  
-  if (clang_isDeclaration(cursor.kind)) {
-    // Avoid having the implicit methods override the property decls.
-    if (ObjCMethodDecl *MD
-          = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
-      if (MD->isImplicit())
-        return CXChildVisit_Break;
-
-    } else if (ObjCInterfaceDecl *ID
-                 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
-      // Check that when we have multiple @class references in the same line,
-      // that later ones do not override the previous ones.
-      // If we have:
-      // @class Foo, Bar;
-      // source ranges for both start at '@', so 'Bar' will end up overriding
-      // 'Foo' even though the cursor location was at 'Foo'.
-      if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
-          BestCursor->kind == CXCursor_ObjCClassRef)
-        if (ObjCInterfaceDecl *PrevID
-             = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
-         if (PrevID != ID &&
-             !PrevID->isThisDeclarationADefinition() &&
-             !ID->isThisDeclarationADefinition())
-           return CXChildVisit_Break;
-        }
-
-    } else if (DeclaratorDecl *DD
-                    = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
-      SourceLocation StartLoc = DD->getSourceRange().getBegin();
-      // Check that when we have multiple declarators in the same line,
-      // that later ones do not override the previous ones.
-      // If we have:
-      // int Foo, Bar;
-      // source ranges for both start at 'int', so 'Bar' will end up overriding
-      // 'Foo' even though the cursor location was at 'Foo'.
-      if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
-        return CXChildVisit_Break;
-      Data->VisitedDeclaratorDeclStartLoc = StartLoc;
-
-    } else if (ObjCPropertyImplDecl *PropImp
-              = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
-      (void)PropImp;
-      // Check that when we have multiple @synthesize in the same line,
-      // that later ones do not override the previous ones.
-      // If we have:
-      // @synthesize Foo, Bar;
-      // source ranges for both start at '@', so 'Bar' will end up overriding
-      // 'Foo' even though the cursor location was at 'Foo'.
-      if (Data->VisitedObjCPropertyImplDecl)
-        return CXChildVisit_Break;
-      Data->VisitedObjCPropertyImplDecl = true;
-    }
-  }
-
-  if (clang_isExpression(cursor.kind) &&
-      clang_isDeclaration(BestCursor->kind)) {
-    if (Decl *D = getCursorDecl(*BestCursor)) {
-      // Avoid having the cursor of an expression replace the declaration cursor
-      // when the expression source range overlaps the declaration range.
-      // This can happen for C++ constructor expressions whose range generally
-      // include the variable declaration, e.g.:
-      //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
-      if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
-          D->getLocation() == Data->TokenBeginLoc)
-        return CXChildVisit_Break;
-    }
-  }
-
-  // If our current best cursor is the construction of a temporary object, 
-  // don't replace that cursor with a type reference, because we want 
-  // clang_getCursor() to point at the constructor.
-  if (clang_isExpression(BestCursor->kind) &&
-      isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
-      cursor.kind == CXCursor_TypeRef) {
-    // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
-    // as having the actual point on the type reference.
-    *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
-    return CXChildVisit_Recurse;
-  }
-  
-  *BestCursor = cursor;
-  return CXChildVisit_Recurse;
-}
-
-CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
-  if (!TU)
-    return clang_getNullCursor();
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-
-  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
-  CXCursor Result = cxcursor::getCursor(TU, SLoc);
-
-  bool Logging = getenv("LIBCLANG_LOGGING");  
-  if (Logging) {
-    CXFile SearchFile;
-    unsigned SearchLine, SearchColumn;
-    CXFile ResultFile;
-    unsigned ResultLine, ResultColumn;
-    CXString SearchFileName, ResultFileName, KindSpelling, USR;
-    const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
-    CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
-    
-    clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
-    clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
-                               &ResultColumn, 0);
-    SearchFileName = clang_getFileName(SearchFile);
-    ResultFileName = clang_getFileName(ResultFile);
-    KindSpelling = clang_getCursorKindSpelling(Result.kind);
-    USR = clang_getCursorUSR(Result);
-    fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
-            clang_getCString(SearchFileName), SearchLine, SearchColumn,
-            clang_getCString(KindSpelling),
-            clang_getCString(ResultFileName), ResultLine, ResultColumn,
-            clang_getCString(USR), IsDef);
-    clang_disposeString(SearchFileName);
-    clang_disposeString(ResultFileName);
-    clang_disposeString(KindSpelling);
-    clang_disposeString(USR);
-    
-    CXCursor Definition = clang_getCursorDefinition(Result);
-    if (!clang_equalCursors(Definition, clang_getNullCursor())) {
-      CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
-      CXString DefinitionKindSpelling
-                                = clang_getCursorKindSpelling(Definition.kind);
-      CXFile DefinitionFile;
-      unsigned DefinitionLine, DefinitionColumn;
-      clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
-                                 &DefinitionLine, &DefinitionColumn, 0);
-      CXString DefinitionFileName = clang_getFileName(DefinitionFile);
-      fprintf(stderr, "  -> %s(%s:%d:%d)\n",
-              clang_getCString(DefinitionKindSpelling),
-              clang_getCString(DefinitionFileName),
-              DefinitionLine, DefinitionColumn);
-      clang_disposeString(DefinitionFileName);
-      clang_disposeString(DefinitionKindSpelling);
-    }
-  }
-
-  return Result;
-}
-
-CXCursor clang_getNullCursor(void) {
-  return MakeCXCursorInvalid(CXCursor_InvalidFile);
-}
-
-unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
-  return X == Y;
-}
-
-unsigned clang_hashCursor(CXCursor C) {
-  unsigned Index = 0;
-  if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
-    Index = 1;
-  
-  return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
-                                        std::make_pair(C.kind, C.data[Index]));
-}
-
-unsigned clang_isInvalid(enum CXCursorKind K) {
-  return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
-}
-
-unsigned clang_isDeclaration(enum CXCursorKind K) {
-  return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
-         (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
-}
-
-unsigned clang_isReference(enum CXCursorKind K) {
-  return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
-}
-
-unsigned clang_isExpression(enum CXCursorKind K) {
-  return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
-}
-
-unsigned clang_isStatement(enum CXCursorKind K) {
-  return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
-}
-
-unsigned clang_isAttribute(enum CXCursorKind K) {
-    return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
-}
-
-unsigned clang_isTranslationUnit(enum CXCursorKind K) {
-  return K == CXCursor_TranslationUnit;
-}
-
-unsigned clang_isPreprocessing(enum CXCursorKind K) {
-  return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
-}
-  
-unsigned clang_isUnexposed(enum CXCursorKind K) {
-  switch (K) {
-    case CXCursor_UnexposedDecl:
-    case CXCursor_UnexposedExpr:
-    case CXCursor_UnexposedStmt:
-    case CXCursor_UnexposedAttr:
-      return true;
-    default:
-      return false;
-  }
-}
-
-CXCursorKind clang_getCursorKind(CXCursor C) {
-  return C.kind;
-}
-
-CXSourceLocation clang_getCursorLocation(CXCursor C) {
-  if (clang_isReference(C.kind)) {
-    switch (C.kind) {
-    case CXCursor_ObjCSuperClassRef: {
-      std::pair<ObjCInterfaceDecl *, SourceLocation> P
-        = getCursorObjCSuperClassRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_ObjCProtocolRef: {
-      std::pair<ObjCProtocolDecl *, SourceLocation> P
-        = getCursorObjCProtocolRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_ObjCClassRef: {
-      std::pair<ObjCInterfaceDecl *, SourceLocation> P
-        = getCursorObjCClassRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_TypeRef: {
-      std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_TemplateRef: {
-      std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_NamespaceRef: {
-      std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_MemberRef: {
-      std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_VariableRef: {
-      std::pair<VarDecl *, SourceLocation> P = getCursorVariableRef(C);
-      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
-    }
-
-    case CXCursor_CXXBaseSpecifier: {
-      CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
-      if (!BaseSpec)
-        return clang_getNullLocation();
-      
-      if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
-        return cxloc::translateSourceLocation(getCursorContext(C),
-                                            TSInfo->getTypeLoc().getBeginLoc());
-      
-      return cxloc::translateSourceLocation(getCursorContext(C),
-                                        BaseSpec->getLocStart());
-    }
-
-    case CXCursor_LabelRef: {
-      std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
-      return cxloc::translateSourceLocation(getCursorContext(C), P.second);
-    }
-
-    case CXCursor_OverloadedDeclRef:
-      return cxloc::translateSourceLocation(getCursorContext(C),
-                                          getCursorOverloadedDeclRef(C).second);
-
-    default:
-      // FIXME: Need a way to enumerate all non-reference cases.
-      llvm_unreachable("Missed a reference kind");
-    }
-  }
-
-  if (clang_isExpression(C.kind))
-    return cxloc::translateSourceLocation(getCursorContext(C),
-                                   getLocationFromExpr(getCursorExpr(C)));
-
-  if (clang_isStatement(C.kind))
-    return cxloc::translateSourceLocation(getCursorContext(C),
-                                          getCursorStmt(C)->getLocStart());
-
-  if (C.kind == CXCursor_PreprocessingDirective) {
-    SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
-    return cxloc::translateSourceLocation(getCursorContext(C), L);
-  }
-
-  if (C.kind == CXCursor_MacroExpansion) {
-    SourceLocation L
-      = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin();
-    return cxloc::translateSourceLocation(getCursorContext(C), L);
-  }
-
-  if (C.kind == CXCursor_MacroDefinition) {
-    SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
-    return cxloc::translateSourceLocation(getCursorContext(C), L);
-  }
-
-  if (C.kind == CXCursor_InclusionDirective) {
-    SourceLocation L
-      = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
-    return cxloc::translateSourceLocation(getCursorContext(C), L);
-  }
-
-  if (!clang_isDeclaration(C.kind))
-    return clang_getNullLocation();
-
-  Decl *D = getCursorDecl(C);
-  if (!D)
-    return clang_getNullLocation();
-
-  SourceLocation Loc = D->getLocation();
-  // FIXME: Multiple variables declared in a single declaration
-  // currently lack the information needed to correctly determine their
-  // ranges when accounting for the type-specifier.  We use context
-  // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
-  // and if so, whether it is the first decl.
-  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    if (!cxcursor::isFirstInDeclGroup(C))
-      Loc = VD->getLocation();
-  }
-
-  // For ObjC methods, give the start location of the method name.
-  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
-    Loc = MD->getSelectorStartLoc();
-
-  return cxloc::translateSourceLocation(getCursorContext(C), Loc);
-}
-
-} // end extern "C"
-
-CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
-  assert(TU);
-
-  // Guard against an invalid SourceLocation, or we may assert in one
-  // of the following calls.
-  if (SLoc.isInvalid())
-    return clang_getNullCursor();
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-
-  // Translate the given source location to make it point at the beginning of
-  // the token under the cursor.
-  SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
-                                    CXXUnit->getASTContext().getLangOpts());
-  
-  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
-  if (SLoc.isValid()) {
-    GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
-    CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
-                            /*VisitPreprocessorLast=*/true, 
-                            /*VisitIncludedEntities=*/false,
-                            SourceLocation(SLoc));
-    CursorVis.visitFileRegion();
-  }
-
-  return Result;
-}
-
-static SourceRange getRawCursorExtent(CXCursor C) {
-  if (clang_isReference(C.kind)) {
-    switch (C.kind) {
-    case CXCursor_ObjCSuperClassRef:
-      return  getCursorObjCSuperClassRef(C).second;
-
-    case CXCursor_ObjCProtocolRef:
-      return getCursorObjCProtocolRef(C).second;
-
-    case CXCursor_ObjCClassRef:
-      return getCursorObjCClassRef(C).second;
-
-    case CXCursor_TypeRef:
-      return getCursorTypeRef(C).second;
-
-    case CXCursor_TemplateRef:
-      return getCursorTemplateRef(C).second;
-
-    case CXCursor_NamespaceRef:
-      return getCursorNamespaceRef(C).second;
-
-    case CXCursor_MemberRef:
-      return getCursorMemberRef(C).second;
-
-    case CXCursor_CXXBaseSpecifier:
-      return getCursorCXXBaseSpecifier(C)->getSourceRange();
-
-    case CXCursor_LabelRef:
-      return getCursorLabelRef(C).second;
-
-    case CXCursor_OverloadedDeclRef:
-      return getCursorOverloadedDeclRef(C).second;
-
-    case CXCursor_VariableRef:
-      return getCursorVariableRef(C).second;
-        
-    default:
-      // FIXME: Need a way to enumerate all non-reference cases.
-      llvm_unreachable("Missed a reference kind");
-    }
-  }
-
-  if (clang_isExpression(C.kind))
-    return getCursorExpr(C)->getSourceRange();
-
-  if (clang_isStatement(C.kind))
-    return getCursorStmt(C)->getSourceRange();
-
-  if (clang_isAttribute(C.kind))
-    return getCursorAttr(C)->getRange();
-
-  if (C.kind == CXCursor_PreprocessingDirective)
-    return cxcursor::getCursorPreprocessingDirective(C);
-
-  if (C.kind == CXCursor_MacroExpansion) {
-    ASTUnit *TU = getCursorASTUnit(C);
-    SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange();
-    return TU->mapRangeFromPreamble(Range);
-  }
-
-  if (C.kind == CXCursor_MacroDefinition) {
-    ASTUnit *TU = getCursorASTUnit(C);
-    SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
-    return TU->mapRangeFromPreamble(Range);
-  }
-
-  if (C.kind == CXCursor_InclusionDirective) {
-    ASTUnit *TU = getCursorASTUnit(C);
-    SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
-    return TU->mapRangeFromPreamble(Range);
-  }
-
-  if (C.kind == CXCursor_TranslationUnit) {
-    ASTUnit *TU = getCursorASTUnit(C);
-    FileID MainID = TU->getSourceManager().getMainFileID();
-    SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
-    SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
-    return SourceRange(Start, End);
-  }
-
-  if (clang_isDeclaration(C.kind)) {
-    Decl *D = cxcursor::getCursorDecl(C);
-    if (!D)
-      return SourceRange();
-
-    SourceRange R = D->getSourceRange();
-    // FIXME: Multiple variables declared in a single declaration
-    // currently lack the information needed to correctly determine their
-    // ranges when accounting for the type-specifier.  We use context
-    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
-    // and if so, whether it is the first decl.
-    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-      if (!cxcursor::isFirstInDeclGroup(C))
-        R.setBegin(VD->getLocation());
-    }
-    return R;
-  }
-  return SourceRange();
-}
-
-/// \brief Retrieves the "raw" cursor extent, which is then extended to include
-/// the decl-specifier-seq for declarations.
-static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
-  if (clang_isDeclaration(C.kind)) {
-    Decl *D = cxcursor::getCursorDecl(C);
-    if (!D)
-      return SourceRange();
-
-    SourceRange R = D->getSourceRange();
-
-    // Adjust the start of the location for declarations preceded by
-    // declaration specifiers.
-    SourceLocation StartLoc;
-    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
-      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
-        StartLoc = TI->getTypeLoc().getLocStart();
-    } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
-      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
-        StartLoc = TI->getTypeLoc().getLocStart();
-    }
-
-    if (StartLoc.isValid() && R.getBegin().isValid() &&
-        SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
-      R.setBegin(StartLoc);
-
-    // FIXME: Multiple variables declared in a single declaration
-    // currently lack the information needed to correctly determine their
-    // ranges when accounting for the type-specifier.  We use context
-    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
-    // and if so, whether it is the first decl.
-    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-      if (!cxcursor::isFirstInDeclGroup(C))
-        R.setBegin(VD->getLocation());
-    }
-
-    return R;    
-  }
-  
-  return getRawCursorExtent(C);
-}
-
-extern "C" {
-
-CXSourceRange clang_getCursorExtent(CXCursor C) {
-  SourceRange R = getRawCursorExtent(C);
-  if (R.isInvalid())
-    return clang_getNullRange();
-
-  return cxloc::translateSourceRange(getCursorContext(C), R);
-}
-
-CXCursor clang_getCursorReferenced(CXCursor C) {
-  if (clang_isInvalid(C.kind))
-    return clang_getNullCursor();
-
-  CXTranslationUnit tu = getCursorTU(C);
-  if (clang_isDeclaration(C.kind)) {
-    Decl *D = getCursorDecl(C);
-    if (!D)
-      return clang_getNullCursor();
-    if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
-      return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
-    if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
-      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
-        return MakeCXCursor(Property, tu);
-    
-    return C;
-  }
-  
-  if (clang_isExpression(C.kind)) {
-    Expr *E = getCursorExpr(C);
-    Decl *D = getDeclFromExpr(E);
-    if (D) {
-      CXCursor declCursor = MakeCXCursor(D, tu);
-      declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
-                                               declCursor);
-      return declCursor;
-    }
-    
-    if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
-      return MakeCursorOverloadedDeclRef(Ovl, tu);
-        
-    return clang_getNullCursor();
-  }
-
-  if (clang_isStatement(C.kind)) {
-    Stmt *S = getCursorStmt(C);
-    if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
-      if (LabelDecl *label = Goto->getLabel())
-        if (LabelStmt *labelS = label->getStmt())
-        return MakeCXCursor(labelS, getCursorDecl(C), tu);
-
-    return clang_getNullCursor();
-  }
-  
-  if (C.kind == CXCursor_MacroExpansion) {
-    if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition())
-      return MakeMacroDefinitionCursor(Def, tu);
-  }
-
-  if (!clang_isReference(C.kind))
-    return clang_getNullCursor();
-
-  switch (C.kind) {
-    case CXCursor_ObjCSuperClassRef:
-      return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
-
-    case CXCursor_ObjCProtocolRef: {
-      ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
-      if (ObjCProtocolDecl *Def = Prot->getDefinition())
-        return MakeCXCursor(Def, tu);
-
-      return MakeCXCursor(Prot, tu);
-    }
-
-    case CXCursor_ObjCClassRef: {
-      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
-      if (ObjCInterfaceDecl *Def = Class->getDefinition())
-        return MakeCXCursor(Def, tu);
-
-      return MakeCXCursor(Class, tu);
-    }
-
-    case CXCursor_TypeRef:
-      return MakeCXCursor(getCursorTypeRef(C).first, tu );
-
-    case CXCursor_TemplateRef:
-      return MakeCXCursor(getCursorTemplateRef(C).first, tu );
-
-    case CXCursor_NamespaceRef:
-      return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
-
-    case CXCursor_MemberRef:
-      return MakeCXCursor(getCursorMemberRef(C).first, tu );
-
-    case CXCursor_CXXBaseSpecifier: {
-      CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
-      return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
-                                                         tu ));
-    }
-
-    case CXCursor_LabelRef:
-      // FIXME: We end up faking the "parent" declaration here because we
-      // don't want to make CXCursor larger.
-      return MakeCXCursor(getCursorLabelRef(C).first, 
-               static_cast<ASTUnit*>(tu->TUData)->getASTContext()
-                          .getTranslationUnitDecl(),
-                          tu);
-
-    case CXCursor_OverloadedDeclRef:
-      return C;
-      
-    case CXCursor_VariableRef:
-      return MakeCXCursor(getCursorVariableRef(C).first, tu);
-
-    default:
-      // We would prefer to enumerate all non-reference cursor kinds here.
-      llvm_unreachable("Unhandled reference cursor kind");
-  }
-}
-
-CXCursor clang_getCursorDefinition(CXCursor C) {
-  if (clang_isInvalid(C.kind))
-    return clang_getNullCursor();
-
-  CXTranslationUnit TU = getCursorTU(C);
-
-  bool WasReference = false;
-  if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
-    C = clang_getCursorReferenced(C);
-    WasReference = true;
-  }
-
-  if (C.kind == CXCursor_MacroExpansion)
-    return clang_getCursorReferenced(C);
-
-  if (!clang_isDeclaration(C.kind))
-    return clang_getNullCursor();
-
-  Decl *D = getCursorDecl(C);
-  if (!D)
-    return clang_getNullCursor();
-
-  switch (D->getKind()) {
-  // Declaration kinds that don't really separate the notions of
-  // declaration and definition.
-  case Decl::Namespace:
-  case Decl::Typedef:
-  case Decl::TypeAlias:
-  case Decl::TypeAliasTemplate:
-  case Decl::TemplateTypeParm:
-  case Decl::EnumConstant:
-  case Decl::Field:
-  case Decl::IndirectField:
-  case Decl::ObjCIvar:
-  case Decl::ObjCAtDefsField:
-  case Decl::ImplicitParam:
-  case Decl::ParmVar:
-  case Decl::NonTypeTemplateParm:
-  case Decl::TemplateTemplateParm:
-  case Decl::ObjCCategoryImpl:
-  case Decl::ObjCImplementation:
-  case Decl::AccessSpec:
-  case Decl::LinkageSpec:
-  case Decl::ObjCPropertyImpl:
-  case Decl::FileScopeAsm:
-  case Decl::StaticAssert:
-  case Decl::Block:
-  case Decl::Label:  // FIXME: Is this right??
-  case Decl::ClassScopeFunctionSpecialization:
-  case Decl::Import:
-    return C;
-
-  // Declaration kinds that don't make any sense here, but are
-  // nonetheless harmless.
-  case Decl::TranslationUnit:
-    break;
-
-  // Declaration kinds for which the definition is not resolvable.
-  case Decl::UnresolvedUsingTypename:
-  case Decl::UnresolvedUsingValue:
-    break;
-
-  case Decl::UsingDirective:
-    return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
-                        TU);
-
-  case Decl::NamespaceAlias:
-    return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
-
-  case Decl::Enum:
-  case Decl::Record:
-  case Decl::CXXRecord:
-  case Decl::ClassTemplateSpecialization:
-  case Decl::ClassTemplatePartialSpecialization:
-    if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
-      return MakeCXCursor(Def, TU);
-    return clang_getNullCursor();
-
-  case Decl::Function:
-  case Decl::CXXMethod:
-  case Decl::CXXConstructor:
-  case Decl::CXXDestructor:
-  case Decl::CXXConversion: {
-    const FunctionDecl *Def = 0;
-    if (cast<FunctionDecl>(D)->getBody(Def))
-      return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
-    return clang_getNullCursor();
-  }
-
-  case Decl::Var: {
-    // Ask the variable if it has a definition.
-    if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
-      return MakeCXCursor(Def, TU);
-    return clang_getNullCursor();
-  }
-
-  case Decl::FunctionTemplate: {
-    const FunctionDecl *Def = 0;
-    if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
-      return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
-    return clang_getNullCursor();
-  }
-
-  case Decl::ClassTemplate: {
-    if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
-                                                            ->getDefinition())
-      return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
-                          TU);
-    return clang_getNullCursor();
-  }
-
-  case Decl::Using:
-    return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 
-                                       D->getLocation(), TU);
-
-  case Decl::UsingShadow:
-    return clang_getCursorDefinition(
-                       MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
-                                    TU));
-
-  case Decl::ObjCMethod: {
-    ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
-    if (Method->isThisDeclarationADefinition())
-      return C;
-
-    // Dig out the method definition in the associated
-    // @implementation, if we have it.
-    // FIXME: The ASTs should make finding the definition easier.
-    if (ObjCInterfaceDecl *Class
-                       = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
-      if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
-        if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
-                                                  Method->isInstanceMethod()))
-          if (Def->isThisDeclarationADefinition())
-            return MakeCXCursor(Def, TU);
-
-    return clang_getNullCursor();
-  }
-
-  case Decl::ObjCCategory:
-    if (ObjCCategoryImplDecl *Impl
-                               = cast<ObjCCategoryDecl>(D)->getImplementation())
-      return MakeCXCursor(Impl, TU);
-    return clang_getNullCursor();
-
-  case Decl::ObjCProtocol:
-    if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
-      return MakeCXCursor(Def, TU);
-    return clang_getNullCursor();
-
-  case Decl::ObjCInterface: {
-    // There are two notions of a "definition" for an Objective-C
-    // class: the interface and its implementation. When we resolved a
-    // reference to an Objective-C class, produce the @interface as
-    // the definition; when we were provided with the interface,
-    // produce the @implementation as the definition.
-    ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
-    if (WasReference) {
-      if (ObjCInterfaceDecl *Def = IFace->getDefinition())
-        return MakeCXCursor(Def, TU);
-    } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
-      return MakeCXCursor(Impl, TU);
-    return clang_getNullCursor();
-  }
-
-  case Decl::ObjCProperty:
-    // FIXME: We don't really know where to find the
-    // ObjCPropertyImplDecls that implement this property.
-    return clang_getNullCursor();
-
-  case Decl::ObjCCompatibleAlias:
-    if (ObjCInterfaceDecl *Class
-          = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
-      if (ObjCInterfaceDecl *Def = Class->getDefinition())
-        return MakeCXCursor(Def, TU);
-
-    return clang_getNullCursor();
-
-  case Decl::Friend:
-    if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
-      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
-    return clang_getNullCursor();
-
-  case Decl::FriendTemplate:
-    if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
-      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
-    return clang_getNullCursor();
-  }
-
-  return clang_getNullCursor();
-}
-
-unsigned clang_isCursorDefinition(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return 0;
-
-  return clang_getCursorDefinition(C) == C;
-}
-
-CXCursor clang_getCanonicalCursor(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return C;
-  
-  if (Decl *D = getCursorDecl(C)) {
-    if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
-      if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
-        return MakeCXCursor(CatD, getCursorTU(C));
-
-    if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
-      if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
-        return MakeCXCursor(IFD, getCursorTU(C));
-
-    return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
-  }
-  
-  return C;
-}
-
-int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
-  return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
-}
-  
-unsigned clang_getNumOverloadedDecls(CXCursor C) {
-  if (C.kind != CXCursor_OverloadedDeclRef)
-    return 0;
-  
-  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
-  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
-    return E->getNumDecls();
-  
-  if (OverloadedTemplateStorage *S
-                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
-    return S->size();
-  
-  Decl *D = Storage.get<Decl*>();
-  if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
-    return Using->shadow_size();
-  
-  return 0;
-}
-
-CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
-  if (cursor.kind != CXCursor_OverloadedDeclRef)
-    return clang_getNullCursor();
-
-  if (index >= clang_getNumOverloadedDecls(cursor))
-    return clang_getNullCursor();
-  
-  CXTranslationUnit TU = getCursorTU(cursor);
-  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
-  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
-    return MakeCXCursor(E->decls_begin()[index], TU);
-  
-  if (OverloadedTemplateStorage *S
-                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
-    return MakeCXCursor(S->begin()[index], TU);
-  
-  Decl *D = Storage.get<Decl*>();
-  if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
-    // FIXME: This is, unfortunately, linear time.
-    UsingDecl::shadow_iterator Pos = Using->shadow_begin();
-    std::advance(Pos, index);
-    return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
-  }
-  
-  return clang_getNullCursor();
-}
-  
-void clang_getDefinitionSpellingAndExtent(CXCursor C,
-                                          const char **startBuf,
-                                          const char **endBuf,
-                                          unsigned *startLine,
-                                          unsigned *startColumn,
-                                          unsigned *endLine,
-                                          unsigned *endColumn) {
-  assert(getCursorDecl(C) && "CXCursor has null decl");
-  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
-  CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
-
-  SourceManager &SM = FD->getASTContext().getSourceManager();
-  *startBuf = SM.getCharacterData(Body->getLBracLoc());
-  *endBuf = SM.getCharacterData(Body->getRBracLoc());
-  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
-  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
-  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
-  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
-}
-
-
-CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
-                                                unsigned PieceIndex) {
-  RefNamePieces Pieces;
-  
-  switch (C.kind) {
-  case CXCursor_MemberRefExpr:
-    if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
-      Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
-                           E->getQualifierLoc().getSourceRange());
-    break;
-  
-  case CXCursor_DeclRefExpr:
-    if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
-      Pieces = buildPieces(NameFlags, false, E->getNameInfo(), 
-                           E->getQualifierLoc().getSourceRange(),
-                           E->getOptionalExplicitTemplateArgs());
-    break;
-    
-  case CXCursor_CallExpr:
-    if (CXXOperatorCallExpr *OCE = 
-        dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
-      Expr *Callee = OCE->getCallee();
-      if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
-        Callee = ICE->getSubExpr();
-
-      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
-        Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
-                             DRE->getQualifierLoc().getSourceRange());
-    }
-    break;
-    
-  default:
-    break;
-  }
-
-  if (Pieces.empty()) {
-    if (PieceIndex == 0)
-      return clang_getCursorExtent(C);
-  } else if (PieceIndex < Pieces.size()) {
-      SourceRange R = Pieces[PieceIndex];
-      if (R.isValid())
-        return cxloc::translateSourceRange(getCursorContext(C), R);
-  }
-  
-  return clang_getNullRange();
-}
-
-void clang_enableStackTraces(void) {
-  llvm::sys::PrintStackTraceOnErrorSignal();
-}
-
-void clang_executeOnThread(void (*fn)(void*), void *user_data,
-                           unsigned stack_size) {
-  llvm::llvm_execute_on_thread(fn, user_data, stack_size);
-}
-
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// Token-based Operations.
-//===----------------------------------------------------------------------===//
-
-/* CXToken layout:
- *   int_data[0]: a CXTokenKind
- *   int_data[1]: starting token location
- *   int_data[2]: token length
- *   int_data[3]: reserved
- *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
- *   otherwise unused.
- */
-extern "C" {
-
-CXTokenKind clang_getTokenKind(CXToken CXTok) {
-  return static_cast<CXTokenKind>(CXTok.int_data[0]);
-}
-
-CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
-  switch (clang_getTokenKind(CXTok)) {
-  case CXToken_Identifier:
-  case CXToken_Keyword:
-    // We know we have an IdentifierInfo*, so use that.
-    return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
-                            ->getNameStart());
-
-  case CXToken_Literal: {
-    // We have stashed the starting pointer in the ptr_data field. Use it.
-    const char *Text = static_cast<const char *>(CXTok.ptr_data);
-    return createCXString(StringRef(Text, CXTok.int_data[2]));
-  }
-
-  case CXToken_Punctuation:
-  case CXToken_Comment:
-    break;
-  }
-
-  // We have to find the starting buffer pointer the hard way, by
-  // deconstructing the source location.
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  if (!CXXUnit)
-    return createCXString("");
-
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
-  std::pair<FileID, unsigned> LocInfo
-    = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
-  bool Invalid = false;
-  StringRef Buffer
-    = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
-  if (Invalid)
-    return createCXString("");
-
-  return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
-}
-
-CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  if (!CXXUnit)
-    return clang_getNullLocation();
-
-  return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
-                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
-}
-
-CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  if (!CXXUnit)
-    return clang_getNullRange();
-
-  return cxloc::translateSourceRange(CXXUnit->getASTContext(),
-                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
-}
-
-static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
-                      SmallVectorImpl<CXToken> &CXTokens) {
-  SourceManager &SourceMgr = CXXUnit->getSourceManager();
-  std::pair<FileID, unsigned> BeginLocInfo
-    = SourceMgr.getDecomposedLoc(Range.getBegin());
-  std::pair<FileID, unsigned> EndLocInfo
-    = SourceMgr.getDecomposedLoc(Range.getEnd());
-
-  // Cannot tokenize across files.
-  if (BeginLocInfo.first != EndLocInfo.first)
-    return;
-
-  // Create a lexer
-  bool Invalid = false;
-  StringRef Buffer
-    = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
-  if (Invalid)
-    return;
-  
-  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
-            CXXUnit->getASTContext().getLangOpts(),
-            Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
-  Lex.SetCommentRetentionState(true);
-
-  // Lex tokens until we hit the end of the range.
-  const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
-  Token Tok;
-  bool previousWasAt = false;
-  do {
-    // Lex the next token
-    Lex.LexFromRawLexer(Tok);
-    if (Tok.is(tok::eof))
-      break;
-
-    // Initialize the CXToken.
-    CXToken CXTok;
-
-    //   - Common fields
-    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
-    CXTok.int_data[2] = Tok.getLength();
-    CXTok.int_data[3] = 0;
-
-    //   - Kind-specific fields
-    if (Tok.isLiteral()) {
-      CXTok.int_data[0] = CXToken_Literal;
-      CXTok.ptr_data = (void *)Tok.getLiteralData();
-    } else if (Tok.is(tok::raw_identifier)) {
-      // Lookup the identifier to determine whether we have a keyword.
-      IdentifierInfo *II
-        = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
-
-      if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
-        CXTok.int_data[0] = CXToken_Keyword;
-      }
-      else {
-        CXTok.int_data[0] = Tok.is(tok::identifier)
-          ? CXToken_Identifier
-          : CXToken_Keyword;
-      }
-      CXTok.ptr_data = II;
-    } else if (Tok.is(tok::comment)) {
-      CXTok.int_data[0] = CXToken_Comment;
-      CXTok.ptr_data = 0;
-    } else {
-      CXTok.int_data[0] = CXToken_Punctuation;
-      CXTok.ptr_data = 0;
-    }
-    CXTokens.push_back(CXTok);
-    previousWasAt = Tok.is(tok::at);
-  } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
-}
-
-void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
-                    CXToken **Tokens, unsigned *NumTokens) {
-  if (Tokens)
-    *Tokens = 0;
-  if (NumTokens)
-    *NumTokens = 0;
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  if (!CXXUnit || !Tokens || !NumTokens)
-    return;
-
-  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-  
-  SourceRange R = cxloc::translateCXSourceRange(Range);
-  if (R.isInvalid())
-    return;
-
-  SmallVector<CXToken, 32> CXTokens;
-  getTokens(CXXUnit, R, CXTokens);
-
-  if (CXTokens.empty())
-    return;
-
-  *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
-  memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
-  *NumTokens = CXTokens.size();
-}
-
-void clang_disposeTokens(CXTranslationUnit TU,
-                         CXToken *Tokens, unsigned NumTokens) {
-  free(Tokens);
-}
-
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// Token annotation APIs.
-//===----------------------------------------------------------------------===//
-
-typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
-static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
-                                                     CXCursor parent,
-                                                     CXClientData client_data);
-static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
-                                              CXClientData client_data);
-
-namespace {
-class AnnotateTokensWorker {
-  AnnotateTokensData &Annotated;
-  CXToken *Tokens;
-  CXCursor *Cursors;
-  unsigned NumTokens;
-  unsigned TokIdx;
-  unsigned PreprocessingTokIdx;
-  CursorVisitor AnnotateVis;
-  SourceManager &SrcMgr;
-  bool HasContextSensitiveKeywords;
-
-  struct PostChildrenInfo {
-    CXCursor Cursor;
-    SourceRange CursorRange;
-    unsigned BeforeChildrenTokenIdx;
-  };
-  llvm::SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
-  
-  bool MoreTokens() const { return TokIdx < NumTokens; }
-  unsigned NextToken() const { return TokIdx; }
-  void AdvanceToken() { ++TokIdx; }
-  SourceLocation GetTokenLoc(unsigned tokI) {
-    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
-  }
-  bool isFunctionMacroToken(unsigned tokI) const {
-    return Tokens[tokI].int_data[3] != 0;
-  }
-  SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
-    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
-  }
-
-  void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
-  void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
-                                             SourceRange);
-
-public:
-  AnnotateTokensWorker(AnnotateTokensData &annotated,
-                       CXToken *tokens, CXCursor *cursors, unsigned numTokens,
-                       CXTranslationUnit tu, SourceRange RegionOfInterest)
-    : Annotated(annotated), Tokens(tokens), Cursors(cursors),
-      NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
-      AnnotateVis(tu,
-                  AnnotateTokensVisitor, this,
-                  /*VisitPreprocessorLast=*/true,
-                  /*VisitIncludedEntities=*/false,
-                  RegionOfInterest,
-                  /*VisitDeclsOnly=*/false,
-                  AnnotateTokensPostChildrenVisitor),
-      SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
-      HasContextSensitiveKeywords(false) { }
-
-  void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
-  enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
-  bool postVisitChildren(CXCursor cursor);
-  void AnnotateTokens();
-  
-  /// \brief Determine whether the annotator saw any cursors that have 
-  /// context-sensitive keywords.
-  bool hasContextSensitiveKeywords() const {
-    return HasContextSensitiveKeywords;
-  }
-
-  ~AnnotateTokensWorker() {
-    assert(PostChildrenInfos.empty());
-  }
-};
-}
-
-void AnnotateTokensWorker::AnnotateTokens() {
-  // Walk the AST within the region of interest, annotating tokens
-  // along the way.
-  AnnotateVis.visitFileRegion();
-
-  for (unsigned I = 0 ; I < TokIdx ; ++I) {
-    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
-    if (Pos != Annotated.end() && !clang_isPreprocessing(Cursors[I].kind))
-      Cursors[I] = Pos->second;
-  }
-
-  // Finish up annotating any tokens left.
-  if (!MoreTokens())
-    return;
-
-  const CXCursor &C = clang_getNullCursor();
-  for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
-    if (I < PreprocessingTokIdx && clang_isPreprocessing(Cursors[I].kind))
-      continue;
-
-    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
-    Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
-  }
-}
-
-/// \brief It annotates and advances tokens with a cursor until the comparison
-//// between the cursor location and the source range is the same as
-/// \arg compResult.
-///
-/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
-/// Pass RangeOverlap to annotate tokens inside a range.
-void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
-                                               RangeComparisonResult compResult,
-                                               SourceRange range) {
-  while (MoreTokens()) {
-    const unsigned I = NextToken();
-    if (isFunctionMacroToken(I))
-      return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
-
-    SourceLocation TokLoc = GetTokenLoc(I);
-    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
-      Cursors[I] = updateC;
-      AdvanceToken();
-      continue;
-    }
-    break;
-  }
-}
-
-/// \brief Special annotation handling for macro argument tokens.
-void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
-                                               CXCursor updateC,
-                                               RangeComparisonResult compResult,
-                                               SourceRange range) {
-  assert(MoreTokens());
-  assert(isFunctionMacroToken(NextToken()) &&
-         "Should be called only for macro arg tokens");
-
-  // This works differently than annotateAndAdvanceTokens; because expanded
-  // macro arguments can have arbitrary translation-unit source order, we do not
-  // advance the token index one by one until a token fails the range test.
-  // We only advance once past all of the macro arg tokens if all of them
-  // pass the range test. If one of them fails we keep the token index pointing
-  // at the start of the macro arg tokens so that the failing token will be
-  // annotated by a subsequent annotation try.
-
-  bool atLeastOneCompFail = false;
-  
-  unsigned I = NextToken();
-  for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
-    SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
-    if (TokLoc.isFileID())
-      continue; // not macro arg token, it's parens or comma.
-    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
-      if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
-        Cursors[I] = updateC;
-    } else
-      atLeastOneCompFail = true;
-  }
-
-  if (!atLeastOneCompFail)
-    TokIdx = I; // All of the tokens were handled, advance beyond all of them.
-}
-
-enum CXChildVisitResult
-AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {  
-  CXSourceLocation Loc = clang_getCursorLocation(cursor);
-  SourceRange cursorRange = getRawCursorExtent(cursor);
-  if (cursorRange.isInvalid())
-    return CXChildVisit_Recurse;
-      
-  if (!HasContextSensitiveKeywords) {
-    // Objective-C properties can have context-sensitive keywords.
-    if (cursor.kind == CXCursor_ObjCPropertyDecl) {
-      if (ObjCPropertyDecl *Property 
-                  = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
-        HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
-    }
-    // Objective-C methods can have context-sensitive keywords.
-    else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
-             cursor.kind == CXCursor_ObjCClassMethodDecl) {
-      if (ObjCMethodDecl *Method
-            = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
-        if (Method->getObjCDeclQualifier())
-          HasContextSensitiveKeywords = true;
-        else {
-          for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
-                                           PEnd = Method->param_end();
-               P != PEnd; ++P) {
-            if ((*P)->getObjCDeclQualifier()) {
-              HasContextSensitiveKeywords = true;
-              break;
-            }
-          }
-        }
-      }
-    }    
-    // C++ methods can have context-sensitive keywords.
-    else if (cursor.kind == CXCursor_CXXMethod) {
-      if (CXXMethodDecl *Method
-                  = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
-        if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
-          HasContextSensitiveKeywords = true;
-      }
-    }
-    // C++ classes can have context-sensitive keywords.
-    else if (cursor.kind == CXCursor_StructDecl ||
-             cursor.kind == CXCursor_ClassDecl ||
-             cursor.kind == CXCursor_ClassTemplate ||
-             cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
-      if (Decl *D = getCursorDecl(cursor))
-        if (D->hasAttr<FinalAttr>())
-          HasContextSensitiveKeywords = true;
-    }
-  }
-  
-  if (clang_isPreprocessing(cursor.kind)) {    
-    // Items in the preprocessing record are kept separate from items in
-    // declarations, so we keep a separate token index.
-    unsigned SavedTokIdx = TokIdx;
-    TokIdx = PreprocessingTokIdx;
-
-    // Skip tokens up until we catch up to the beginning of the preprocessing
-    // entry.
-    while (MoreTokens()) {
-      const unsigned I = NextToken();
-      SourceLocation TokLoc = GetTokenLoc(I);
-      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
-      case RangeBefore:
-        AdvanceToken();
-        continue;
-      case RangeAfter:
-      case RangeOverlap:
-        break;
-      }
-      break;
-    }
-    
-    // Look at all of the tokens within this range.
-    while (MoreTokens()) {
-      const unsigned I = NextToken();
-      SourceLocation TokLoc = GetTokenLoc(I);
-      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
-      case RangeBefore:
-        llvm_unreachable("Infeasible");
-      case RangeAfter:
-        break;
-      case RangeOverlap:
-        Cursors[I] = cursor;
-        AdvanceToken();
-        // For macro expansions, just note where the beginning of the macro
-        // expansion occurs.
-        if (cursor.kind == CXCursor_MacroExpansion)
-          break;
-        continue;
-      }
-      break;
-    }
-
-    // Save the preprocessing token index; restore the non-preprocessing
-    // token index.
-    PreprocessingTokIdx = TokIdx;
-    TokIdx = SavedTokIdx;
-    return CXChildVisit_Recurse;
-  }
-
-  if (cursorRange.isInvalid())
-    return CXChildVisit_Continue;
-  
-  SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
-
-  // Adjust the annotated range based specific declarations.
-  const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
-  if (clang_isDeclaration(cursorK)) {
-    Decl *D = cxcursor::getCursorDecl(cursor);
-    
-    SourceLocation StartLoc;
-    if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(D)) {
-      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
-        StartLoc = TI->getTypeLoc().getLocStart();
-    } else if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(D)) {
-      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
-        StartLoc = TI->getTypeLoc().getLocStart();
-    }
-
-    if (StartLoc.isValid() && L.isValid() &&
-        SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
-      cursorRange.setBegin(StartLoc);
-  }
-  
-  // If the location of the cursor occurs within a macro instantiation, record
-  // the spelling location of the cursor in our annotation map.  We can then
-  // paper over the token labelings during a post-processing step to try and
-  // get cursor mappings for tokens that are the *arguments* of a macro
-  // instantiation.
-  if (L.isMacroID()) {
-    unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
-    // Only invalidate the old annotation if it isn't part of a preprocessing
-    // directive.  Here we assume that the default construction of CXCursor
-    // results in CXCursor.kind being an initialized value (i.e., 0).  If
-    // this isn't the case, we can fix by doing lookup + insertion.
-    
-    CXCursor &oldC = Annotated[rawEncoding];
-    if (!clang_isPreprocessing(oldC.kind))
-      oldC = cursor;
-  }
-  
-  const enum CXCursorKind K = clang_getCursorKind(parent);
-  const CXCursor updateC =
-    (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
-     ? clang_getNullCursor() : parent;
-
-  annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
-
-  // Avoid having the cursor of an expression "overwrite" the annotation of the
-  // variable declaration that it belongs to.
-  // This can happen for C++ constructor expressions whose range generally
-  // include the variable declaration, e.g.:
-  //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
-  if (clang_isExpression(cursorK)) {
-    Expr *E = getCursorExpr(cursor);
-    if (Decl *D = getCursorParentDecl(cursor)) {
-      const unsigned I = NextToken();
-      if (E->getLocStart().isValid() && D->getLocation().isValid() &&
-          E->getLocStart() == D->getLocation() &&
-          E->getLocStart() == GetTokenLoc(I)) {
-        Cursors[I] = updateC;
-        AdvanceToken();
-      }
-    }
-  }
-
-  // Before recursing into the children keep some state that we are going
-  // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
-  // extra work after the child nodes are visited.
-  // Note that we don't call VisitChildren here to avoid traversing statements
-  // code-recursively which can blow the stack.
-
-  PostChildrenInfo Info;
-  Info.Cursor = cursor;
-  Info.CursorRange = cursorRange;
-  Info.BeforeChildrenTokenIdx = NextToken();
-  PostChildrenInfos.push_back(Info);
-
-  return CXChildVisit_Recurse;
-}
-
-bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
-  if (PostChildrenInfos.empty())
-    return false;
-  const PostChildrenInfo &Info = PostChildrenInfos.back();
-  if (!clang_equalCursors(Info.Cursor, cursor))
-    return false;
-
-  const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
-  const unsigned AfterChildren = NextToken();
-  SourceRange cursorRange = Info.CursorRange;
-
-  // Scan the tokens that are at the end of the cursor, but are not captured
-  // but the child cursors.
-  annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
-
-  // Scan the tokens that are at the beginning of the cursor, but are not
-  // capture by the child cursors.
-  for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
-    if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
-      break;
-
-    Cursors[I] = cursor;
-  }
-
-  PostChildrenInfos.pop_back();
-  return false;
-}
-
-static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
-                                                     CXCursor parent,
-                                                     CXClientData client_data) {
-  return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
-}
-
-static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
-                                              CXClientData client_data) {
-  return static_cast<AnnotateTokensWorker*>(client_data)->
-                                                      postVisitChildren(cursor);
-}
-
-namespace {
-
-/// \brief Uses the macro expansions in the preprocessing record to find
-/// and mark tokens that are macro arguments. This info is used by the
-/// AnnotateTokensWorker.
-class MarkMacroArgTokensVisitor {
-  SourceManager &SM;
-  CXToken *Tokens;
-  unsigned NumTokens;
-  unsigned CurIdx;
-  
-public:
-  MarkMacroArgTokensVisitor(SourceManager &SM,
-                            CXToken *tokens, unsigned numTokens)
-    : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
-
-  CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
-    if (cursor.kind != CXCursor_MacroExpansion)
-      return CXChildVisit_Continue;
-
-    SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
-    if (macroRange.getBegin() == macroRange.getEnd())
-      return CXChildVisit_Continue; // it's not a function macro.
-
-    for (; CurIdx < NumTokens; ++CurIdx) {
-      if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
-                                        macroRange.getBegin()))
-        break;
-    }
-    
-    if (CurIdx == NumTokens)
-      return CXChildVisit_Break;
-
-    for (; CurIdx < NumTokens; ++CurIdx) {
-      SourceLocation tokLoc = getTokenLoc(CurIdx);
-      if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
-        break;
-
-      setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
-    }
-
-    if (CurIdx == NumTokens)
-      return CXChildVisit_Break;
-
-    return CXChildVisit_Continue;
-  }
-
-private:
-  SourceLocation getTokenLoc(unsigned tokI) {
-    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
-  }
-
-  void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
-    // The third field is reserved and currently not used. Use it here
-    // to mark macro arg expanded tokens with their expanded locations.
-    Tokens[tokI].int_data[3] = loc.getRawEncoding();
-  }
-};
-
-} // end anonymous namespace
-
-static CXChildVisitResult
-MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
-                                  CXClientData client_data) {
-  return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
-                                                                     parent);
-}
-
-namespace {
-  struct clang_annotateTokens_Data {
-    CXTranslationUnit TU;
-    ASTUnit *CXXUnit;
-    CXToken *Tokens;
-    unsigned NumTokens;
-    CXCursor *Cursors;
-  };
-}
-
-static void annotatePreprocessorTokens(CXTranslationUnit TU,
-                                       SourceRange RegionOfInterest,
-                                       AnnotateTokensData &Annotated) {
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-
-  SourceManager &SourceMgr = CXXUnit->getSourceManager();
-  std::pair<FileID, unsigned> BeginLocInfo
-    = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
-  std::pair<FileID, unsigned> EndLocInfo
-    = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
-
-  if (BeginLocInfo.first != EndLocInfo.first)
-    return;
-
-  StringRef Buffer;
-  bool Invalid = false;
-  Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
-  if (Buffer.empty() || Invalid)
-    return;
-
-  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
-            CXXUnit->getASTContext().getLangOpts(),
-            Buffer.begin(), Buffer.data() + BeginLocInfo.second,
-            Buffer.end());
-  Lex.SetCommentRetentionState(true);
-  
-  // Lex tokens in raw mode until we hit the end of the range, to avoid
-  // entering #includes or expanding macros.
-  while (true) {
-    Token Tok;
-    Lex.LexFromRawLexer(Tok);
-    
-  reprocess:
-    if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
-      // We have found a preprocessing directive. Gobble it up so that we
-      // don't see it while preprocessing these tokens later, but keep track
-      // of all of the token locations inside this preprocessing directive so
-      // that we can annotate them appropriately.
-      //
-      // FIXME: Some simple tests here could identify macro definitions and
-      // #undefs, to provide specific cursor kinds for those.
-      SmallVector<SourceLocation, 32> Locations;
-      do {
-        Locations.push_back(Tok.getLocation());
-        Lex.LexFromRawLexer(Tok);
-      } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
-      
-      using namespace cxcursor;
-      CXCursor Cursor
-      = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
-                                                     Locations.back()),
-                                         TU);
-      for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
-        Annotated[Locations[I].getRawEncoding()] = Cursor;
-      }
-      
-      if (Tok.isAtStartOfLine())
-        goto reprocess;
-      
-      continue;
-    }
-    
-    if (Tok.is(tok::eof))
-      break;
-  }
-}
-
-// This gets run a separate thread to avoid stack blowout.
-static void clang_annotateTokensImpl(void *UserData) {
-  CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
-  ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
-  CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
-  const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
-  CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
-
-  CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
-  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
-    setThreadBackgroundPriority();
-
-  // Determine the region of interest, which contains all of the tokens.
-  SourceRange RegionOfInterest;
-  RegionOfInterest.setBegin(
-    cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
-  RegionOfInterest.setEnd(
-    cxloc::translateSourceLocation(clang_getTokenLocation(TU,
-                                                         Tokens[NumTokens-1])));
-
-  // A mapping from the source locations found when re-lexing or traversing the
-  // region of interest to the corresponding cursors.
-  AnnotateTokensData Annotated;
-
-  // Relex the tokens within the source range to look for preprocessing
-  // directives.
-  annotatePreprocessorTokens(TU, RegionOfInterest, Annotated);
-  
-  if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
-    // Search and mark tokens that are macro argument expansions.
-    MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
-                                      Tokens, NumTokens);
-    CursorVisitor MacroArgMarker(TU,
-                                 MarkMacroArgTokensVisitorDelegate, &Visitor,
-                                 /*VisitPreprocessorLast=*/true,
-                                 /*VisitIncludedEntities=*/false,
-                                 RegionOfInterest);
-    MacroArgMarker.visitPreprocessedEntitiesInRegion();
-  }
-  
-  // Annotate all of the source locations in the region of interest that map to
-  // a specific cursor.
-  AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
-                         TU, RegionOfInterest);
-  
-  // FIXME: We use a ridiculous stack size here because the data-recursion
-  // algorithm uses a large stack frame than the non-data recursive version,
-  // and AnnotationTokensWorker currently transforms the data-recursion
-  // algorithm back into a traditional recursion by explicitly calling
-  // VisitChildren().  We will need to remove this explicit recursive call.
-  W.AnnotateTokens();
-
-  // If we ran into any entities that involve context-sensitive keywords,
-  // take another pass through the tokens to mark them as such.
-  if (W.hasContextSensitiveKeywords()) {
-    for (unsigned I = 0; I != NumTokens; ++I) {
-      if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
-        continue;
-      
-      if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
-        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
-        if (ObjCPropertyDecl *Property
-            = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
-          if (Property->getPropertyAttributesAsWritten() != 0 &&
-              llvm::StringSwitch<bool>(II->getName())
-              .Case("readonly", true)
-              .Case("assign", true)
-              .Case("unsafe_unretained", true)
-              .Case("readwrite", true)
-              .Case("retain", true)
-              .Case("copy", true)
-              .Case("nonatomic", true)
-              .Case("atomic", true)
-              .Case("getter", true)
-              .Case("setter", true)
-              .Case("strong", true)
-              .Case("weak", true)
-              .Default(false))
-            Tokens[I].int_data[0] = CXToken_Keyword;
-        }
-        continue;
-      }
-      
-      if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
-          Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
-        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
-        if (llvm::StringSwitch<bool>(II->getName())
-            .Case("in", true)
-            .Case("out", true)
-            .Case("inout", true)
-            .Case("oneway", true)
-            .Case("bycopy", true)
-            .Case("byref", true)
-            .Default(false))
-          Tokens[I].int_data[0] = CXToken_Keyword;
-        continue;
-      }
-
-      if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
-          Cursors[I].kind == CXCursor_CXXOverrideAttr) {
-        Tokens[I].int_data[0] = CXToken_Keyword;
-        continue;
-      }
-    }
-  }
-}
-
-extern "C" {
-
-void clang_annotateTokens(CXTranslationUnit TU,
-                          CXToken *Tokens, unsigned NumTokens,
-                          CXCursor *Cursors) {
-
-  if (NumTokens == 0 || !Tokens || !Cursors)
-    return;
-
-  // Any token we don't specifically annotate will have a NULL cursor.
-  CXCursor C = clang_getNullCursor();
-  for (unsigned I = 0; I != NumTokens; ++I)
-    Cursors[I] = C;
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  if (!CXXUnit)
-    return;
-
-  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-  
-  clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
-  llvm::CrashRecoveryContext CRC;
-  if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
-                 GetSafetyThreadStackSize() * 2)) {
-    fprintf(stderr, "libclang: crash detected while annotating tokens\n");
-  }
-}
-
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// Operations for querying linkage of a cursor.
-//===----------------------------------------------------------------------===//
-
-extern "C" {
-CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
-  if (!clang_isDeclaration(cursor.kind))
-    return CXLinkage_Invalid;
-
-  Decl *D = cxcursor::getCursorDecl(cursor);
-  if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
-    switch (ND->getLinkage()) {
-      case NoLinkage: return CXLinkage_NoLinkage;
-      case InternalLinkage: return CXLinkage_Internal;
-      case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
-      case ExternalLinkage: return CXLinkage_External;
-    };
-
-  return CXLinkage_Invalid;
-}
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// Operations for querying language of a cursor.
-//===----------------------------------------------------------------------===//
-
-static CXLanguageKind getDeclLanguage(const Decl *D) {
-  if (!D)
-    return CXLanguage_C;
-
-  switch (D->getKind()) {
-    default:
-      break;
-    case Decl::ImplicitParam:
-    case Decl::ObjCAtDefsField:
-    case Decl::ObjCCategory:
-    case Decl::ObjCCategoryImpl:
-    case Decl::ObjCCompatibleAlias:
-    case Decl::ObjCImplementation:
-    case Decl::ObjCInterface:
-    case Decl::ObjCIvar:
-    case Decl::ObjCMethod:
-    case Decl::ObjCProperty:
-    case Decl::ObjCPropertyImpl:
-    case Decl::ObjCProtocol:
-      return CXLanguage_ObjC;
-    case Decl::CXXConstructor:
-    case Decl::CXXConversion:
-    case Decl::CXXDestructor:
-    case Decl::CXXMethod:
-    case Decl::CXXRecord:
-    case Decl::ClassTemplate:
-    case Decl::ClassTemplatePartialSpecialization:
-    case Decl::ClassTemplateSpecialization:
-    case Decl::Friend:
-    case Decl::FriendTemplate:
-    case Decl::FunctionTemplate:
-    case Decl::LinkageSpec:
-    case Decl::Namespace:
-    case Decl::NamespaceAlias:
-    case Decl::NonTypeTemplateParm:
-    case Decl::StaticAssert:
-    case Decl::TemplateTemplateParm:
-    case Decl::TemplateTypeParm:
-    case Decl::UnresolvedUsingTypename:
-    case Decl::UnresolvedUsingValue:
-    case Decl::Using:
-    case Decl::UsingDirective:
-    case Decl::UsingShadow:
-      return CXLanguage_CPlusPlus;
-  }
-
-  return CXLanguage_C;
-}
-
-extern "C" {
-  
-enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
-  if (clang_isDeclaration(cursor.kind))
-    if (Decl *D = cxcursor::getCursorDecl(cursor)) {
-      if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
-        return CXAvailability_Available;
-      
-      switch (D->getAvailability()) {
-      case AR_Available:
-      case AR_NotYetIntroduced:
-        return CXAvailability_Available;
-
-      case AR_Deprecated:
-        return CXAvailability_Deprecated;
-
-      case AR_Unavailable:
-        return CXAvailability_NotAvailable;
-      }
-    }
-
-  return CXAvailability_Available;
-}
-
-static CXVersion convertVersion(VersionTuple In) {
-  CXVersion Out = { -1, -1, -1 };
-  if (In.empty())
-    return Out;
-
-  Out.Major = In.getMajor();
-  
-  if (llvm::Optional<unsigned> Minor = In.getMinor())
-    Out.Minor = *Minor;
-  else
-    return Out;
-
-  if (llvm::Optional<unsigned> Subminor = In.getSubminor())
-    Out.Subminor = *Subminor;
-  
-  return Out;
-}
-  
-int clang_getCursorPlatformAvailability(CXCursor cursor,
-                                        int *always_deprecated,
-                                        CXString *deprecated_message,
-                                        int *always_unavailable,
-                                        CXString *unavailable_message,
-                                        CXPlatformAvailability *availability,
-                                        int availability_size) {
-  if (always_deprecated)
-    *always_deprecated = 0;
-  if (deprecated_message)
-    *deprecated_message = cxstring::createCXString("", /*DupString=*/false);
-  if (always_unavailable)
-    *always_unavailable = 0;
-  if (unavailable_message)
-    *unavailable_message = cxstring::createCXString("", /*DupString=*/false);
-  
-  if (!clang_isDeclaration(cursor.kind))
-    return 0;
-  
-  Decl *D = cxcursor::getCursorDecl(cursor);
-  if (!D)
-    return 0;
-  
-  int N = 0;
-  for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
-       ++A) {
-    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
-      if (always_deprecated)
-        *always_deprecated = 1;
-      if (deprecated_message)
-        *deprecated_message = cxstring::createCXString(Deprecated->getMessage());
-      continue;
-    }
-    
-    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
-      if (always_unavailable)
-        *always_unavailable = 1;
-      if (unavailable_message) {
-        *unavailable_message
-          = cxstring::createCXString(Unavailable->getMessage());
-      }
-      continue;
-    }
-    
-    if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
-      if (N < availability_size) {
-        availability[N].Platform
-          = cxstring::createCXString(Avail->getPlatform()->getName());
-        availability[N].Introduced = convertVersion(Avail->getIntroduced());
-        availability[N].Deprecated = convertVersion(Avail->getDeprecated());
-        availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
-        availability[N].Unavailable = Avail->getUnavailable();
-        availability[N].Message = cxstring::createCXString(Avail->getMessage());
-      }
-      ++N;
-    }
-  }
-  
-  return N;
-}
-  
-void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
-  clang_disposeString(availability->Platform);
-  clang_disposeString(availability->Message);
-}
-
-CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
-  if (clang_isDeclaration(cursor.kind))
-    return getDeclLanguage(cxcursor::getCursorDecl(cursor));
-
-  return CXLanguage_Invalid;
-}
-
- /// \brief If the given cursor is the "templated" declaration
- /// descibing a class or function template, return the class or
- /// function template.
-static Decl *maybeGetTemplateCursor(Decl *D) {
-  if (!D)
-    return 0;
-
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
-      return FunTmpl;
-
-  if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
-    if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
-      return ClassTmpl;
-
-  return D;
-}
-
-CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
-  if (clang_isDeclaration(cursor.kind)) {
-    if (Decl *D = getCursorDecl(cursor)) {
-      DeclContext *DC = D->getDeclContext();
-      if (!DC)
-        return clang_getNullCursor();
-
-      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 
-                          getCursorTU(cursor));
-    }
-  }
-  
-  if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
-    if (Decl *D = getCursorDecl(cursor))
-      return MakeCXCursor(D, getCursorTU(cursor));
-  }
-  
-  return clang_getNullCursor();
-}
-
-CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
-  if (clang_isDeclaration(cursor.kind)) {
-    if (Decl *D = getCursorDecl(cursor)) {
-      DeclContext *DC = D->getLexicalDeclContext();
-      if (!DC)
-        return clang_getNullCursor();
-
-      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 
-                          getCursorTU(cursor));
-    }
-  }
-
-  // FIXME: Note that we can't easily compute the lexical context of a 
-  // statement or expression, so we return nothing.
-  return clang_getNullCursor();
-}
-
-CXFile clang_getIncludedFile(CXCursor cursor) {
-  if (cursor.kind != CXCursor_InclusionDirective)
-    return 0;
-  
-  InclusionDirective *ID = getCursorInclusionDirective(cursor);
-  return (void *)ID->getFile();
-}
-
-CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return clang_getNullRange();
-
-  const Decl *D = getCursorDecl(C);
-  ASTContext &Context = getCursorContext(C);
-  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
-  if (!RC)
-    return clang_getNullRange();
-
-  return cxloc::translateSourceRange(Context, RC->getSourceRange());
-}
-
-CXString clang_Cursor_getRawCommentText(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return createCXString((const char *) NULL);
-
-  const Decl *D = getCursorDecl(C);
-  ASTContext &Context = getCursorContext(C);
-  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
-  StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
-                           StringRef();
-
-  // Don't duplicate the string because RawText points directly into source
-  // code.
-  return createCXString(RawText, false);
-}
-
-CXString clang_Cursor_getBriefCommentText(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return createCXString((const char *) NULL);
-
-  const Decl *D = getCursorDecl(C);
-  const ASTContext &Context = getCursorContext(C);
-  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
-
-  if (RC) {
-    StringRef BriefText = RC->getBriefText(Context);
-
-    // Don't duplicate the string because RawComment ensures that this memory
-    // will not go away.
-    return createCXString(BriefText, false);
-  }
-
-  return createCXString((const char *) NULL);
-}
-
-CXComment clang_Cursor_getParsedComment(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return cxcomment::createCXComment(NULL, NULL);
-
-  const Decl *D = getCursorDecl(C);
-  const ASTContext &Context = getCursorContext(C);
-  const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
-
-  return cxcomment::createCXComment(FC, getCursorTU(C));
-}
-
-CXModule clang_Cursor_getModule(CXCursor C) {
-  if (C.kind == CXCursor_ModuleImportDecl) {
-    if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
-      return ImportD->getImportedModule();
-  }
-
-  return 0;
-}
-
-CXModule clang_Module_getParent(CXModule CXMod) {
-  if (!CXMod)
-    return 0;
-  Module *Mod = static_cast<Module*>(CXMod);
-  return Mod->Parent;
-}
-
-CXString clang_Module_getName(CXModule CXMod) {
-  if (!CXMod)
-    return createCXString("");
-  Module *Mod = static_cast<Module*>(CXMod);
-  return createCXString(Mod->Name);
-}
-
-CXString clang_Module_getFullName(CXModule CXMod) {
-  if (!CXMod)
-    return createCXString("");
-  Module *Mod = static_cast<Module*>(CXMod);
-  return createCXString(Mod->getFullModuleName());
-}
-
-unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
-  if (!CXMod)
-    return 0;
-  Module *Mod = static_cast<Module*>(CXMod);
-  return Mod->TopHeaders.size();
-}
-
-CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
-  if (!CXMod)
-    return 0;
-  Module *Mod = static_cast<Module*>(CXMod);
-
-  if (Index < Mod->TopHeaders.size())
-    return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
-
-  return 0;
-}
-
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// C++ AST instrospection.
-//===----------------------------------------------------------------------===//
-
-extern "C" {
-unsigned clang_CXXMethod_isStatic(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return 0;
-  
-  CXXMethodDecl *Method = 0;
-  Decl *D = cxcursor::getCursorDecl(C);
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
-    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
-  else
-    Method = dyn_cast_or_null<CXXMethodDecl>(D);
-  return (Method && Method->isStatic()) ? 1 : 0;
-}
-
-unsigned clang_CXXMethod_isVirtual(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return 0;
-  
-  CXXMethodDecl *Method = 0;
-  Decl *D = cxcursor::getCursorDecl(C);
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
-    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
-  else
-    Method = dyn_cast_or_null<CXXMethodDecl>(D);
-  return (Method && Method->isVirtual()) ? 1 : 0;
-}
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// Attribute introspection.
-//===----------------------------------------------------------------------===//
-
-extern "C" {
-CXType clang_getIBOutletCollectionType(CXCursor C) {
-  if (C.kind != CXCursor_IBOutletCollectionAttr)
-    return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
-  
-  IBOutletCollectionAttr *A =
-    cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
-  
-  return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));  
-}
-} // end: extern "C"
-
-//===----------------------------------------------------------------------===//
-// Inspecting memory usage.
-//===----------------------------------------------------------------------===//
-
-typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
-
-static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
-                                              enum CXTUResourceUsageKind k,
-                                              unsigned long amount) {
-  CXTUResourceUsageEntry entry = { k, amount };
-  entries.push_back(entry);
-}
-
-extern "C" {
-
-const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
-  const char *str = "";
-  switch (kind) {
-    case CXTUResourceUsage_AST:
-      str = "ASTContext: expressions, declarations, and types"; 
-      break;
-    case CXTUResourceUsage_Identifiers:
-      str = "ASTContext: identifiers";
-      break;
-    case CXTUResourceUsage_Selectors:
-      str = "ASTContext: selectors";
-      break;
-    case CXTUResourceUsage_GlobalCompletionResults:
-      str = "Code completion: cached global results";
-      break;
-    case CXTUResourceUsage_SourceManagerContentCache:
-      str = "SourceManager: content cache allocator";
-      break;
-    case CXTUResourceUsage_AST_SideTables:
-      str = "ASTContext: side tables";
-      break;
-    case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
-      str = "SourceManager: malloc'ed memory buffers";
-      break;
-    case CXTUResourceUsage_SourceManager_Membuffer_MMap:
-      str = "SourceManager: mmap'ed memory buffers";
-      break;
-    case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
-      str = "ExternalASTSource: malloc'ed memory buffers";
-      break;
-    case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
-      str = "ExternalASTSource: mmap'ed memory buffers";
-      break;
-    case CXTUResourceUsage_Preprocessor:
-      str = "Preprocessor: malloc'ed memory";
-      break;
-    case CXTUResourceUsage_PreprocessingRecord:
-      str = "Preprocessor: PreprocessingRecord";
-      break;
-    case CXTUResourceUsage_SourceManager_DataStructures:
-      str = "SourceManager: data structures and tables";
-      break;
-    case CXTUResourceUsage_Preprocessor_HeaderSearch:
-      str = "Preprocessor: header search tables";
-      break;
-  }
-  return str;
-}
-
-CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
-  if (!TU) {
-    CXTUResourceUsage usage = { (void*) 0, 0, 0 };
-    return usage;
-  }
-  
-  ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
-  OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
-  ASTContext &astContext = astUnit->getASTContext();
-  
-  // How much memory is used by AST nodes and types?
-  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
-    (unsigned long) astContext.getASTAllocatedMemory());
-
-  // How much memory is used by identifiers?
-  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
-    (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
-
-  // How much memory is used for selectors?
-  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
-    (unsigned long) astContext.Selectors.getTotalMemory());
-  
-  // How much memory is used by ASTContext's side tables?
-  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
-    (unsigned long) astContext.getSideTableAllocatedMemory());
-  
-  // How much memory is used for caching global code completion results?
-  unsigned long completionBytes = 0;
-  if (GlobalCodeCompletionAllocator *completionAllocator =
-      astUnit->getCachedCompletionAllocator().getPtr()) {
-    completionBytes = completionAllocator->getTotalMemory();
-  }
-  createCXTUResourceUsageEntry(*entries,
-                               CXTUResourceUsage_GlobalCompletionResults,
-                               completionBytes);
-  
-  // How much memory is being used by SourceManager's content cache?
-  createCXTUResourceUsageEntry(*entries,
-          CXTUResourceUsage_SourceManagerContentCache,
-          (unsigned long) astContext.getSourceManager().getContentCacheSize());
-  
-  // How much memory is being used by the MemoryBuffer's in SourceManager?
-  const SourceManager::MemoryBufferSizes &srcBufs =
-    astUnit->getSourceManager().getMemoryBufferSizes();
-  
-  createCXTUResourceUsageEntry(*entries,
-                               CXTUResourceUsage_SourceManager_Membuffer_Malloc,
-                               (unsigned long) srcBufs.malloc_bytes);
-  createCXTUResourceUsageEntry(*entries,
-                               CXTUResourceUsage_SourceManager_Membuffer_MMap,
-                               (unsigned long) srcBufs.mmap_bytes);
-  createCXTUResourceUsageEntry(*entries,
-                               CXTUResourceUsage_SourceManager_DataStructures,
-                               (unsigned long) astContext.getSourceManager()
-                                .getDataStructureSizes());
-  
-  // How much memory is being used by the ExternalASTSource?
-  if (ExternalASTSource *esrc = astContext.getExternalSource()) {
-    const ExternalASTSource::MemoryBufferSizes &sizes =
-      esrc->getMemoryBufferSizes();
-    
-    createCXTUResourceUsageEntry(*entries,
-      CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
-                                 (unsigned long) sizes.malloc_bytes);
-    createCXTUResourceUsageEntry(*entries,
-      CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
-                                 (unsigned long) sizes.mmap_bytes);
-  }
-  
-  // How much memory is being used by the Preprocessor?
-  Preprocessor &pp = astUnit->getPreprocessor();
-  createCXTUResourceUsageEntry(*entries,
-                               CXTUResourceUsage_Preprocessor,
-                               pp.getTotalMemory());
-  
-  if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
-    createCXTUResourceUsageEntry(*entries,
-                                 CXTUResourceUsage_PreprocessingRecord,
-                                 pRec->getTotalMemory());    
-  }
-  
-  createCXTUResourceUsageEntry(*entries,
-                               CXTUResourceUsage_Preprocessor_HeaderSearch,
-                               pp.getHeaderSearchInfo().getTotalMemory());
-  
-  CXTUResourceUsage usage = { (void*) entries.get(),
-                            (unsigned) entries->size(),
-                            entries->size() ? &(*entries)[0] : 0 };
-  entries.take();
-  return usage;
-}
-
-void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
-  if (usage.data)
-    delete (MemUsageEntries*) usage.data;
-}
-
-} // end extern "C"
-
-void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
-  CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
-  for (unsigned I = 0; I != Usage.numEntries; ++I)
-    fprintf(stderr, "  %s: %lu\n", 
-            clang_getTUResourceUsageName(Usage.entries[I].kind),
-            Usage.entries[I].amount);
-  
-  clang_disposeCXTUResourceUsage(Usage);
-}
-
-//===----------------------------------------------------------------------===//
-// Misc. utility functions.
-//===----------------------------------------------------------------------===//
-
-/// Default to using an 8 MB stack size on "safety" threads.
-static unsigned SafetyStackThreadSize = 8 << 20;
-
-namespace clang {
-
-bool RunSafely(llvm::CrashRecoveryContext &CRC,
-               void (*Fn)(void*), void *UserData,
-               unsigned Size) {
-  if (!Size)
-    Size = GetSafetyThreadStackSize();
-  if (Size)
-    return CRC.RunSafelyOnThread(Fn, UserData, Size);
-  return CRC.RunSafely(Fn, UserData);
-}
-
-unsigned GetSafetyThreadStackSize() {
-  return SafetyStackThreadSize;
-}
-
-void SetSafetyThreadStackSize(unsigned Value) {
-  SafetyStackThreadSize = Value;
-}
-
-}
-
-void clang::setThreadBackgroundPriority() {
-  if (getenv("LIBCLANG_BGPRIO_DISABLE"))
-    return;
-
-  // FIXME: Move to llvm/Support and make it cross-platform.
-#ifdef __APPLE__
-  setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
-#endif
-}
-
-void cxindex::printDiagsToStderr(ASTUnit *Unit) {
-  if (!Unit)
-    return;
-
-  for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 
-                                  DEnd = Unit->stored_diag_end();
-       D != DEnd; ++D) {
-    CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
-    CXString Msg = clang_formatDiagnostic(&Diag,
-                                clang_defaultDiagnosticDisplayOptions());
-    fprintf(stderr, "%s\n", clang_getCString(Msg));
-    clang_disposeString(Msg);
-  }
-#ifdef LLVM_ON_WIN32
-  // On Windows, force a flush, since there may be multiple copies of
-  // stderr and stdout in the file system, all with different buffers
-  // but writing to the same device.
-  fflush(stderr);
-#endif
-}
-
-extern "C" {
-
-CXString clang_getClangVersion() {
-  return createCXString(getClangFullVersion());
-}
-
-} // end: extern "C"
-
+//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
+//
+//                     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 main API hooks in the Clang-C Source Indexing
+// library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CIndexDiagnostic.h"
+#include "CXComment.h"
+#include "CXCursor.h"
+#include "CXSourceLocation.h"
+#include "CXString.h"
+#include "CXTranslationUnit.h"
+#include "CXType.h"
+#include "CursorVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/Version.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::cxcursor;
+using namespace clang::cxstring;
+using namespace clang::cxtu;
+using namespace clang::cxindex;
+
+CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU) {
+  if (!TU)
+    return 0;
+  CXTranslationUnit D = new CXTranslationUnitImpl();
+  D->CIdx = CIdx;
+  D->TUData = TU;
+  D->StringPool = createCXStringPool();
+  D->Diagnostics = 0;
+  D->OverridenCursorsPool = createOverridenCXCursorsPool();
+  return D;
+}
+
+cxtu::CXTUOwner::~CXTUOwner() {
+  if (TU)
+    clang_disposeTranslationUnit(TU);
+}
+
+/// \brief Compare two source ranges to determine their relative position in
+/// the translation unit.
+static RangeComparisonResult RangeCompare(SourceManager &SM,
+                                          SourceRange R1,
+                                          SourceRange R2) {
+  assert(R1.isValid() && "First range is invalid?");
+  assert(R2.isValid() && "Second range is invalid?");
+  if (R1.getEnd() != R2.getBegin() &&
+      SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
+    return RangeBefore;
+  if (R2.getEnd() != R1.getBegin() &&
+      SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
+    return RangeAfter;
+  return RangeOverlap;
+}
+
+/// \brief Determine if a source location falls within, before, or after a
+///   a given source range.
+static RangeComparisonResult LocationCompare(SourceManager &SM,
+                                             SourceLocation L, SourceRange R) {
+  assert(R.isValid() && "First range is invalid?");
+  assert(L.isValid() && "Second range is invalid?");
+  if (L == R.getBegin() || L == R.getEnd())
+    return RangeOverlap;
+  if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
+    return RangeBefore;
+  if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
+    return RangeAfter;
+  return RangeOverlap;
+}
+
+/// \brief Translate a Clang source range into a CIndex source range.
+///
+/// Clang internally represents ranges where the end location points to the
+/// start of the token at the end. However, for external clients it is more
+/// useful to have a CXSourceRange be a proper half-open interval. This routine
+/// does the appropriate translation.
+CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
+                                          const LangOptions &LangOpts,
+                                          const CharSourceRange &R) {
+  // We want the last character in this location, so we will adjust the
+  // location accordingly.
+  SourceLocation EndLoc = R.getEnd();
+  if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
+    EndLoc = SM.getExpansionRange(EndLoc).second;
+  if (R.isTokenRange() && !EndLoc.isInvalid()) {
+    unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
+                                                SM, LangOpts);
+    EndLoc = EndLoc.getLocWithOffset(Length);
+  }
+
+  CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
+                           R.getBegin().getRawEncoding(),
+                           EndLoc.getRawEncoding() };
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Cursor visitor.
+//===----------------------------------------------------------------------===//
+
+static SourceRange getRawCursorExtent(CXCursor C);
+static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
+
+
+RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
+  return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
+}
+
+/// \brief Visit the given cursor and, if requested by the visitor,
+/// its children.
+///
+/// \param Cursor the cursor to visit.
+///
+/// \param CheckedRegionOfInterest if true, then the caller already checked
+/// that this cursor is within the region of interest.
+///
+/// \returns true if the visitation should be aborted, false if it
+/// should continue.
+bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
+  if (clang_isInvalid(Cursor.kind))
+    return false;
+
+  if (clang_isDeclaration(Cursor.kind)) {
+    Decl *D = getCursorDecl(Cursor);
+    if (!D) {
+      assert(0 && "Invalid declaration cursor");
+      return true; // abort.
+    }
+    
+    // Ignore implicit declarations, unless it's an objc method because
+    // currently we should report implicit methods for properties when indexing.
+    if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
+      return false;
+  }
+
+  // If we have a range of interest, and this cursor doesn't intersect with it,
+  // we're done.
+  if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
+    SourceRange Range = getRawCursorExtent(Cursor);
+    if (Range.isInvalid() || CompareRegionOfInterest(Range))
+      return false;
+  }
+
+  switch (Visitor(Cursor, Parent, ClientData)) {
+  case CXChildVisit_Break:
+    return true;
+
+  case CXChildVisit_Continue:
+    return false;
+
+  case CXChildVisit_Recurse: {
+    bool ret = VisitChildren(Cursor);
+    if (PostChildrenVisitor)
+      if (PostChildrenVisitor(Cursor, ClientData))
+        return true;
+    return ret;
+  }
+  }
+
+  llvm_unreachable("Invalid CXChildVisitResult!");
+}
+
+static bool visitPreprocessedEntitiesInRange(SourceRange R,
+                                             PreprocessingRecord &PPRec,
+                                             CursorVisitor &Visitor) {
+  SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
+  FileID FID;
+  
+  if (!Visitor.shouldVisitIncludedEntities()) {
+    // If the begin/end of the range lie in the same FileID, do the optimization
+    // where we skip preprocessed entities that do not come from the same FileID.
+    FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
+    if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
+      FID = FileID();
+  }
+
+  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+    Entities = PPRec.getPreprocessedEntitiesInRange(R);
+  return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
+                                           PPRec, FID);
+}
+
+void CursorVisitor::visitFileRegion() {
+  if (RegionOfInterest.isInvalid())
+    return;
+
+  ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+  SourceManager &SM = Unit->getSourceManager();
+  
+  std::pair<FileID, unsigned>
+    Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())), 
+    End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd())); 
+
+  if (End.first != Begin.first) {
+    // If the end does not reside in the same file, try to recover by
+    // picking the end of the file of begin location.
+    End.first = Begin.first;
+    End.second = SM.getFileIDSize(Begin.first);
+  }
+
+  assert(Begin.first == End.first);
+  if (Begin.second > End.second)
+    return;
+  
+  FileID File = Begin.first;
+  unsigned Offset = Begin.second;
+  unsigned Length = End.second - Begin.second;
+
+  if (!VisitDeclsOnly && !VisitPreprocessorLast)
+    if (visitPreprocessedEntitiesInRegion())
+      return; // visitation break.
+
+  visitDeclsFromFileRegion(File, Offset, Length);
+
+  if (!VisitDeclsOnly && VisitPreprocessorLast)
+    visitPreprocessedEntitiesInRegion();
+}
+
+static bool isInLexicalContext(Decl *D, DeclContext *DC) {
+  if (!DC)
+    return false;
+
+  for (DeclContext *DeclDC = D->getLexicalDeclContext();
+         DeclDC; DeclDC = DeclDC->getLexicalParent()) {
+    if (DeclDC == DC)
+      return true;
+  }
+  return false;
+}
+
+void CursorVisitor::visitDeclsFromFileRegion(FileID File,
+                                             unsigned Offset, unsigned Length) {
+  ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+  SourceManager &SM = Unit->getSourceManager();
+  SourceRange Range = RegionOfInterest;
+
+  SmallVector<Decl *, 16> Decls;
+  Unit->findFileRegionDecls(File, Offset, Length, Decls);
+
+  // If we didn't find any file level decls for the file, try looking at the
+  // file that it was included from.
+  while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
+    if (Invalid)
+      return;
+
+    SourceLocation Outer;
+    if (SLEntry.isFile())
+      Outer = SLEntry.getFile().getIncludeLoc();
+    else
+      Outer = SLEntry.getExpansion().getExpansionLocStart();
+    if (Outer.isInvalid())
+      return;
+
+    llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
+    Length = 0;
+    Unit->findFileRegionDecls(File, Offset, Length, Decls);
+  }
+
+  assert(!Decls.empty());
+
+  bool VisitedAtLeastOnce = false;
+  DeclContext *CurDC = 0;
+  SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
+  for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
+    Decl *D = *DIt;
+    if (D->getSourceRange().isInvalid())
+      continue;
+
+    if (isInLexicalContext(D, CurDC))
+      continue;
+
+    CurDC = dyn_cast<DeclContext>(D);
+
+    if (TagDecl *TD = dyn_cast<TagDecl>(D))
+      if (!TD->isFreeStanding())
+        continue;
+
+    RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
+    if (CompRes == RangeBefore)
+      continue;
+    if (CompRes == RangeAfter)
+      break;
+
+    assert(CompRes == RangeOverlap);
+    VisitedAtLeastOnce = true;
+
+    if (isa<ObjCContainerDecl>(D)) {
+      FileDI_current = &DIt;
+      FileDE_current = DE;
+    } else {
+      FileDI_current = 0;
+    }
+
+    if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
+      break;
+  }
+
+  if (VisitedAtLeastOnce)
+    return;
+
+  // No Decls overlapped with the range. Move up the lexical context until there
+  // is a context that contains the range or we reach the translation unit
+  // level.
+  DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
+                                         : (*(DIt-1))->getLexicalDeclContext();
+
+  while (DC && !DC->isTranslationUnit()) {
+    Decl *D = cast<Decl>(DC);
+    SourceRange CurDeclRange = D->getSourceRange();
+    if (CurDeclRange.isInvalid())
+      break;
+
+    if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
+      Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true);
+      break;
+    }
+
+    DC = D->getLexicalDeclContext();
+  }
+}
+
+bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
+  if (!AU->getPreprocessor().getPreprocessingRecord())
+    return false;
+
+  PreprocessingRecord &PPRec
+    = *AU->getPreprocessor().getPreprocessingRecord();
+  SourceManager &SM = AU->getSourceManager();
+  
+  if (RegionOfInterest.isValid()) {
+    SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
+    SourceLocation B = MappedRange.getBegin();
+    SourceLocation E = MappedRange.getEnd();
+
+    if (AU->isInPreambleFileID(B)) {
+      if (SM.isLoadedSourceLocation(E))
+        return visitPreprocessedEntitiesInRange(SourceRange(B, E),
+                                                 PPRec, *this);
+
+      // Beginning of range lies in the preamble but it also extends beyond
+      // it into the main file. Split the range into 2 parts, one covering
+      // the preamble and another covering the main file. This allows subsequent
+      // calls to visitPreprocessedEntitiesInRange to accept a source range that
+      // lies in the same FileID, allowing it to skip preprocessed entities that
+      // do not come from the same FileID.
+      bool breaked =
+        visitPreprocessedEntitiesInRange(
+                                   SourceRange(B, AU->getEndOfPreambleFileID()),
+                                          PPRec, *this);
+      if (breaked) return true;
+      return visitPreprocessedEntitiesInRange(
+                                    SourceRange(AU->getStartOfMainFileID(), E),
+                                        PPRec, *this);
+    }
+
+    return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
+  }
+
+  bool OnlyLocalDecls
+    = !AU->isMainFileAST() && AU->getOnlyLocalDecls(); 
+  
+  if (OnlyLocalDecls)
+    return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
+                                     PPRec);
+
+  return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
+}
+
+template<typename InputIterator>
+bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
+                                              InputIterator Last,
+                                              PreprocessingRecord &PPRec,
+                                              FileID FID) {
+  for (; First != Last; ++First) {
+    if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
+      continue;
+
+    PreprocessedEntity *PPE = *First;
+    if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
+      if (Visit(MakeMacroExpansionCursor(ME, TU)))
+        return true;
+      
+      continue;
+    }
+    
+    if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
+      if (Visit(MakeMacroDefinitionCursor(MD, TU)))
+        return true;
+      
+      continue;
+    }
+    
+    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
+      if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
+        return true;
+      
+      continue;
+    }
+  }
+
+  return false;
+}
+
+/// \brief Visit the children of the given cursor.
+/// 
+/// \returns true if the visitation should be aborted, false if it
+/// should continue.
+bool CursorVisitor::VisitChildren(CXCursor Cursor) {
+  if (clang_isReference(Cursor.kind) && 
+      Cursor.kind != CXCursor_CXXBaseSpecifier) {
+    // By definition, references have no children.
+    return false;
+  }
+
+  // Set the Parent field to Cursor, then back to its old value once we're
+  // done.
+  SetParentRAII SetParent(Parent, StmtParent, Cursor);
+
+  if (clang_isDeclaration(Cursor.kind)) {
+    Decl *D = getCursorDecl(Cursor);
+    if (!D)
+      return false;
+
+    return VisitAttributes(D) || Visit(D);
+  }
+
+  if (clang_isStatement(Cursor.kind)) {
+    if (Stmt *S = getCursorStmt(Cursor))
+      return Visit(S);
+
+    return false;
+  }
+
+  if (clang_isExpression(Cursor.kind)) {
+    if (Expr *E = getCursorExpr(Cursor))
+      return Visit(E);
+
+    return false;
+  }
+
+  if (clang_isTranslationUnit(Cursor.kind)) {
+    CXTranslationUnit tu = getCursorTU(Cursor);
+    ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
+    
+    int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
+    for (unsigned I = 0; I != 2; ++I) {
+      if (VisitOrder[I]) {
+        if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
+            RegionOfInterest.isInvalid()) {
+          for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
+                                        TLEnd = CXXUnit->top_level_end();
+               TL != TLEnd; ++TL) {
+            if (Visit(MakeCXCursor(*TL, tu, RegionOfInterest), true))
+              return true;
+          }
+        } else if (VisitDeclContext(
+                                CXXUnit->getASTContext().getTranslationUnitDecl()))
+          return true;
+        continue;
+      }
+
+      // Walk the preprocessing record.
+      if (CXXUnit->getPreprocessor().getPreprocessingRecord())
+        visitPreprocessedEntitiesInRegion();
+    }
+    
+    return false;
+  }
+
+  if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
+    if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
+      if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
+        return Visit(BaseTSInfo->getTypeLoc());
+      }
+    }
+  }
+
+  if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
+    IBOutletCollectionAttr *A =
+      cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
+    if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
+      return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
+                                                    A->getInterfaceLoc(), TU));
+  }
+
+  // Nothing to visit at the moment.
+  return false;
+}
+
+bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
+  if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
+    if (Visit(TSInfo->getTypeLoc()))
+        return true;
+
+  if (Stmt *Body = B->getBody())
+    return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
+
+  return false;
+}
+
+llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
+  if (RegionOfInterest.isValid()) {
+    SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
+    if (Range.isInvalid())
+      return llvm::Optional<bool>();
+    
+    switch (CompareRegionOfInterest(Range)) {
+    case RangeBefore:
+      // This declaration comes before the region of interest; skip it.
+      return llvm::Optional<bool>();
+
+    case RangeAfter:
+      // This declaration comes after the region of interest; we're done.
+      return false;
+
+    case RangeOverlap:
+      // This declaration overlaps the region of interest; visit it.
+      break;
+    }
+  }
+  return true;
+}
+
+bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
+  DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
+
+  // FIXME: Eventually remove.  This part of a hack to support proper
+  // iteration over all Decls contained lexically within an ObjC container.
+  SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
+  SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
+
+  for ( ; I != E; ++I) {
+    Decl *D = *I;
+    if (D->getLexicalDeclContext() != DC)
+      continue;
+    CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
+
+    // Ignore synthesized ivars here, otherwise if we have something like:
+    //   @synthesize prop = _prop;
+    // and '_prop' is not declared, we will encounter a '_prop' ivar before
+    // encountering the 'prop' synthesize declaration and we will think that
+    // we passed the region-of-interest.
+    if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
+      if (ivarD->getSynthesize())
+        continue;
+    }
+
+    // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
+    // declarations is a mismatch with the compiler semantics.
+    if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
+      ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
+      if (!ID->isThisDeclarationADefinition())
+        Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
+
+    } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
+      ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
+      if (!PD->isThisDeclarationADefinition())
+        Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
+    }
+
+    const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
+    if (!V.hasValue())
+      continue;
+    if (!V.getValue())
+      return false;
+    if (Visit(Cursor, true))
+      return true;
+  }
+  return false;
+}
+
+bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  llvm_unreachable("Translation units are visited directly by Visit()");
+}
+
+bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
+  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
+bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
+  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
+bool CursorVisitor::VisitTagDecl(TagDecl *D) {
+  return VisitDeclContext(D);
+}
+
+bool CursorVisitor::VisitClassTemplateSpecializationDecl(
+                                          ClassTemplateSpecializationDecl *D) {
+  bool ShouldVisitBody = false;
+  switch (D->getSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ImplicitInstantiation:
+    // Nothing to visit
+    return false;
+      
+  case TSK_ExplicitInstantiationDeclaration:
+  case TSK_ExplicitInstantiationDefinition:
+    break;
+      
+  case TSK_ExplicitSpecialization:
+    ShouldVisitBody = true;
+    break;
+  }
+  
+  // Visit the template arguments used in the specialization.
+  if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
+    TypeLoc TL = SpecType->getTypeLoc();
+    if (TemplateSpecializationTypeLoc *TSTLoc
+          = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
+      for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
+        if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
+          return true;
+    }
+  }
+  
+  if (ShouldVisitBody && VisitCXXRecordDecl(D))
+    return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
+                                   ClassTemplatePartialSpecializationDecl *D) {
+  // FIXME: Visit the "outer" template parameter lists on the TagDecl
+  // before visiting these template parameters.
+  if (VisitTemplateParameters(D->getTemplateParameters()))
+    return true;
+
+  // Visit the partial specialization arguments.
+  const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
+  for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
+    if (VisitTemplateArgumentLoc(TemplateArgs[I]))
+      return true;
+  
+  return VisitCXXRecordDecl(D);
+}
+
+bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  // Visit the default argument.
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+    if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
+      if (Visit(DefArg->getTypeLoc()))
+        return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  if (Expr *Init = D->getInitExpr())
+    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
+  return false;
+}
+
+bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
+  if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  // Visit the nested-name-specifier, if present.
+  if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+
+  return false;
+}
+
+/// \brief Compare two base or member initializers based on their source order.
+static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
+  CXXCtorInitializer const * const *X
+    = static_cast<CXXCtorInitializer const * const *>(Xp);
+  CXXCtorInitializer const * const *Y
+    = static_cast<CXXCtorInitializer const * const *>(Yp);
+  
+  if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
+    return -1;
+  else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
+    return 1;
+  else
+    return 0;
+}
+
+bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
+  if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
+    // Visit the function declaration's syntactic components in the order
+    // written. This requires a bit of work.
+    TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
+    FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
+    
+    // If we have a function declared directly (without the use of a typedef),
+    // visit just the return type. Otherwise, just visit the function's type
+    // now.
+    if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
+        (!FTL && Visit(TL)))
+      return true;
+    
+    // Visit the nested-name-specifier, if present.
+    if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
+      if (VisitNestedNameSpecifierLoc(QualifierLoc))
+        return true;
+    
+    // Visit the declaration name.
+    if (VisitDeclarationNameInfo(ND->getNameInfo()))
+      return true;
+    
+    // FIXME: Visit explicitly-specified template arguments!
+    
+    // Visit the function parameters, if we have a function type.
+    if (FTL && VisitFunctionTypeLoc(*FTL, true))
+      return true;
+    
+    // FIXME: Attributes?
+  }
+  
+  if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
+    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
+      // Find the initializers that were written in the source.
+      SmallVector<CXXCtorInitializer *, 4> WrittenInits;
+      for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
+                                          IEnd = Constructor->init_end();
+           I != IEnd; ++I) {
+        if (!(*I)->isWritten())
+          continue;
+      
+        WrittenInits.push_back(*I);
+      }
+      
+      // Sort the initializers in source order
+      llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
+                           &CompareCXXCtorInitializers);
+      
+      // Visit the initializers in source order
+      for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
+        CXXCtorInitializer *Init = WrittenInits[I];
+        if (Init->isAnyMemberInitializer()) {
+          if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
+                                        Init->getMemberLocation(), TU)))
+            return true;
+        } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
+          if (Visit(TInfo->getTypeLoc()))
+            return true;
+        }
+        
+        // Visit the initializer value.
+        if (Expr *Initializer = Init->getInit())
+          if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
+            return true;
+      } 
+    }
+    
+    if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
+  if (VisitDeclaratorDecl(D))
+    return true;
+
+  if (Expr *BitWidth = D->getBitWidth())
+    return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
+
+  return false;
+}
+
+bool CursorVisitor::VisitVarDecl(VarDecl *D) {
+  if (VisitDeclaratorDecl(D))
+    return true;
+
+  if (Expr *Init = D->getInit())
+    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
+
+  return false;
+}
+
+bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  if (VisitDeclaratorDecl(D))
+    return true;
+  
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+    if (Expr *DefArg = D->getDefaultArgument())
+      return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
+  
+  return false;  
+}
+
+bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
+  // before visiting these template parameters.
+  if (VisitTemplateParameters(D->getTemplateParameters()))
+    return true;
+  
+  return VisitFunctionDecl(D->getTemplatedDecl());
+}
+
+bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  // FIXME: Visit the "outer" template parameter lists on the TagDecl
+  // before visiting these template parameters.
+  if (VisitTemplateParameters(D->getTemplateParameters()))
+    return true;
+  
+  return VisitCXXRecordDecl(D->getTemplatedDecl());
+}
+
+bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  if (VisitTemplateParameters(D->getTemplateParameters()))
+    return true;
+  
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
+      VisitTemplateArgumentLoc(D->getDefaultArgument()))
+    return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
+  if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+
+  for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
+       PEnd = ND->param_end();
+       P != PEnd; ++P) {
+    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
+      return true;
+  }
+
+  if (ND->isThisDeclarationADefinition() &&
+      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
+    return true;
+
+  return false;
+}
+
+template <typename DeclIt>
+static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
+                                      SourceManager &SM, SourceLocation EndLoc,
+                                      SmallVectorImpl<Decl *> &Decls) {
+  DeclIt next = *DI_current;
+  while (++next != DE_current) {
+    Decl *D_next = *next;
+    if (!D_next)
+      break;
+    SourceLocation L = D_next->getLocStart();
+    if (!L.isValid())
+      break;
+    if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
+      *DI_current = next;
+      Decls.push_back(D_next);
+      continue;
+    }
+    break;
+  }
+}
+
+namespace {
+  struct ContainerDeclsSort {
+    SourceManager &SM;
+    ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
+    bool operator()(Decl *A, Decl *B) {
+      SourceLocation L_A = A->getLocStart();
+      SourceLocation L_B = B->getLocStart();
+      assert(L_A.isValid() && L_B.isValid());
+      return SM.isBeforeInTranslationUnit(L_A, L_B);
+    }
+  };
+}
+
+bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
+  // an @implementation can lexically contain Decls that are not properly
+  // nested in the AST.  When we identify such cases, we need to retrofit
+  // this nesting here.
+  if (!DI_current && !FileDI_current)
+    return VisitDeclContext(D);
+
+  // Scan the Decls that immediately come after the container
+  // in the current DeclContext.  If any fall within the
+  // container's lexical region, stash them into a vector
+  // for later processing.
+  SmallVector<Decl *, 24> DeclsInContainer;
+  SourceLocation EndLoc = D->getSourceRange().getEnd();
+  SourceManager &SM = AU->getSourceManager();
+  if (EndLoc.isValid()) {
+    if (DI_current) {
+      addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
+                                DeclsInContainer);
+    } else {
+      addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
+                                DeclsInContainer);
+    }
+  }
+
+  // The common case.
+  if (DeclsInContainer.empty())
+    return VisitDeclContext(D);
+
+  // Get all the Decls in the DeclContext, and sort them with the
+  // additional ones we've collected.  Then visit them.
+  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
+       I!=E; ++I) {
+    Decl *subDecl = *I;
+    if (!subDecl || subDecl->getLexicalDeclContext() != D ||
+        subDecl->getLocStart().isInvalid())
+      continue;
+    DeclsInContainer.push_back(subDecl);
+  }
+
+  // Now sort the Decls so that they appear in lexical order.
+  std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
+            ContainerDeclsSort(SM));
+
+  // Now visit the decls.
+  for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
+         E = DeclsInContainer.end(); I != E; ++I) {
+    CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
+    const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
+    if (!V.hasValue())
+      continue;
+    if (!V.getValue())
+      return false;
+    if (Visit(Cursor, true))
+      return true;
+  }
+  return false;
+}
+
+bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
+  if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
+                                   TU)))
+    return true;
+
+  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
+  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
+         E = ND->protocol_end(); I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return VisitObjCContainerDecl(ND);
+}
+
+bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
+  if (!PID->isThisDeclarationADefinition())
+    return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
+  
+  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
+  for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
+       E = PID->protocol_end(); I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return VisitObjCContainerDecl(PID);
+}
+
+bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
+  if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
+    return true;
+
+  // FIXME: This implements a workaround with @property declarations also being
+  // installed in the DeclContext for the @interface.  Eventually this code
+  // should be removed.
+  ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
+  if (!CDecl || !CDecl->IsClassExtension())
+    return false;
+
+  ObjCInterfaceDecl *ID = CDecl->getClassInterface();
+  if (!ID)
+    return false;
+
+  IdentifierInfo *PropertyId = PD->getIdentifier();
+  ObjCPropertyDecl *prevDecl =
+    ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
+
+  if (!prevDecl)
+    return false;
+
+  // Visit synthesized methods since they will be skipped when visiting
+  // the @interface.
+  if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
+    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
+      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
+        return true;
+
+  if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
+    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
+      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
+        return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+  if (!D->isThisDeclarationADefinition()) {
+    // Forward declaration is treated like a reference.
+    return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
+  }
+
+  // Issue callbacks for super class.
+  if (D->getSuperClass() &&
+      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
+                                        D->getSuperClassLoc(),
+                                        TU)))
+    return true;
+
+  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
+  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
+         E = D->protocol_end(); I != E; ++I, ++PL)
+    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
+      return true;
+
+  return VisitObjCContainerDecl(D);
+}
+
+bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
+  return VisitObjCContainerDecl(D);
+}
+
+bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  // 'ID' could be null when dealing with invalid code.
+  if (ObjCInterfaceDecl *ID = D->getClassInterface())
+    if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
+      return true;
+
+  return VisitObjCImplDecl(D);
+}
+
+bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+#if 0
+  // Issue callbacks for super class.
+  // FIXME: No source location information!
+  if (D->getSuperClass() &&
+      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
+                                        D->getSuperClassLoc(),
+                                        TU)))
+    return true;
+#endif
+
+  return VisitObjCImplDecl(D);
+}
+
+bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
+  if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
+    if (PD->isIvarNameSpecified())
+      return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
+  
+  return false;
+}
+
+bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
+  return VisitDeclContext(D);
+}
+
+bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  // Visit nested-name-specifier.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+  
+  return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), 
+                                      D->getTargetNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
+  // Visit nested-name-specifier.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+  }
+  
+  if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
+    return true;
+    
+  return VisitDeclarationNameInfo(D->getNameInfo());
+}
+
+bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  // Visit nested-name-specifier.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+
+  return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
+                                      D->getIdentLocation(), TU));
+}
+
+bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+  // Visit nested-name-specifier.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+  }
+
+  return VisitDeclarationNameInfo(D->getNameInfo());
+}
+
+bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
+                                               UnresolvedUsingTypenameDecl *D) {
+  // Visit nested-name-specifier.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
+  switch (Name.getName().getNameKind()) {
+  case clang::DeclarationName::Identifier:
+  case clang::DeclarationName::CXXLiteralOperatorName:
+  case clang::DeclarationName::CXXOperatorName:
+  case clang::DeclarationName::CXXUsingDirective:
+    return false;
+      
+  case clang::DeclarationName::CXXConstructorName:
+  case clang::DeclarationName::CXXDestructorName:
+  case clang::DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
+      return Visit(TSInfo->getTypeLoc());
+    return false;
+
+  case clang::DeclarationName::ObjCZeroArgSelector:
+  case clang::DeclarationName::ObjCOneArgSelector:
+  case clang::DeclarationName::ObjCMultiArgSelector:
+    // FIXME: Per-identifier location info?
+    return false;
+  }
+
+  llvm_unreachable("Invalid DeclarationName::Kind!");
+}
+
+bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, 
+                                             SourceRange Range) {
+  // FIXME: This whole routine is a hack to work around the lack of proper
+  // source information in nested-name-specifiers (PR5791). Since we do have
+  // a beginning source location, we can visit the first component of the
+  // nested-name-specifier, if it's a single-token component.
+  if (!NNS)
+    return false;
+  
+  // Get the first component in the nested-name-specifier.
+  while (NestedNameSpecifier *Prefix = NNS->getPrefix())
+    NNS = Prefix;
+  
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Namespace:
+    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
+                                        TU));
+
+  case NestedNameSpecifier::NamespaceAlias:
+    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
+                                        Range.getBegin(), TU));
+
+  case NestedNameSpecifier::TypeSpec: {
+    // If the type has a form where we know that the beginning of the source
+    // range matches up with a reference cursor. Visit the appropriate reference
+    // cursor.
+    const Type *T = NNS->getAsType();
+    if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
+      return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
+    if (const TagType *Tag = dyn_cast<TagType>(T))
+      return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
+    if (const TemplateSpecializationType *TST
+                                      = dyn_cast<TemplateSpecializationType>(T))
+      return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
+    break;
+  }
+      
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+  case NestedNameSpecifier::Global:
+  case NestedNameSpecifier::Identifier:
+    break;      
+  }
+  
+  return false;
+}
+
+bool 
+CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
+  SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
+  for (; Qualifier; Qualifier = Qualifier.getPrefix())
+    Qualifiers.push_back(Qualifier);
+  
+  while (!Qualifiers.empty()) {
+    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
+    NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
+    switch (NNS->getKind()) {
+    case NestedNameSpecifier::Namespace:
+      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), 
+                                       Q.getLocalBeginLoc(),
+                                       TU)))
+        return true;
+        
+      break;
+      
+    case NestedNameSpecifier::NamespaceAlias:
+      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
+                                       Q.getLocalBeginLoc(),
+                                       TU)))
+        return true;
+        
+      break;
+        
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate:
+      if (Visit(Q.getTypeLoc()))
+        return true;
+        
+      break;
+        
+    case NestedNameSpecifier::Global:
+    case NestedNameSpecifier::Identifier:
+      break;              
+    }
+  }
+  
+  return false;
+}
+
+bool CursorVisitor::VisitTemplateParameters(
+                                          const TemplateParameterList *Params) {
+  if (!Params)
+    return false;
+  
+  for (TemplateParameterList::const_iterator P = Params->begin(),
+                                          PEnd = Params->end();
+       P != PEnd; ++P) {
+    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
+      return true;
+  }
+  
+  return false;
+}
+
+bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
+  switch (Name.getKind()) {
+  case TemplateName::Template:
+    return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
+
+  case TemplateName::OverloadedTemplate:
+    // Visit the overloaded template set.
+    if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
+      return true;
+
+    return false;
+
+  case TemplateName::DependentTemplate:
+    // FIXME: Visit nested-name-specifier.
+    return false;
+      
+  case TemplateName::QualifiedTemplate:
+    // FIXME: Visit nested-name-specifier.
+    return Visit(MakeCursorTemplateRef(
+                                  Name.getAsQualifiedTemplateName()->getDecl(), 
+                                       Loc, TU));
+
+  case TemplateName::SubstTemplateTemplateParm:
+    return Visit(MakeCursorTemplateRef(
+                         Name.getAsSubstTemplateTemplateParm()->getParameter(),
+                                       Loc, TU));
+      
+  case TemplateName::SubstTemplateTemplateParmPack:
+    return Visit(MakeCursorTemplateRef(
+                  Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
+                                       Loc, TU));
+  }
+
+  llvm_unreachable("Invalid TemplateName::Kind!");
+}
+
+bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
+  switch (TAL.getArgument().getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Pack:
+    return false;
+      
+  case TemplateArgument::Type:
+    if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
+      return Visit(TSInfo->getTypeLoc());
+    return false;
+      
+  case TemplateArgument::Declaration:
+    if (Expr *E = TAL.getSourceDeclExpression())
+      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
+    return false;
+
+  case TemplateArgument::NullPtr:
+    if (Expr *E = TAL.getSourceNullPtrExpression())
+      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
+    return false;
+
+  case TemplateArgument::Expression:
+    if (Expr *E = TAL.getSourceExpression())
+      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
+    return false;
+  
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
+      return true;
+      
+    return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(), 
+                             TAL.getTemplateNameLoc());
+  }
+
+  llvm_unreachable("Invalid TemplateArgument::Kind!");
+}
+
+bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  return VisitDeclContext(D);
+}
+
+bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  return Visit(TL.getUnqualifiedLoc());
+}
+
+bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  ASTContext &Context = AU->getASTContext();
+
+  // Some builtin types (such as Objective-C's "id", "sel", and
+  // "Class") have associated declarations. Create cursors for those.
+  QualType VisitType;
+  switch (TL.getTypePtr()->getKind()) {
+
+  case BuiltinType::Void:
+  case BuiltinType::NullPtr:
+  case BuiltinType::Dependent:
+#define BUILTIN_TYPE(Id, SingletonId)
+#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
+#include "clang/AST/BuiltinTypes.def"
+    break;
+
+  case BuiltinType::ObjCId:
+    VisitType = Context.getObjCIdType();
+    break;
+
+  case BuiltinType::ObjCClass:
+    VisitType = Context.getObjCClassType();
+    break;
+
+  case BuiltinType::ObjCSel:
+    VisitType = Context.getObjCSelType();
+    break;
+  }
+
+  if (!VisitType.isNull()) {
+    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
+      return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
+                                     TU));
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
+  if (TL.isDefinition())
+    return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
+
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
+    return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
+    return true;
+
+  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
+                                        TU)))
+      return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
+  return Visit(TL.getInnerLoc());
+}
+
+bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  return Visit(TL.getPointeeLoc());
+}
+
+bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
+  return Visit(TL.getModifiedLoc());
+}
+
+bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 
+                                         bool SkipResultType) {
+  if (!SkipResultType && Visit(TL.getResultLoc()))
+    return true;
+
+  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
+    if (Decl *D = TL.getArg(I))
+      if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
+        return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  if (Visit(TL.getElementLoc()))
+    return true;
+
+  if (Expr *Size = TL.getSizeExpr())
+    return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
+
+  return false;
+}
+
+bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
+                                             TemplateSpecializationTypeLoc TL) {
+  // Visit the template name.
+  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 
+                        TL.getTemplateNameLoc()))
+    return true;
+  
+  // Visit the template arguments.
+  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
+    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
+      return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+  return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
+}
+
+bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
+bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
+  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
+bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+    return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
+                                    DependentTemplateSpecializationTypeLoc TL) {
+  // Visit the nested-name-specifier, if there is one.
+  if (TL.getQualifierLoc() &&
+      VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+    return true;
+  
+  // Visit the template arguments.
+  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
+    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
+      return true;
+
+  return false;
+}
+
+bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+    return true;
+  
+  return Visit(TL.getNamedTypeLoc());
+}
+
+bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
+  return Visit(TL.getPatternLoc());
+}
+
+bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+  if (Expr *E = TL.getUnderlyingExpr())
+    return Visit(MakeCXCursor(E, StmtParent, TU));
+
+  return false;
+}
+
+bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+  return Visit(TL.getValueLoc());
+}
+
+#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
+bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+  return Visit##PARENT##Loc(TL); \
+}
+
+DEFAULT_TYPELOC_IMPL(Complex, Type)
+DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
+DEFAULT_TYPELOC_IMPL(Vector, Type)
+DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
+DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
+DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
+DEFAULT_TYPELOC_IMPL(Record, TagType)
+DEFAULT_TYPELOC_IMPL(Enum, TagType)
+DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
+DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
+DEFAULT_TYPELOC_IMPL(Auto, Type)
+
+bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  // Visit the nested-name-specifier, if present.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+
+  if (D->isCompleteDefinition()) {
+    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+         E = D->bases_end(); I != E; ++I) {
+      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
+        return true;
+    }
+  }
+
+  return VisitTagDecl(D);
+}
+
+bool CursorVisitor::VisitAttributes(Decl *D) {
+  for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
+       i != e; ++i)
+    if (Visit(MakeCXCursor(*i, D, TU)))
+        return true;
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Data-recursive visitor methods.
+//===----------------------------------------------------------------------===//
+
+namespace {
+#define DEF_JOB(NAME, DATA, KIND)\
+class NAME : public VisitorJob {\
+public:\
+  NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
+  static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
+  DATA *get() const { return static_cast<DATA*>(data[0]); }\
+};
+
+DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
+DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
+DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
+DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
+DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo, 
+        ExplicitTemplateArgsVisitKind)
+DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
+DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
+DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
+#undef DEF_JOB
+
+class DeclVisit : public VisitorJob {
+public:
+  DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
+    VisitorJob(parent, VisitorJob::DeclVisitKind,
+               d, isFirst ? (void*) 1 : (void*) 0) {}
+  static bool classof(const VisitorJob *VJ) {
+    return VJ->getKind() == DeclVisitKind;
+  }
+  Decl *get() const { return static_cast<Decl*>(data[0]); }
+  bool isFirst() const { return data[1] ? true : false; }
+};
+class TypeLocVisit : public VisitorJob {
+public:
+  TypeLocVisit(TypeLoc tl, CXCursor parent) :
+    VisitorJob(parent, VisitorJob::TypeLocVisitKind,
+               tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
+
+  static bool classof(const VisitorJob *VJ) {
+    return VJ->getKind() == TypeLocVisitKind;
+  }
+
+  TypeLoc get() const { 
+    QualType T = QualType::getFromOpaquePtr(data[0]);
+    return TypeLoc(T, data[1]);
+  }
+};
+
+class LabelRefVisit : public VisitorJob {
+public:
+  LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
+    : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
+                 labelLoc.getPtrEncoding()) {}
+  
+  static bool classof(const VisitorJob *VJ) {
+    return VJ->getKind() == VisitorJob::LabelRefVisitKind;
+  }
+  LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
+  SourceLocation getLoc() const { 
+    return SourceLocation::getFromPtrEncoding(data[1]); }
+};
+  
+class NestedNameSpecifierLocVisit : public VisitorJob {
+public:
+  NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
+    : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
+                 Qualifier.getNestedNameSpecifier(),
+                 Qualifier.getOpaqueData()) { }
+  
+  static bool classof(const VisitorJob *VJ) {
+    return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
+  }
+  
+  NestedNameSpecifierLoc get() const {
+    return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]), 
+                                  data[1]);
+  }
+};
+  
+class DeclarationNameInfoVisit : public VisitorJob {
+public:
+  DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
+    : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
+  static bool classof(const VisitorJob *VJ) {
+    return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
+  }
+  DeclarationNameInfo get() const {
+    Stmt *S = static_cast<Stmt*>(data[0]);
+    switch (S->getStmtClass()) {
+    default:
+      llvm_unreachable("Unhandled Stmt");
+    case clang::Stmt::MSDependentExistsStmtClass:
+      return cast<MSDependentExistsStmt>(S)->getNameInfo();
+    case Stmt::CXXDependentScopeMemberExprClass:
+      return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
+    case Stmt::DependentScopeDeclRefExprClass:
+      return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
+    }
+  }
+};
+class MemberRefVisit : public VisitorJob {
+public:
+  MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
+    : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
+                 L.getPtrEncoding()) {}
+  static bool classof(const VisitorJob *VJ) {
+    return VJ->getKind() == VisitorJob::MemberRefVisitKind;
+  }
+  FieldDecl *get() const {
+    return static_cast<FieldDecl*>(data[0]);
+  }
+  SourceLocation getLoc() const {
+    return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
+  }
+};
+class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
+  VisitorWorkList &WL;
+  CXCursor Parent;
+public:
+  EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
+    : WL(wl), Parent(parent) {}
+
+  void VisitAddrLabelExpr(AddrLabelExpr *E);
+  void VisitBlockExpr(BlockExpr *B);
+  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+  void VisitCompoundStmt(CompoundStmt *S);
+  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
+  void VisitMSDependentExistsStmt(MSDependentExistsStmt *S);
+  void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+  void VisitCXXNewExpr(CXXNewExpr *E);
+  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
+  void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+  void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
+  void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
+  void VisitCXXTypeidExpr(CXXTypeidExpr *E);
+  void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
+  void VisitCXXUuidofExpr(CXXUuidofExpr *E);
+  void VisitCXXCatchStmt(CXXCatchStmt *S);
+  void VisitDeclRefExpr(DeclRefExpr *D);
+  void VisitDeclStmt(DeclStmt *S);
+  void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
+  void VisitDesignatedInitExpr(DesignatedInitExpr *E);
+  void VisitExplicitCastExpr(ExplicitCastExpr *E);
+  void VisitForStmt(ForStmt *FS);
+  void VisitGotoStmt(GotoStmt *GS);
+  void VisitIfStmt(IfStmt *If);
+  void VisitInitListExpr(InitListExpr *IE);
+  void VisitMemberExpr(MemberExpr *M);
+  void VisitOffsetOfExpr(OffsetOfExpr *E);
+  void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
+  void VisitObjCMessageExpr(ObjCMessageExpr *M);
+  void VisitOverloadExpr(OverloadExpr *E);
+  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
+  void VisitStmt(Stmt *S);
+  void VisitSwitchStmt(SwitchStmt *S);
+  void VisitWhileStmt(WhileStmt *W);
+  void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
+  void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
+  void VisitTypeTraitExpr(TypeTraitExpr *E);
+  void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
+  void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
+  void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
+  void VisitVAArgExpr(VAArgExpr *E);
+  void VisitSizeOfPackExpr(SizeOfPackExpr *E);
+  void VisitPseudoObjectExpr(PseudoObjectExpr *E);
+  void VisitOpaqueValueExpr(OpaqueValueExpr *E);
+  void VisitLambdaExpr(LambdaExpr *E);
+  
+private:
+  void AddDeclarationNameInfo(Stmt *S);
+  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
+  void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
+  void AddMemberRef(FieldDecl *D, SourceLocation L);
+  void AddStmt(Stmt *S);
+  void AddDecl(Decl *D, bool isFirst = true);
+  void AddTypeLoc(TypeSourceInfo *TI);
+  void EnqueueChildren(Stmt *S);
+};
+} // end anonyous namespace
+
+void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
+  // 'S' should always be non-null, since it comes from the
+  // statement we are visiting.
+  WL.push_back(DeclarationNameInfoVisit(S, Parent));
+}
+
+void 
+EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
+  if (Qualifier)
+    WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
+}
+
+void EnqueueVisitor::AddStmt(Stmt *S) {
+  if (S)
+    WL.push_back(StmtVisit(S, Parent));
+}
+void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
+  if (D)
+    WL.push_back(DeclVisit(D, Parent, isFirst));
+}
+void EnqueueVisitor::
+  AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
+  if (A)
+    WL.push_back(ExplicitTemplateArgsVisit(
+                        const_cast<ASTTemplateArgumentListInfo*>(A), Parent));
+}
+void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
+  if (D)
+    WL.push_back(MemberRefVisit(D, L, Parent));
+}
+void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
+  if (TI)
+    WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
+ }
+void EnqueueVisitor::EnqueueChildren(Stmt *S) {
+  unsigned size = WL.size();
+  for (Stmt::child_range Child = S->children(); Child; ++Child) {
+    AddStmt(*Child);
+  }
+  if (size == WL.size())
+    return;
+  // Now reverse the entries we just added.  This will match the DFS
+  // ordering performed by the worklist.
+  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
+  std::reverse(I, E);
+}
+void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
+  WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
+}
+void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
+  AddDecl(B->getBlockDecl());
+}
+void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  EnqueueChildren(E);
+  AddTypeLoc(E->getTypeSourceInfo());
+}
+void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
+  for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
+        E = S->body_rend(); I != E; ++I) {
+    AddStmt(*I);
+  }
+}
+void EnqueueVisitor::
+VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
+  AddStmt(S->getSubStmt());
+  AddDeclarationNameInfo(S);
+  if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
+    AddNestedNameSpecifierLoc(QualifierLoc);
+}
+
+void EnqueueVisitor::
+VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
+  AddDeclarationNameInfo(E);
+  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
+    AddNestedNameSpecifierLoc(QualifierLoc);
+  if (!E->isImplicitAccess())
+    AddStmt(E->getBase());
+}
+void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
+  // Enqueue the initializer , if any.
+  AddStmt(E->getInitializer());
+  // Enqueue the array size, if any.
+  AddStmt(E->getArraySize());
+  // Enqueue the allocated type.
+  AddTypeLoc(E->getAllocatedTypeSourceInfo());
+  // Enqueue the placement arguments.
+  for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
+    AddStmt(E->getPlacementArg(I-1));
+}
+void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
+  for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
+    AddStmt(CE->getArg(I-1));
+  AddStmt(CE->getCallee());
+  AddStmt(CE->getArg(0));
+}
+void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+  // Visit the name of the type being destroyed.
+  AddTypeLoc(E->getDestroyedTypeInfo());
+  // Visit the scope type that looks disturbingly like the nested-name-specifier
+  // but isn't.
+  AddTypeLoc(E->getScopeTypeInfo());
+  // Visit the nested-name-specifier.
+  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
+    AddNestedNameSpecifierLoc(QualifierLoc);
+  // Visit base expression.
+  AddStmt(E->getBase());
+}
+void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+  AddTypeLoc(E->getTypeSourceInfo());
+}
+void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+  EnqueueChildren(E);
+  AddTypeLoc(E->getTypeSourceInfo());
+}
+void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+  EnqueueChildren(E);
+  if (E->isTypeOperand())
+    AddTypeLoc(E->getTypeOperandSourceInfo());
+}
+
+void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr 
+                                                     *E) {
+  EnqueueChildren(E);
+  AddTypeLoc(E->getTypeSourceInfo());
+}
+void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
+  EnqueueChildren(E);
+  if (E->isTypeOperand())
+    AddTypeLoc(E->getTypeOperandSourceInfo());
+}
+
+void EnqueueVisitor::VisitCXXCatchStmt(CXXCatchStmt *S) {
+  EnqueueChildren(S);
+  AddDecl(S->getExceptionDecl());
+}
+
+void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
+  if (DR->hasExplicitTemplateArgs()) {
+    AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
+  }
+  WL.push_back(DeclRefExprParts(DR, Parent));
+}
+void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
+  AddDeclarationNameInfo(E);
+  AddNestedNameSpecifierLoc(E->getQualifierLoc());
+}
+void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
+  unsigned size = WL.size();
+  bool isFirst = true;
+  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+       D != DEnd; ++D) {
+    AddDecl(*D, isFirst);
+    isFirst = false;
+  }
+  if (size == WL.size())
+    return;
+  // Now reverse the entries we just added.  This will match the DFS
+  // ordering performed by the worklist.
+  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
+  std::reverse(I, E);
+}
+void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  AddStmt(E->getInit());
+  typedef DesignatedInitExpr::Designator Designator;
+  for (DesignatedInitExpr::reverse_designators_iterator
+         D = E->designators_rbegin(), DEnd = E->designators_rend();
+         D != DEnd; ++D) {
+    if (D->isFieldDesignator()) {
+      if (FieldDecl *Field = D->getField())
+        AddMemberRef(Field, D->getFieldLoc());
+      continue;
+    }
+    if (D->isArrayDesignator()) {
+      AddStmt(E->getArrayIndex(*D));
+      continue;
+    }
+    assert(D->isArrayRangeDesignator() && "Unknown designator kind");
+    AddStmt(E->getArrayRangeEnd(*D));
+    AddStmt(E->getArrayRangeStart(*D));
+  }
+}
+void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  EnqueueChildren(E);
+  AddTypeLoc(E->getTypeInfoAsWritten());
+}
+void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
+  AddStmt(FS->getBody());
+  AddStmt(FS->getInc());
+  AddStmt(FS->getCond());
+  AddDecl(FS->getConditionVariable());
+  AddStmt(FS->getInit());
+}
+void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
+  WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
+}
+void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
+  AddStmt(If->getElse());
+  AddStmt(If->getThen());
+  AddStmt(If->getCond());
+  AddDecl(If->getConditionVariable());
+}
+void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
+  // We care about the syntactic form of the initializer list, only.
+  if (InitListExpr *Syntactic = IE->getSyntacticForm())
+    IE = Syntactic;
+  EnqueueChildren(IE);
+}
+void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
+  WL.push_back(MemberExprParts(M, Parent));
+  
+  // If the base of the member access expression is an implicit 'this', don't
+  // visit it.
+  // FIXME: If we ever want to show these implicit accesses, this will be
+  // unfortunate. However, clang_getCursor() relies on this behavior.
+  if (!M->isImplicitAccess())
+    AddStmt(M->getBase());
+}
+void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  AddTypeLoc(E->getEncodedTypeSourceInfo());
+}
+void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
+  EnqueueChildren(M);
+  AddTypeLoc(M->getClassReceiverTypeInfo());
+}
+void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
+  // Visit the components of the offsetof expression.
+  for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
+    typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
+    const OffsetOfNode &Node = E->getComponent(I-1);
+    switch (Node.getKind()) {
+    case OffsetOfNode::Array:
+      AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
+      break;
+    case OffsetOfNode::Field:
+      AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
+      break;
+    case OffsetOfNode::Identifier:
+    case OffsetOfNode::Base:
+      continue;
+    }
+  }
+  // Visit the type into which we're computing the offset.
+  AddTypeLoc(E->getTypeSourceInfo());
+}
+void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
+  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
+  WL.push_back(OverloadExprParts(E, Parent));
+}
+void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
+                                              UnaryExprOrTypeTraitExpr *E) {
+  EnqueueChildren(E);
+  if (E->isArgumentType())
+    AddTypeLoc(E->getArgumentTypeInfo());
+}
+void EnqueueVisitor::VisitStmt(Stmt *S) {
+  EnqueueChildren(S);
+}
+void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
+  AddStmt(S->getBody());
+  AddStmt(S->getCond());
+  AddDecl(S->getConditionVariable());
+}
+
+void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
+  AddStmt(W->getBody());
+  AddStmt(W->getCond());
+  AddDecl(W->getConditionVariable());
+}
+
+void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+  AddTypeLoc(E->getQueriedTypeSourceInfo());
+}
+
+void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
+  AddTypeLoc(E->getRhsTypeSourceInfo());
+  AddTypeLoc(E->getLhsTypeSourceInfo());
+}
+
+void EnqueueVisitor::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  for (unsigned I = E->getNumArgs(); I > 0; --I)
+    AddTypeLoc(E->getArg(I-1));
+}
+
+void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  AddTypeLoc(E->getQueriedTypeSourceInfo());
+}
+
+void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
+  EnqueueChildren(E);
+}
+
+void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
+  VisitOverloadExpr(U);
+  if (!U->isImplicitAccess())
+    AddStmt(U->getBase());
+}
+void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
+  AddStmt(E->getSubExpr());
+  AddTypeLoc(E->getWrittenTypeInfo());
+}
+void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
+  WL.push_back(SizeOfPackExprParts(E, Parent));
+}
+void EnqueueVisitor::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
+  // If the opaque value has a source expression, just transparently
+  // visit that.  This is useful for (e.g.) pseudo-object expressions.
+  if (Expr *SourceExpr = E->getSourceExpr())
+    return Visit(SourceExpr);
+}
+void EnqueueVisitor::VisitLambdaExpr(LambdaExpr *E) {
+  AddStmt(E->getBody());
+  WL.push_back(LambdaExprParts(E, Parent));
+}
+void EnqueueVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+  // Treat the expression like its syntactic form.
+  Visit(E->getSyntacticForm());
+}
+
+void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
+  EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
+}
+
+bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
+  if (RegionOfInterest.isValid()) {
+    SourceRange Range = getRawCursorExtent(C);
+    if (Range.isInvalid() || CompareRegionOfInterest(Range))
+      return false;
+  }
+  return true;
+}
+
+bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
+  while (!WL.empty()) {
+    // Dequeue the worklist item.
+    VisitorJob LI = WL.back();
+    WL.pop_back();
+
+    // Set the Parent field, then back to its old value once we're done.
+    SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
+  
+    switch (LI.getKind()) {
+      case VisitorJob::DeclVisitKind: {
+        Decl *D = cast<DeclVisit>(&LI)->get();
+        if (!D)
+          continue;
+
+        // For now, perform default visitation for Decls.
+        if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
+                               cast<DeclVisit>(&LI)->isFirst())))
+            return true;
+
+        continue;
+      }
+      case VisitorJob::ExplicitTemplateArgsVisitKind: {
+        const ASTTemplateArgumentListInfo *ArgList =
+          cast<ExplicitTemplateArgsVisit>(&LI)->get();
+        for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
+               *ArgEnd = Arg + ArgList->NumTemplateArgs;
+               Arg != ArgEnd; ++Arg) {
+          if (VisitTemplateArgumentLoc(*Arg))
+            return true;
+        }
+        continue;
+      }
+      case VisitorJob::TypeLocVisitKind: {
+        // Perform default visitation for TypeLocs.
+        if (Visit(cast<TypeLocVisit>(&LI)->get()))
+          return true;
+        continue;
+      }
+      case VisitorJob::LabelRefVisitKind: {
+        LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
+        if (LabelStmt *stmt = LS->getStmt()) {
+          if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
+                                       TU))) {
+            return true;
+          }
+        }
+        continue;
+      }
+
+      case VisitorJob::NestedNameSpecifierLocVisitKind: {
+        NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
+        if (VisitNestedNameSpecifierLoc(V->get()))
+          return true;
+        continue;
+      }
+        
+      case VisitorJob::DeclarationNameInfoVisitKind: {
+        if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
+                                     ->get()))
+          return true;
+        continue;
+      }
+      case VisitorJob::MemberRefVisitKind: {
+        MemberRefVisit *V = cast<MemberRefVisit>(&LI);
+        if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
+          return true;
+        continue;
+      }
+      case VisitorJob::StmtVisitKind: {
+        Stmt *S = cast<StmtVisit>(&LI)->get();
+        if (!S)
+          continue;
+
+        // Update the current cursor.
+        CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
+        if (!IsInRegionOfInterest(Cursor))
+          continue;
+        switch (Visitor(Cursor, Parent, ClientData)) {
+          case CXChildVisit_Break: return true;
+          case CXChildVisit_Continue: break;
+          case CXChildVisit_Recurse:
+            if (PostChildrenVisitor)
+              WL.push_back(PostChildrenVisit(0, Cursor));
+            EnqueueWorkList(WL, S);
+            break;
+        }
+        continue;
+      }
+      case VisitorJob::MemberExprPartsKind: {
+        // Handle the other pieces in the MemberExpr besides the base.
+        MemberExpr *M = cast<MemberExprParts>(&LI)->get();
+        
+        // Visit the nested-name-specifier
+        if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
+          if (VisitNestedNameSpecifierLoc(QualifierLoc))
+            return true;
+        
+        // Visit the declaration name.
+        if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
+          return true;
+        
+        // Visit the explicitly-specified template arguments, if any.
+        if (M->hasExplicitTemplateArgs()) {
+          for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
+               *ArgEnd = Arg + M->getNumTemplateArgs();
+               Arg != ArgEnd; ++Arg) {
+            if (VisitTemplateArgumentLoc(*Arg))
+              return true;
+          }
+        }
+        continue;
+      }
+      case VisitorJob::DeclRefExprPartsKind: {
+        DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
+        // Visit nested-name-specifier, if present.
+        if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
+          if (VisitNestedNameSpecifierLoc(QualifierLoc))
+            return true;
+        // Visit declaration name.
+        if (VisitDeclarationNameInfo(DR->getNameInfo()))
+          return true;
+        continue;
+      }
+      case VisitorJob::OverloadExprPartsKind: {
+        OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
+        // Visit the nested-name-specifier.
+        if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
+          if (VisitNestedNameSpecifierLoc(QualifierLoc))
+            return true;
+        // Visit the declaration name.
+        if (VisitDeclarationNameInfo(O->getNameInfo()))
+          return true;
+        // Visit the overloaded declaration reference.
+        if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
+          return true;
+        continue;
+      }
+      case VisitorJob::SizeOfPackExprPartsKind: {
+        SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
+        NamedDecl *Pack = E->getPack();
+        if (isa<TemplateTypeParmDecl>(Pack)) {
+          if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
+                                      E->getPackLoc(), TU)))
+            return true;
+          
+          continue;
+        }
+          
+        if (isa<TemplateTemplateParmDecl>(Pack)) {
+          if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
+                                          E->getPackLoc(), TU)))
+            return true;
+          
+          continue;
+        }
+        
+        // Non-type template parameter packs and function parameter packs are
+        // treated like DeclRefExpr cursors.
+        continue;
+      }
+        
+      case VisitorJob::LambdaExprPartsKind: {
+        // Visit captures.
+        LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
+        for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
+                                       CEnd = E->explicit_capture_end();
+             C != CEnd; ++C) {
+          if (C->capturesThis())
+            continue;
+          
+          if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
+                                          C->getLocation(),
+                                          TU)))
+            return true;
+        }
+        
+        // Visit parameters and return type, if present.
+        if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
+          TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+          if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
+            // Visit the whole type.
+            if (Visit(TL))
+              return true;
+          } else if (isa<FunctionProtoTypeLoc>(TL)) {
+            FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+            if (E->hasExplicitParameters()) {
+              // Visit parameters.
+              for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
+                if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
+                  return true;
+            } else {
+              // Visit result type.
+              if (Visit(Proto.getResultLoc()))
+                return true;
+            }
+          }
+        }
+        break;
+      }
+
+      case VisitorJob::PostChildrenVisitKind:
+        if (PostChildrenVisitor(Parent, ClientData))
+          return true;
+        break;
+    }
+  }
+  return false;
+}
+
+bool CursorVisitor::Visit(Stmt *S) {
+  VisitorWorkList *WL = 0;
+  if (!WorkListFreeList.empty()) {
+    WL = WorkListFreeList.back();
+    WL->clear();
+    WorkListFreeList.pop_back();
+  }
+  else {
+    WL = new VisitorWorkList();
+    WorkListCache.push_back(WL);
+  }
+  EnqueueWorkList(*WL, S);
+  bool result = RunVisitorWorkList(*WL);
+  WorkListFreeList.push_back(WL);
+  return result;
+}
+
+namespace {
+typedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
+RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, 
+                          const DeclarationNameInfo &NI, 
+                          const SourceRange &QLoc, 
+                          const ASTTemplateArgumentListInfo *TemplateArgs = 0){
+  const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
+  const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
+  const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
+  
+  const DeclarationName::NameKind Kind = NI.getName().getNameKind();
+  
+  RefNamePieces Pieces;
+
+  if (WantQualifier && QLoc.isValid())
+    Pieces.push_back(QLoc);
+  
+  if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
+    Pieces.push_back(NI.getLoc());
+  
+  if (WantTemplateArgs && TemplateArgs)
+    Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
+                                 TemplateArgs->RAngleLoc));
+  
+  if (Kind == DeclarationName::CXXOperatorName) {
+    Pieces.push_back(SourceLocation::getFromRawEncoding(
+                       NI.getInfo().CXXOperatorName.BeginOpNameLoc));
+    Pieces.push_back(SourceLocation::getFromRawEncoding(
+                       NI.getInfo().CXXOperatorName.EndOpNameLoc));
+  }
+  
+  if (WantSinglePiece) {
+    SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
+    Pieces.clear();
+    Pieces.push_back(R);
+  }  
+
+  return Pieces;  
+}
+}
+
+//===----------------------------------------------------------------------===//
+// Misc. API hooks.
+//===----------------------------------------------------------------------===//               
+
+static llvm::sys::Mutex EnableMultithreadingMutex;
+static bool EnabledMultithreading;
+
+static void fatal_error_handler(void *user_data, const std::string& reason) {
+  // Write the result out to stderr avoiding errs() because raw_ostreams can
+  // call report_fatal_error.
+  fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
+  ::abort();
+}
+
+extern "C" {
+CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                          int displayDiagnostics) {
+  // Disable pretty stack trace functionality, which will otherwise be a very
+  // poor citizen of the world and set up all sorts of signal handlers.
+  llvm::DisablePrettyStackTrace = true;
+
+  // We use crash recovery to make some of our APIs more reliable, implicitly
+  // enable it.
+  llvm::CrashRecoveryContext::Enable();
+
+  // Enable support for multithreading in LLVM.
+  {
+    llvm::sys::ScopedLock L(EnableMultithreadingMutex);
+    if (!EnabledMultithreading) {
+      llvm::install_fatal_error_handler(fatal_error_handler, 0);
+      llvm::llvm_start_multithreaded();
+      EnabledMultithreading = true;
+    }
+  }
+
+  CIndexer *CIdxr = new CIndexer();
+  if (excludeDeclarationsFromPCH)
+    CIdxr->setOnlyLocalDecls();
+  if (displayDiagnostics)
+    CIdxr->setDisplayDiagnostics();
+
+  if (getenv("LIBCLANG_BGPRIO_INDEX"))
+    CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
+                               CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
+  if (getenv("LIBCLANG_BGPRIO_EDIT"))
+    CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
+                               CXGlobalOpt_ThreadBackgroundPriorityForEditing);
+
+  return CIdxr;
+}
+
+void clang_disposeIndex(CXIndex CIdx) {
+  if (CIdx)
+    delete static_cast<CIndexer *>(CIdx);
+}
+
+void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
+  if (CIdx)
+    static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
+}
+
+unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
+  if (CIdx)
+    return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
+  return 0;
+}
+
+void clang_toggleCrashRecovery(unsigned isEnabled) {
+  if (isEnabled)
+    llvm::CrashRecoveryContext::Enable();
+  else
+    llvm::CrashRecoveryContext::Disable();
+}
+  
+CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
+                                              const char *ast_filename) {
+  if (!CIdx)
+    return 0;
+
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+  FileSystemOptions FileSystemOpts;
+
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+  ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
+                                  CXXIdx->getOnlyLocalDecls(),
+                                  0, 0,
+                                  /*CaptureDiagnostics=*/true,
+                                  /*AllowPCHWithCompilerErrors=*/true,
+                                  /*UserFilesAreVolatile=*/true);
+  return MakeCXTranslationUnit(CXXIdx, TU);
+}
+
+unsigned clang_defaultEditingTranslationUnitOptions() {
+  return CXTranslationUnit_PrecompiledPreamble | 
+         CXTranslationUnit_CacheCompletionResults;
+}
+  
+CXTranslationUnit
+clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
+                                          const char *source_filename,
+                                          int num_command_line_args,
+                                          const char * const *command_line_args,
+                                          unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files) {
+  unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
+  return clang_parseTranslationUnit(CIdx, source_filename,
+                                    command_line_args, num_command_line_args,
+                                    unsaved_files, num_unsaved_files,
+                                    Options);
+}
+
+struct ParseTranslationUnitInfo {
+  CXIndex CIdx;
+  const char *source_filename;
+  const char *const *command_line_args;
+  int num_command_line_args;
+  struct CXUnsavedFile *unsaved_files;
+  unsigned num_unsaved_files;
+  unsigned options;
+  CXTranslationUnit result;
+};
+static void clang_parseTranslationUnit_Impl(void *UserData) {
+  ParseTranslationUnitInfo *PTUI =
+    static_cast<ParseTranslationUnitInfo*>(UserData);
+  CXIndex CIdx = PTUI->CIdx;
+  const char *source_filename = PTUI->source_filename;
+  const char * const *command_line_args = PTUI->command_line_args;
+  int num_command_line_args = PTUI->num_command_line_args;
+  struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
+  unsigned num_unsaved_files = PTUI->num_unsaved_files;
+  unsigned options = PTUI->options;
+  PTUI->result = 0;
+
+  if (!CIdx)
+    return;
+
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
+    setThreadBackgroundPriority();
+
+  bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
+  // FIXME: Add a flag for modules.
+  TranslationUnitKind TUKind
+    = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
+  bool CacheCodeCompetionResults
+    = options & CXTranslationUnit_CacheCompletionResults;
+  bool IncludeBriefCommentsInCodeCompletion
+    = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
+  bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
+  bool ForSerialization = options & CXTranslationUnit_ForSerialization;
+
+  // Configure the diagnostics.
+  IntrusiveRefCntPtr<DiagnosticsEngine>
+    Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
+                                              num_command_line_args,
+                                              command_line_args));
+
+  // Recover resources if we crash before exiting this function.
+  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
+    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
+    DiagCleanup(Diags.getPtr());
+
+  OwningPtr<std::vector<ASTUnit::RemappedFile> >
+    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
+
+  // Recover resources if we crash before exiting this function.
+  llvm::CrashRecoveryContextCleanupRegistrar<
+    std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
+
+  for (unsigned I = 0; I != num_unsaved_files; ++I) {
+    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+    const llvm::MemoryBuffer *Buffer
+      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
+    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
+                                            Buffer));
+  }
+
+  OwningPtr<std::vector<const char *> >
+    Args(new std::vector<const char*>());
+
+  // Recover resources if we crash before exiting this method.
+  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
+    ArgsCleanup(Args.get());
+
+  // Since the Clang C library is primarily used by batch tools dealing with
+  // (often very broken) source code, where spell-checking can have a
+  // significant negative impact on performance (particularly when 
+  // precompiled headers are involved), we disable it by default.
+  // Only do this if we haven't found a spell-checking-related argument.
+  bool FoundSpellCheckingArgument = false;
+  for (int I = 0; I != num_command_line_args; ++I) {
+    if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
+        strcmp(command_line_args[I], "-fspell-checking") == 0) {
+      FoundSpellCheckingArgument = true;
+      break;
+    }
+  }
+  if (!FoundSpellCheckingArgument)
+    Args->push_back("-fno-spell-checking");
+  
+  Args->insert(Args->end(), command_line_args,
+               command_line_args + num_command_line_args);
+
+  // The 'source_filename' argument is optional.  If the caller does not
+  // specify it then it is assumed that the source file is specified
+  // in the actual argument list.
+  // Put the source file after command_line_args otherwise if '-x' flag is
+  // present it will be unused.
+  if (source_filename)
+    Args->push_back(source_filename);
+
+  // Do we need the detailed preprocessing record?
+  if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
+    Args->push_back("-Xclang");
+    Args->push_back("-detailed-preprocessing-record");
+  }
+  
+  unsigned NumErrors = Diags->getClient()->getNumErrors();
+  OwningPtr<ASTUnit> ErrUnit;
+  OwningPtr<ASTUnit> Unit(
+    ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0 
+                                 /* vector::data() not portable */,
+                                 Args->size() ? (&(*Args)[0] + Args->size()) :0,
+                                 Diags,
+                                 CXXIdx->getClangResourcesPath(),
+                                 CXXIdx->getOnlyLocalDecls(),
+                                 /*CaptureDiagnostics=*/true,
+                                 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
+                                 RemappedFiles->size(),
+                                 /*RemappedFilesKeepOriginalName=*/true,
+                                 PrecompilePreamble,
+                                 TUKind,
+                                 CacheCodeCompetionResults,
+                                 IncludeBriefCommentsInCodeCompletion,
+                                 /*AllowPCHWithCompilerErrors=*/true,
+                                 SkipFunctionBodies,
+                                 /*UserFilesAreVolatile=*/true,
+                                 ForSerialization,
+                                 &ErrUnit));
+
+  if (NumErrors != Diags->getClient()->getNumErrors()) {
+    // Make sure to check that 'Unit' is non-NULL.
+    if (CXXIdx->getDisplayDiagnostics())
+      printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
+  }
+
+  PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
+}
+CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
+                                             const char *source_filename,
+                                         const char * const *command_line_args,
+                                             int num_command_line_args,
+                                            struct CXUnsavedFile *unsaved_files,
+                                             unsigned num_unsaved_files,
+                                             unsigned options) {
+  ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
+                                    num_command_line_args, unsaved_files,
+                                    num_unsaved_files, options, 0 };
+  llvm::CrashRecoveryContext CRC;
+
+  if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
+    fprintf(stderr, "libclang: crash detected during parsing: {\n");
+    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
+    fprintf(stderr, "  'command_line_args' : [");
+    for (int i = 0; i != num_command_line_args; ++i) {
+      if (i)
+        fprintf(stderr, ", ");
+      fprintf(stderr, "'%s'", command_line_args[i]);
+    }
+    fprintf(stderr, "],\n");
+    fprintf(stderr, "  'unsaved_files' : [");
+    for (unsigned i = 0; i != num_unsaved_files; ++i) {
+      if (i)
+        fprintf(stderr, ", ");
+      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
+              unsaved_files[i].Length);
+    }
+    fprintf(stderr, "],\n");
+    fprintf(stderr, "  'options' : %d,\n", options);
+    fprintf(stderr, "}\n");
+    
+    return 0;
+  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
+    PrintLibclangResourceUsage(PTUI.result);
+  }
+  
+  return PTUI.result;
+}
+
+unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
+  return CXSaveTranslationUnit_None;
+}  
+
+namespace {
+
+struct SaveTranslationUnitInfo {
+  CXTranslationUnit TU;
+  const char *FileName;
+  unsigned options;
+  CXSaveError result;
+};
+
+}
+
+static void clang_saveTranslationUnit_Impl(void *UserData) {
+  SaveTranslationUnitInfo *STUI =
+    static_cast<SaveTranslationUnitInfo*>(UserData);
+
+  CIndexer *CXXIdx = (CIndexer*)STUI->TU->CIdx;
+  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
+    setThreadBackgroundPriority();
+
+  bool hadError = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName);
+  STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
+}
+
+int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
+                              unsigned options) {
+  if (!TU)
+    return CXSaveError_InvalidTU;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  if (!CXXUnit->hasSema())
+    return CXSaveError_InvalidTU;
+
+  SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
+
+  if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
+      getenv("LIBCLANG_NOTHREADS")) {
+    clang_saveTranslationUnit_Impl(&STUI);
+
+    if (getenv("LIBCLANG_RESOURCE_USAGE"))
+      PrintLibclangResourceUsage(TU);
+
+    return STUI.result;
+  }
+
+  // We have an AST that has invalid nodes due to compiler errors.
+  // Use a crash recovery thread for protection.
+
+  llvm::CrashRecoveryContext CRC;
+
+  if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
+    fprintf(stderr, "libclang: crash detected during AST saving: {\n");
+    fprintf(stderr, "  'filename' : '%s'\n", FileName);
+    fprintf(stderr, "  'options' : %d,\n", options);
+    fprintf(stderr, "}\n");
+
+    return CXSaveError_Unknown;
+
+  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
+    PrintLibclangResourceUsage(TU);
+  }
+
+  return STUI.result;
+}
+
+void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
+  if (CTUnit) {
+    // If the translation unit has been marked as unsafe to free, just discard
+    // it.
+    if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
+      return;
+
+    delete static_cast<ASTUnit *>(CTUnit->TUData);
+    disposeCXStringPool(CTUnit->StringPool);
+    delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
+    disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
+    delete CTUnit;
+  }
+}
+
+unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
+  return CXReparse_None;
+}
+
+struct ReparseTranslationUnitInfo {
+  CXTranslationUnit TU;
+  unsigned num_unsaved_files;
+  struct CXUnsavedFile *unsaved_files;
+  unsigned options;
+  int result;
+};
+
+static void clang_reparseTranslationUnit_Impl(void *UserData) {
+  ReparseTranslationUnitInfo *RTUI =
+    static_cast<ReparseTranslationUnitInfo*>(UserData);
+  CXTranslationUnit TU = RTUI->TU;
+
+  // Reset the associated diagnostics.
+  delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
+  TU->Diagnostics = 0;
+
+  unsigned num_unsaved_files = RTUI->num_unsaved_files;
+  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
+  unsigned options = RTUI->options;
+  (void) options;
+  RTUI->result = 1;
+
+  if (!TU)
+    return;
+
+  CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
+    setThreadBackgroundPriority();
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  
+  OwningPtr<std::vector<ASTUnit::RemappedFile> >
+    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
+  
+  // Recover resources if we crash before exiting this function.
+  llvm::CrashRecoveryContextCleanupRegistrar<
+    std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
+  
+  for (unsigned I = 0; I != num_unsaved_files; ++I) {
+    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+    const llvm::MemoryBuffer *Buffer
+      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
+    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
+                                            Buffer));
+  }
+  
+  if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
+                        RemappedFiles->size()))
+    RTUI->result = 0;
+}
+
+int clang_reparseTranslationUnit(CXTranslationUnit TU,
+                                 unsigned num_unsaved_files,
+                                 struct CXUnsavedFile *unsaved_files,
+                                 unsigned options) {
+  ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
+                                      options, 0 };
+
+  if (getenv("LIBCLANG_NOTHREADS")) {
+    clang_reparseTranslationUnit_Impl(&RTUI);
+    return RTUI.result;
+  }
+
+  llvm::CrashRecoveryContext CRC;
+
+  if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
+    fprintf(stderr, "libclang: crash detected during reparsing\n");
+    static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
+    return 1;
+  } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
+    PrintLibclangResourceUsage(TU);
+
+  return RTUI.result;
+}
+
+
+CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
+  if (!CTUnit)
+    return createCXString("");
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
+  return createCXString(CXXUnit->getOriginalSourceFileName(), true);
+}
+
+CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit*>(TU->TUData);
+  return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// CXFile Operations.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXString clang_getFileName(CXFile SFile) {
+  if (!SFile)
+    return createCXString((const char*)NULL);
+
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return createCXString(FEnt->getName());
+}
+
+time_t clang_getFileTime(CXFile SFile) {
+  if (!SFile)
+    return 0;
+
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return FEnt->getModificationTime();
+}
+
+CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
+  if (!tu)
+    return 0;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+
+  FileManager &FMgr = CXXUnit->getFileManager();
+  return const_cast<FileEntry *>(FMgr.getFile(file_name));
+}
+
+unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
+  if (!tu || !file)
+    return 0;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+  FileEntry *FEnt = static_cast<FileEntry *>(file);
+  return CXXUnit->getPreprocessor().getHeaderSearchInfo()
+                                          .isFileMultipleIncludeGuarded(FEnt);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// CXCursor Operations.
+//===----------------------------------------------------------------------===//
+
+static Decl *getDeclFromExpr(Stmt *E) {
+  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+    return getDeclFromExpr(CE->getSubExpr());
+
+  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+    return RefExpr->getDecl();
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return ME->getMemberDecl();
+  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+    return RE->getDecl();
+  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (PRE->isExplicitProperty())
+      return PRE->getExplicitProperty();
+    // It could be messaging both getter and setter as in:
+    // ++myobj.myprop;
+    // in which case prefer to associate the setter since it is less obvious
+    // from inspecting the source that the setter is going to get called.
+    if (PRE->isMessagingSetter())
+      return PRE->getImplicitPropertySetter();
+    return PRE->getImplicitPropertyGetter();
+  }
+  if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
+    return getDeclFromExpr(POE->getSyntacticForm());
+  if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
+    if (Expr *Src = OVE->getSourceExpr())
+      return getDeclFromExpr(Src);
+      
+  if (CallExpr *CE = dyn_cast<CallExpr>(E))
+    return getDeclFromExpr(CE->getCallee());
+  if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
+    if (!CE->isElidable())
+    return CE->getConstructor();
+  if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
+    return OME->getMethodDecl();
+
+  if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
+    return PE->getProtocol();
+  if (SubstNonTypeTemplateParmPackExpr *NTTP 
+                              = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
+    return NTTP->getParameterPack();
+  if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
+    if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || 
+        isa<ParmVarDecl>(SizeOfPack->getPack()))
+      return SizeOfPack->getPack();
+  
+  return 0;
+}
+
+static SourceLocation getLocationFromExpr(Expr *E) {
+  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+    return getLocationFromExpr(CE->getSubExpr());
+
+  if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
+    return /*FIXME:*/Msg->getLeftLoc();
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    return DRE->getLocation();
+  if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
+    return Member->getMemberLoc();
+  if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
+    return Ivar->getLocation();
+  if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
+    return SizeOfPack->getPackLoc();
+  if (ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
+    return PropRef->getLocation();
+  
+  return E->getLocStart();
+}
+
+extern "C" {
+
+unsigned clang_visitChildren(CXCursor parent,
+                             CXCursorVisitor visitor,
+                             CXClientData client_data) {
+  CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
+                          /*VisitPreprocessorLast=*/false);
+  return CursorVis.VisitChildren(parent);
+}
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#if __has_feature(blocks)
+typedef enum CXChildVisitResult 
+     (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
+
+static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
+    CXClientData client_data) {
+  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
+  return block(cursor, parent);
+}
+#else
+// If we are compiled with a compiler that doesn't have native blocks support,
+// define and call the block manually, so the 
+typedef struct _CXChildVisitResult
+{
+	void *isa;
+	int flags;
+	int reserved;
+	enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
+                                         CXCursor);
+} *CXCursorVisitorBlock;
+
+static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
+    CXClientData client_data) {
+  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
+  return block->invoke(block, cursor, parent);
+}
+#endif
+
+
+unsigned clang_visitChildrenWithBlock(CXCursor parent,
+                                      CXCursorVisitorBlock block) {
+  return clang_visitChildren(parent, visitWithBlock, block);
+}
+
+static CXString getDeclSpelling(Decl *D) {
+  if (!D)
+    return createCXString("");
+
+  NamedDecl *ND = dyn_cast<NamedDecl>(D);
+  if (!ND) {
+    if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
+      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
+        return createCXString(Property->getIdentifier()->getName());
+    
+    if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
+      if (Module *Mod = ImportD->getImportedModule())
+        return createCXString(Mod->getFullModuleName());
+
+    return createCXString("");
+  }
+  
+  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
+    return createCXString(OMD->getSelector().getAsString());
+
+  if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
+    // No, this isn't the same as the code below. getIdentifier() is non-virtual
+    // and returns different names. NamedDecl returns the class name and
+    // ObjCCategoryImplDecl returns the category name.
+    return createCXString(CIMP->getIdentifier()->getNameStart());
+
+  if (isa<UsingDirectiveDecl>(D))
+    return createCXString("");
+  
+  SmallString<1024> S;
+  llvm::raw_svector_ostream os(S);
+  ND->printName(os);
+  
+  return createCXString(os.str());
+}
+
+CXString clang_getCursorSpelling(CXCursor C) {
+  if (clang_isTranslationUnit(C.kind))
+    return clang_getTranslationUnitSpelling(
+                            static_cast<CXTranslationUnit>(C.data[2]));
+
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef: {
+      ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
+      return createCXString(Super->getIdentifier()->getNameStart());
+    }
+    case CXCursor_ObjCClassRef: {
+      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+      return createCXString(Class->getIdentifier()->getNameStart());
+    }
+    case CXCursor_ObjCProtocolRef: {
+      ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
+      assert(OID && "getCursorSpelling(): Missing protocol decl");
+      return createCXString(OID->getIdentifier()->getNameStart());
+    }
+    case CXCursor_CXXBaseSpecifier: {
+      CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+      return createCXString(B->getType().getAsString());
+    }
+    case CXCursor_TypeRef: {
+      TypeDecl *Type = getCursorTypeRef(C).first;
+      assert(Type && "Missing type decl");
+
+      return createCXString(getCursorContext(C).getTypeDeclType(Type).
+                              getAsString());
+    }
+    case CXCursor_TemplateRef: {
+      TemplateDecl *Template = getCursorTemplateRef(C).first;
+      assert(Template && "Missing template decl");
+      
+      return createCXString(Template->getNameAsString());
+    }
+        
+    case CXCursor_NamespaceRef: {
+      NamedDecl *NS = getCursorNamespaceRef(C).first;
+      assert(NS && "Missing namespace decl");
+      
+      return createCXString(NS->getNameAsString());
+    }
+
+    case CXCursor_MemberRef: {
+      FieldDecl *Field = getCursorMemberRef(C).first;
+      assert(Field && "Missing member decl");
+      
+      return createCXString(Field->getNameAsString());
+    }
+
+    case CXCursor_LabelRef: {
+      LabelStmt *Label = getCursorLabelRef(C).first;
+      assert(Label && "Missing label");
+      
+      return createCXString(Label->getName());
+    }
+
+    case CXCursor_OverloadedDeclRef: {
+      OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
+      if (Decl *D = Storage.dyn_cast<Decl *>()) {
+        if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+          return createCXString(ND->getNameAsString());
+        return createCXString("");
+      }
+      if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+        return createCXString(E->getName().getAsString());
+      OverloadedTemplateStorage *Ovl
+        = Storage.get<OverloadedTemplateStorage*>();
+      if (Ovl->size() == 0)
+        return createCXString("");
+      return createCXString((*Ovl->begin())->getNameAsString());
+    }
+        
+    case CXCursor_VariableRef: {
+      VarDecl *Var = getCursorVariableRef(C).first;
+      assert(Var && "Missing variable decl");
+      
+      return createCXString(Var->getNameAsString());
+    }
+        
+    default:
+      return createCXString("<not implemented>");
+    }
+  }
+
+  if (clang_isExpression(C.kind)) {
+    Decl *D = getDeclFromExpr(getCursorExpr(C));
+    if (D)
+      return getDeclSpelling(D);
+    return createCXString("");
+  }
+
+  if (clang_isStatement(C.kind)) {
+    Stmt *S = getCursorStmt(C);
+    if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
+      return createCXString(Label->getName());
+
+    return createCXString("");
+  }
+  
+  if (C.kind == CXCursor_MacroExpansion)
+    return createCXString(getCursorMacroExpansion(C)->getName()
+                                                           ->getNameStart());
+
+  if (C.kind == CXCursor_MacroDefinition)
+    return createCXString(getCursorMacroDefinition(C)->getName()
+                                                           ->getNameStart());
+
+  if (C.kind == CXCursor_InclusionDirective)
+    return createCXString(getCursorInclusionDirective(C)->getFileName());
+      
+  if (clang_isDeclaration(C.kind))
+    return getDeclSpelling(getCursorDecl(C));
+
+  if (C.kind == CXCursor_AnnotateAttr) {
+    AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
+    return createCXString(AA->getAnnotation());
+  }
+
+  if (C.kind == CXCursor_AsmLabelAttr) {
+    AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
+    return createCXString(AA->getLabel());
+  }
+
+  return createCXString("");
+}
+
+CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
+                                                unsigned pieceIndex,
+                                                unsigned options) {
+  if (clang_Cursor_isNull(C))
+    return clang_getNullRange();
+
+  ASTContext &Ctx = getCursorContext(C);
+
+  if (clang_isStatement(C.kind)) {
+    Stmt *S = getCursorStmt(C);
+    if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
+      if (pieceIndex > 0)
+        return clang_getNullRange();
+      return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
+    }
+
+    return clang_getNullRange();
+  }
+
+  if (C.kind == CXCursor_ObjCMessageExpr) {
+    if (ObjCMessageExpr *
+          ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
+      if (pieceIndex >= ME->getNumSelectorLocs())
+        return clang_getNullRange();
+      return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
+    }
+  }
+
+  if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
+      C.kind == CXCursor_ObjCClassMethodDecl) {
+    if (ObjCMethodDecl *
+          MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
+      if (pieceIndex >= MD->getNumSelectorLocs())
+        return clang_getNullRange();
+      return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
+    }
+  }
+
+  if (C.kind == CXCursor_ObjCCategoryDecl ||
+      C.kind == CXCursor_ObjCCategoryImplDecl) {
+    if (pieceIndex > 0)
+      return clang_getNullRange();
+    if (ObjCCategoryDecl *
+          CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
+      return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
+    if (ObjCCategoryImplDecl *
+          CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
+      return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
+  }
+
+  if (C.kind == CXCursor_ModuleImportDecl) {
+    if (pieceIndex > 0)
+      return clang_getNullRange();
+    if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
+      ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
+      if (!Locs.empty())
+        return cxloc::translateSourceRange(Ctx,
+                                         SourceRange(Locs.front(), Locs.back()));
+    }
+    return clang_getNullRange();
+  }
+
+  // FIXME: A CXCursor_InclusionDirective should give the location of the
+  // filename, but we don't keep track of this.
+
+  // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
+  // but we don't keep track of this.
+
+  // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
+  // but we don't keep track of this.
+
+  // Default handling, give the location of the cursor.
+
+  if (pieceIndex > 0)
+    return clang_getNullRange();
+
+  CXSourceLocation CXLoc = clang_getCursorLocation(C);
+  SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
+  return cxloc::translateSourceRange(Ctx, Loc);
+}
+
+CXString clang_getCursorDisplayName(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return clang_getCursorSpelling(C);
+  
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return createCXString("");
+
+  PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
+    D = FunTmpl->getTemplatedDecl();
+  
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    SmallString<64> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << *Function;
+    if (Function->getPrimaryTemplate())
+      OS << "<>";
+    OS << "(";
+    for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
+      if (I)
+        OS << ", ";
+      OS << Function->getParamDecl(I)->getType().getAsString(Policy);
+    }
+    
+    if (Function->isVariadic()) {
+      if (Function->getNumParams())
+        OS << ", ";
+      OS << "...";
+    }
+    OS << ")";
+    return createCXString(OS.str());
+  }
+  
+  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
+    SmallString<64> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << *ClassTemplate;
+    OS << "<";
+    TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
+    for (unsigned I = 0, N = Params->size(); I != N; ++I) {
+      if (I)
+        OS << ", ";
+      
+      NamedDecl *Param = Params->getParam(I);
+      if (Param->getIdentifier()) {
+        OS << Param->getIdentifier()->getName();
+        continue;
+      }
+      
+      // There is no parameter name, which makes this tricky. Try to come up
+      // with something useful that isn't too long.
+      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
+        OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
+      else if (NonTypeTemplateParmDecl *NTTP
+                                    = dyn_cast<NonTypeTemplateParmDecl>(Param))
+        OS << NTTP->getType().getAsString(Policy);
+      else
+        OS << "template<...> class";
+    }
+    
+    OS << ">";
+    return createCXString(OS.str());
+  }
+  
+  if (ClassTemplateSpecializationDecl *ClassSpec
+                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    // If the type was explicitly written, use that.
+    if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
+      return createCXString(TSInfo->getType().getAsString(Policy));
+    
+    SmallString<64> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << *ClassSpec;
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                      ClassSpec->getTemplateArgs().data(),
+                                      ClassSpec->getTemplateArgs().size(),
+                                                                Policy);
+    return createCXString(OS.str());
+  }
+  
+  return clang_getCursorSpelling(C);
+}
+  
+CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
+  switch (Kind) {
+  case CXCursor_FunctionDecl:
+      return createCXString("FunctionDecl");
+  case CXCursor_TypedefDecl:
+      return createCXString("TypedefDecl");
+  case CXCursor_EnumDecl:
+      return createCXString("EnumDecl");
+  case CXCursor_EnumConstantDecl:
+      return createCXString("EnumConstantDecl");
+  case CXCursor_StructDecl:
+      return createCXString("StructDecl");
+  case CXCursor_UnionDecl:
+      return createCXString("UnionDecl");
+  case CXCursor_ClassDecl:
+      return createCXString("ClassDecl");
+  case CXCursor_FieldDecl:
+      return createCXString("FieldDecl");
+  case CXCursor_VarDecl:
+      return createCXString("VarDecl");
+  case CXCursor_ParmDecl:
+      return createCXString("ParmDecl");
+  case CXCursor_ObjCInterfaceDecl:
+      return createCXString("ObjCInterfaceDecl");
+  case CXCursor_ObjCCategoryDecl:
+      return createCXString("ObjCCategoryDecl");
+  case CXCursor_ObjCProtocolDecl:
+      return createCXString("ObjCProtocolDecl");
+  case CXCursor_ObjCPropertyDecl:
+      return createCXString("ObjCPropertyDecl");
+  case CXCursor_ObjCIvarDecl:
+      return createCXString("ObjCIvarDecl");
+  case CXCursor_ObjCInstanceMethodDecl:
+      return createCXString("ObjCInstanceMethodDecl");
+  case CXCursor_ObjCClassMethodDecl:
+      return createCXString("ObjCClassMethodDecl");
+  case CXCursor_ObjCImplementationDecl:
+      return createCXString("ObjCImplementationDecl");
+  case CXCursor_ObjCCategoryImplDecl:
+      return createCXString("ObjCCategoryImplDecl");
+  case CXCursor_CXXMethod:
+      return createCXString("CXXMethod");
+  case CXCursor_UnexposedDecl:
+      return createCXString("UnexposedDecl");
+  case CXCursor_ObjCSuperClassRef:
+      return createCXString("ObjCSuperClassRef");
+  case CXCursor_ObjCProtocolRef:
+      return createCXString("ObjCProtocolRef");
+  case CXCursor_ObjCClassRef:
+      return createCXString("ObjCClassRef");
+  case CXCursor_TypeRef:
+      return createCXString("TypeRef");
+  case CXCursor_TemplateRef:
+      return createCXString("TemplateRef");
+  case CXCursor_NamespaceRef:
+    return createCXString("NamespaceRef");
+  case CXCursor_MemberRef:
+    return createCXString("MemberRef");
+  case CXCursor_LabelRef:
+    return createCXString("LabelRef");
+  case CXCursor_OverloadedDeclRef:
+    return createCXString("OverloadedDeclRef");
+  case CXCursor_VariableRef:
+    return createCXString("VariableRef");
+  case CXCursor_IntegerLiteral:
+      return createCXString("IntegerLiteral");
+  case CXCursor_FloatingLiteral:
+      return createCXString("FloatingLiteral");
+  case CXCursor_ImaginaryLiteral:
+      return createCXString("ImaginaryLiteral");
+  case CXCursor_StringLiteral:
+      return createCXString("StringLiteral");
+  case CXCursor_CharacterLiteral:
+      return createCXString("CharacterLiteral");
+  case CXCursor_ParenExpr:
+      return createCXString("ParenExpr");
+  case CXCursor_UnaryOperator:
+      return createCXString("UnaryOperator");
+  case CXCursor_ArraySubscriptExpr:
+      return createCXString("ArraySubscriptExpr");
+  case CXCursor_BinaryOperator:
+      return createCXString("BinaryOperator");
+  case CXCursor_CompoundAssignOperator:
+      return createCXString("CompoundAssignOperator");
+  case CXCursor_ConditionalOperator:
+      return createCXString("ConditionalOperator");
+  case CXCursor_CStyleCastExpr:
+      return createCXString("CStyleCastExpr");
+  case CXCursor_CompoundLiteralExpr:
+      return createCXString("CompoundLiteralExpr");
+  case CXCursor_InitListExpr:
+      return createCXString("InitListExpr");
+  case CXCursor_AddrLabelExpr:
+      return createCXString("AddrLabelExpr");
+  case CXCursor_StmtExpr:
+      return createCXString("StmtExpr");
+  case CXCursor_GenericSelectionExpr:
+      return createCXString("GenericSelectionExpr");
+  case CXCursor_GNUNullExpr:
+      return createCXString("GNUNullExpr");
+  case CXCursor_CXXStaticCastExpr:
+      return createCXString("CXXStaticCastExpr");
+  case CXCursor_CXXDynamicCastExpr:
+      return createCXString("CXXDynamicCastExpr");
+  case CXCursor_CXXReinterpretCastExpr:
+      return createCXString("CXXReinterpretCastExpr");
+  case CXCursor_CXXConstCastExpr:
+      return createCXString("CXXConstCastExpr");
+  case CXCursor_CXXFunctionalCastExpr:
+      return createCXString("CXXFunctionalCastExpr");
+  case CXCursor_CXXTypeidExpr:
+      return createCXString("CXXTypeidExpr");
+  case CXCursor_CXXBoolLiteralExpr:
+      return createCXString("CXXBoolLiteralExpr");
+  case CXCursor_CXXNullPtrLiteralExpr:
+      return createCXString("CXXNullPtrLiteralExpr");
+  case CXCursor_CXXThisExpr:
+      return createCXString("CXXThisExpr");
+  case CXCursor_CXXThrowExpr:
+      return createCXString("CXXThrowExpr");
+  case CXCursor_CXXNewExpr:
+      return createCXString("CXXNewExpr");
+  case CXCursor_CXXDeleteExpr:
+      return createCXString("CXXDeleteExpr");
+  case CXCursor_UnaryExpr:
+      return createCXString("UnaryExpr");
+  case CXCursor_ObjCStringLiteral:
+      return createCXString("ObjCStringLiteral");
+  case CXCursor_ObjCBoolLiteralExpr:
+      return createCXString("ObjCBoolLiteralExpr");
+  case CXCursor_ObjCEncodeExpr:
+      return createCXString("ObjCEncodeExpr");
+  case CXCursor_ObjCSelectorExpr:
+      return createCXString("ObjCSelectorExpr");
+  case CXCursor_ObjCProtocolExpr:
+      return createCXString("ObjCProtocolExpr");
+  case CXCursor_ObjCBridgedCastExpr:
+      return createCXString("ObjCBridgedCastExpr");
+  case CXCursor_BlockExpr:
+      return createCXString("BlockExpr");
+  case CXCursor_PackExpansionExpr:
+      return createCXString("PackExpansionExpr");
+  case CXCursor_SizeOfPackExpr:
+      return createCXString("SizeOfPackExpr");
+  case CXCursor_LambdaExpr:
+    return createCXString("LambdaExpr");
+  case CXCursor_UnexposedExpr:
+      return createCXString("UnexposedExpr");
+  case CXCursor_DeclRefExpr:
+      return createCXString("DeclRefExpr");
+  case CXCursor_MemberRefExpr:
+      return createCXString("MemberRefExpr");
+  case CXCursor_CallExpr:
+      return createCXString("CallExpr");
+  case CXCursor_ObjCMessageExpr:
+      return createCXString("ObjCMessageExpr");
+  case CXCursor_UnexposedStmt:
+      return createCXString("UnexposedStmt");
+  case CXCursor_DeclStmt:
+      return createCXString("DeclStmt");
+  case CXCursor_LabelStmt:
+      return createCXString("LabelStmt");
+  case CXCursor_CompoundStmt:
+      return createCXString("CompoundStmt");
+  case CXCursor_CaseStmt:
+      return createCXString("CaseStmt");
+  case CXCursor_DefaultStmt:
+      return createCXString("DefaultStmt");
+  case CXCursor_IfStmt:
+      return createCXString("IfStmt");
+  case CXCursor_SwitchStmt:
+      return createCXString("SwitchStmt");
+  case CXCursor_WhileStmt:
+      return createCXString("WhileStmt");
+  case CXCursor_DoStmt:
+      return createCXString("DoStmt");
+  case CXCursor_ForStmt:
+      return createCXString("ForStmt");
+  case CXCursor_GotoStmt:
+      return createCXString("GotoStmt");
+  case CXCursor_IndirectGotoStmt:
+      return createCXString("IndirectGotoStmt");
+  case CXCursor_ContinueStmt:
+      return createCXString("ContinueStmt");
+  case CXCursor_BreakStmt:
+      return createCXString("BreakStmt");
+  case CXCursor_ReturnStmt:
+      return createCXString("ReturnStmt");
+  case CXCursor_GCCAsmStmt:
+      return createCXString("GCCAsmStmt");
+  case CXCursor_MSAsmStmt:
+      return createCXString("MSAsmStmt");
+  case CXCursor_ObjCAtTryStmt:
+      return createCXString("ObjCAtTryStmt");
+  case CXCursor_ObjCAtCatchStmt:
+      return createCXString("ObjCAtCatchStmt");
+  case CXCursor_ObjCAtFinallyStmt:
+      return createCXString("ObjCAtFinallyStmt");
+  case CXCursor_ObjCAtThrowStmt:
+      return createCXString("ObjCAtThrowStmt");
+  case CXCursor_ObjCAtSynchronizedStmt:
+      return createCXString("ObjCAtSynchronizedStmt");
+  case CXCursor_ObjCAutoreleasePoolStmt:
+      return createCXString("ObjCAutoreleasePoolStmt");
+  case CXCursor_ObjCForCollectionStmt:
+      return createCXString("ObjCForCollectionStmt");
+  case CXCursor_CXXCatchStmt:
+      return createCXString("CXXCatchStmt");
+  case CXCursor_CXXTryStmt:
+      return createCXString("CXXTryStmt");
+  case CXCursor_CXXForRangeStmt:
+      return createCXString("CXXForRangeStmt");
+  case CXCursor_SEHTryStmt:
+      return createCXString("SEHTryStmt");
+  case CXCursor_SEHExceptStmt:
+      return createCXString("SEHExceptStmt");
+  case CXCursor_SEHFinallyStmt:
+      return createCXString("SEHFinallyStmt");
+  case CXCursor_NullStmt:
+      return createCXString("NullStmt");
+  case CXCursor_InvalidFile:
+      return createCXString("InvalidFile");
+  case CXCursor_InvalidCode:
+    return createCXString("InvalidCode");
+  case CXCursor_NoDeclFound:
+      return createCXString("NoDeclFound");
+  case CXCursor_NotImplemented:
+      return createCXString("NotImplemented");
+  case CXCursor_TranslationUnit:
+      return createCXString("TranslationUnit");
+  case CXCursor_UnexposedAttr:
+      return createCXString("UnexposedAttr");
+  case CXCursor_IBActionAttr:
+      return createCXString("attribute(ibaction)");
+  case CXCursor_IBOutletAttr:
+     return createCXString("attribute(iboutlet)");
+  case CXCursor_IBOutletCollectionAttr:
+      return createCXString("attribute(iboutletcollection)");
+  case CXCursor_CXXFinalAttr:
+      return createCXString("attribute(final)");
+  case CXCursor_CXXOverrideAttr:
+      return createCXString("attribute(override)");
+  case CXCursor_AnnotateAttr:
+    return createCXString("attribute(annotate)");
+  case CXCursor_AsmLabelAttr:
+    return createCXString("asm label");
+  case CXCursor_PreprocessingDirective:
+    return createCXString("preprocessing directive");
+  case CXCursor_MacroDefinition:
+    return createCXString("macro definition");
+  case CXCursor_MacroExpansion:
+    return createCXString("macro expansion");
+  case CXCursor_InclusionDirective:
+    return createCXString("inclusion directive");
+  case CXCursor_Namespace:
+    return createCXString("Namespace");
+  case CXCursor_LinkageSpec:
+    return createCXString("LinkageSpec");
+  case CXCursor_CXXBaseSpecifier:
+    return createCXString("C++ base class specifier");  
+  case CXCursor_Constructor:
+    return createCXString("CXXConstructor");
+  case CXCursor_Destructor:
+    return createCXString("CXXDestructor");
+  case CXCursor_ConversionFunction:
+    return createCXString("CXXConversion");
+  case CXCursor_TemplateTypeParameter:
+    return createCXString("TemplateTypeParameter");
+  case CXCursor_NonTypeTemplateParameter:
+    return createCXString("NonTypeTemplateParameter");
+  case CXCursor_TemplateTemplateParameter:
+    return createCXString("TemplateTemplateParameter");
+  case CXCursor_FunctionTemplate:
+    return createCXString("FunctionTemplate");
+  case CXCursor_ClassTemplate:
+    return createCXString("ClassTemplate");
+  case CXCursor_ClassTemplatePartialSpecialization:
+    return createCXString("ClassTemplatePartialSpecialization");
+  case CXCursor_NamespaceAlias:
+    return createCXString("NamespaceAlias");
+  case CXCursor_UsingDirective:
+    return createCXString("UsingDirective");
+  case CXCursor_UsingDeclaration:
+    return createCXString("UsingDeclaration");
+  case CXCursor_TypeAliasDecl:
+    return createCXString("TypeAliasDecl");
+  case CXCursor_ObjCSynthesizeDecl:
+    return createCXString("ObjCSynthesizeDecl");
+  case CXCursor_ObjCDynamicDecl:
+    return createCXString("ObjCDynamicDecl");
+  case CXCursor_CXXAccessSpecifier:
+    return createCXString("CXXAccessSpecifier");
+  case CXCursor_ModuleImportDecl:
+    return createCXString("ModuleImport");
+  }
+
+  llvm_unreachable("Unhandled CXCursorKind");
+}
+
+struct GetCursorData {
+  SourceLocation TokenBeginLoc;
+  bool PointsAtMacroArgExpansion;
+  bool VisitedObjCPropertyImplDecl;
+  SourceLocation VisitedDeclaratorDeclStartLoc;
+  CXCursor &BestCursor;
+
+  GetCursorData(SourceManager &SM,
+                SourceLocation tokenBegin, CXCursor &outputCursor)
+    : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
+    PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
+    VisitedObjCPropertyImplDecl = false;
+  }
+};
+
+static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
+                                                CXCursor parent,
+                                                CXClientData client_data) {
+  GetCursorData *Data = static_cast<GetCursorData *>(client_data);
+  CXCursor *BestCursor = &Data->BestCursor;
+
+  // If we point inside a macro argument we should provide info of what the
+  // token is so use the actual cursor, don't replace it with a macro expansion
+  // cursor.
+  if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
+    return CXChildVisit_Recurse;
+  
+  if (clang_isDeclaration(cursor.kind)) {
+    // Avoid having the implicit methods override the property decls.
+    if (ObjCMethodDecl *MD
+          = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
+      if (MD->isImplicit())
+        return CXChildVisit_Break;
+
+    } else if (ObjCInterfaceDecl *ID
+                 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
+      // Check that when we have multiple @class references in the same line,
+      // that later ones do not override the previous ones.
+      // If we have:
+      // @class Foo, Bar;
+      // source ranges for both start at '@', so 'Bar' will end up overriding
+      // 'Foo' even though the cursor location was at 'Foo'.
+      if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
+          BestCursor->kind == CXCursor_ObjCClassRef)
+        if (ObjCInterfaceDecl *PrevID
+             = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
+         if (PrevID != ID &&
+             !PrevID->isThisDeclarationADefinition() &&
+             !ID->isThisDeclarationADefinition())
+           return CXChildVisit_Break;
+        }
+
+    } else if (DeclaratorDecl *DD
+                    = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
+      SourceLocation StartLoc = DD->getSourceRange().getBegin();
+      // Check that when we have multiple declarators in the same line,
+      // that later ones do not override the previous ones.
+      // If we have:
+      // int Foo, Bar;
+      // source ranges for both start at 'int', so 'Bar' will end up overriding
+      // 'Foo' even though the cursor location was at 'Foo'.
+      if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
+        return CXChildVisit_Break;
+      Data->VisitedDeclaratorDeclStartLoc = StartLoc;
+
+    } else if (ObjCPropertyImplDecl *PropImp
+              = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
+      (void)PropImp;
+      // Check that when we have multiple @synthesize in the same line,
+      // that later ones do not override the previous ones.
+      // If we have:
+      // @synthesize Foo, Bar;
+      // source ranges for both start at '@', so 'Bar' will end up overriding
+      // 'Foo' even though the cursor location was at 'Foo'.
+      if (Data->VisitedObjCPropertyImplDecl)
+        return CXChildVisit_Break;
+      Data->VisitedObjCPropertyImplDecl = true;
+    }
+  }
+
+  if (clang_isExpression(cursor.kind) &&
+      clang_isDeclaration(BestCursor->kind)) {
+    if (Decl *D = getCursorDecl(*BestCursor)) {
+      // Avoid having the cursor of an expression replace the declaration cursor
+      // when the expression source range overlaps the declaration range.
+      // This can happen for C++ constructor expressions whose range generally
+      // include the variable declaration, e.g.:
+      //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
+      if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
+          D->getLocation() == Data->TokenBeginLoc)
+        return CXChildVisit_Break;
+    }
+  }
+
+  // If our current best cursor is the construction of a temporary object, 
+  // don't replace that cursor with a type reference, because we want 
+  // clang_getCursor() to point at the constructor.
+  if (clang_isExpression(BestCursor->kind) &&
+      isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
+      cursor.kind == CXCursor_TypeRef) {
+    // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
+    // as having the actual point on the type reference.
+    *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
+    return CXChildVisit_Recurse;
+  }
+  
+  *BestCursor = cursor;
+  return CXChildVisit_Recurse;
+}
+
+CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
+  if (!TU)
+    return clang_getNullCursor();
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
+  CXCursor Result = cxcursor::getCursor(TU, SLoc);
+
+  bool Logging = getenv("LIBCLANG_LOGGING");  
+  if (Logging) {
+    CXFile SearchFile;
+    unsigned SearchLine, SearchColumn;
+    CXFile ResultFile;
+    unsigned ResultLine, ResultColumn;
+    CXString SearchFileName, ResultFileName, KindSpelling, USR;
+    const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
+    CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
+    
+    clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+    clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
+                               &ResultColumn, 0);
+    SearchFileName = clang_getFileName(SearchFile);
+    ResultFileName = clang_getFileName(ResultFile);
+    KindSpelling = clang_getCursorKindSpelling(Result.kind);
+    USR = clang_getCursorUSR(Result);
+    fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
+            clang_getCString(SearchFileName), SearchLine, SearchColumn,
+            clang_getCString(KindSpelling),
+            clang_getCString(ResultFileName), ResultLine, ResultColumn,
+            clang_getCString(USR), IsDef);
+    clang_disposeString(SearchFileName);
+    clang_disposeString(ResultFileName);
+    clang_disposeString(KindSpelling);
+    clang_disposeString(USR);
+    
+    CXCursor Definition = clang_getCursorDefinition(Result);
+    if (!clang_equalCursors(Definition, clang_getNullCursor())) {
+      CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
+      CXString DefinitionKindSpelling
+                                = clang_getCursorKindSpelling(Definition.kind);
+      CXFile DefinitionFile;
+      unsigned DefinitionLine, DefinitionColumn;
+      clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
+                                 &DefinitionLine, &DefinitionColumn, 0);
+      CXString DefinitionFileName = clang_getFileName(DefinitionFile);
+      fprintf(stderr, "  -> %s(%s:%d:%d)\n",
+              clang_getCString(DefinitionKindSpelling),
+              clang_getCString(DefinitionFileName),
+              DefinitionLine, DefinitionColumn);
+      clang_disposeString(DefinitionFileName);
+      clang_disposeString(DefinitionKindSpelling);
+    }
+  }
+
+  return Result;
+}
+
+CXCursor clang_getNullCursor(void) {
+  return MakeCXCursorInvalid(CXCursor_InvalidFile);
+}
+
+unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
+  return X == Y;
+}
+
+unsigned clang_hashCursor(CXCursor C) {
+  unsigned Index = 0;
+  if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
+    Index = 1;
+  
+  return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
+                                        std::make_pair(C.kind, C.data[Index]));
+}
+
+unsigned clang_isInvalid(enum CXCursorKind K) {
+  return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
+}
+
+unsigned clang_isDeclaration(enum CXCursorKind K) {
+  return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
+         (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
+}
+
+unsigned clang_isReference(enum CXCursorKind K) {
+  return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
+}
+
+unsigned clang_isExpression(enum CXCursorKind K) {
+  return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
+}
+
+unsigned clang_isStatement(enum CXCursorKind K) {
+  return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
+}
+
+unsigned clang_isAttribute(enum CXCursorKind K) {
+    return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
+}
+
+unsigned clang_isTranslationUnit(enum CXCursorKind K) {
+  return K == CXCursor_TranslationUnit;
+}
+
+unsigned clang_isPreprocessing(enum CXCursorKind K) {
+  return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
+}
+  
+unsigned clang_isUnexposed(enum CXCursorKind K) {
+  switch (K) {
+    case CXCursor_UnexposedDecl:
+    case CXCursor_UnexposedExpr:
+    case CXCursor_UnexposedStmt:
+    case CXCursor_UnexposedAttr:
+      return true;
+    default:
+      return false;
+  }
+}
+
+CXCursorKind clang_getCursorKind(CXCursor C) {
+  return C.kind;
+}
+
+CXSourceLocation clang_getCursorLocation(CXCursor C) {
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef: {
+      std::pair<ObjCInterfaceDecl *, SourceLocation> P
+        = getCursorObjCSuperClassRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_ObjCProtocolRef: {
+      std::pair<ObjCProtocolDecl *, SourceLocation> P
+        = getCursorObjCProtocolRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_ObjCClassRef: {
+      std::pair<ObjCInterfaceDecl *, SourceLocation> P
+        = getCursorObjCClassRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_TypeRef: {
+      std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_TemplateRef: {
+      std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_NamespaceRef: {
+      std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_MemberRef: {
+      std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_VariableRef: {
+      std::pair<VarDecl *, SourceLocation> P = getCursorVariableRef(C);
+      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
+    }
+
+    case CXCursor_CXXBaseSpecifier: {
+      CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
+      if (!BaseSpec)
+        return clang_getNullLocation();
+      
+      if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
+        return cxloc::translateSourceLocation(getCursorContext(C),
+                                            TSInfo->getTypeLoc().getBeginLoc());
+      
+      return cxloc::translateSourceLocation(getCursorContext(C),
+                                        BaseSpec->getLocStart());
+    }
+
+    case CXCursor_LabelRef: {
+      std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
+      return cxloc::translateSourceLocation(getCursorContext(C), P.second);
+    }
+
+    case CXCursor_OverloadedDeclRef:
+      return cxloc::translateSourceLocation(getCursorContext(C),
+                                          getCursorOverloadedDeclRef(C).second);
+
+    default:
+      // FIXME: Need a way to enumerate all non-reference cases.
+      llvm_unreachable("Missed a reference kind");
+    }
+  }
+
+  if (clang_isExpression(C.kind))
+    return cxloc::translateSourceLocation(getCursorContext(C),
+                                   getLocationFromExpr(getCursorExpr(C)));
+
+  if (clang_isStatement(C.kind))
+    return cxloc::translateSourceLocation(getCursorContext(C),
+                                          getCursorStmt(C)->getLocStart());
+
+  if (C.kind == CXCursor_PreprocessingDirective) {
+    SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+
+  if (C.kind == CXCursor_MacroExpansion) {
+    SourceLocation L
+      = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+
+  if (C.kind == CXCursor_MacroDefinition) {
+    SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+
+  if (C.kind == CXCursor_InclusionDirective) {
+    SourceLocation L
+      = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
+    return cxloc::translateSourceLocation(getCursorContext(C), L);
+  }
+
+  if (!clang_isDeclaration(C.kind))
+    return clang_getNullLocation();
+
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return clang_getNullLocation();
+
+  SourceLocation Loc = D->getLocation();
+  // FIXME: Multiple variables declared in a single declaration
+  // currently lack the information needed to correctly determine their
+  // ranges when accounting for the type-specifier.  We use context
+  // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+  // and if so, whether it is the first decl.
+  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (!cxcursor::isFirstInDeclGroup(C))
+      Loc = VD->getLocation();
+  }
+
+  // For ObjC methods, give the start location of the method name.
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+    Loc = MD->getSelectorStartLoc();
+
+  return cxloc::translateSourceLocation(getCursorContext(C), Loc);
+}
+
+} // end extern "C"
+
+CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
+  assert(TU);
+
+  // Guard against an invalid SourceLocation, or we may assert in one
+  // of the following calls.
+  if (SLoc.isInvalid())
+    return clang_getNullCursor();
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+
+  // Translate the given source location to make it point at the beginning of
+  // the token under the cursor.
+  SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
+                                    CXXUnit->getASTContext().getLangOpts());
+  
+  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
+  if (SLoc.isValid()) {
+    GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
+    CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
+                            /*VisitPreprocessorLast=*/true, 
+                            /*VisitIncludedEntities=*/false,
+                            SourceLocation(SLoc));
+    CursorVis.visitFileRegion();
+  }
+
+  return Result;
+}
+
+static SourceRange getRawCursorExtent(CXCursor C) {
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef:
+      return  getCursorObjCSuperClassRef(C).second;
+
+    case CXCursor_ObjCProtocolRef:
+      return getCursorObjCProtocolRef(C).second;
+
+    case CXCursor_ObjCClassRef:
+      return getCursorObjCClassRef(C).second;
+
+    case CXCursor_TypeRef:
+      return getCursorTypeRef(C).second;
+
+    case CXCursor_TemplateRef:
+      return getCursorTemplateRef(C).second;
+
+    case CXCursor_NamespaceRef:
+      return getCursorNamespaceRef(C).second;
+
+    case CXCursor_MemberRef:
+      return getCursorMemberRef(C).second;
+
+    case CXCursor_CXXBaseSpecifier:
+      return getCursorCXXBaseSpecifier(C)->getSourceRange();
+
+    case CXCursor_LabelRef:
+      return getCursorLabelRef(C).second;
+
+    case CXCursor_OverloadedDeclRef:
+      return getCursorOverloadedDeclRef(C).second;
+
+    case CXCursor_VariableRef:
+      return getCursorVariableRef(C).second;
+        
+    default:
+      // FIXME: Need a way to enumerate all non-reference cases.
+      llvm_unreachable("Missed a reference kind");
+    }
+  }
+
+  if (clang_isExpression(C.kind))
+    return getCursorExpr(C)->getSourceRange();
+
+  if (clang_isStatement(C.kind))
+    return getCursorStmt(C)->getSourceRange();
+
+  if (clang_isAttribute(C.kind))
+    return getCursorAttr(C)->getRange();
+
+  if (C.kind == CXCursor_PreprocessingDirective)
+    return cxcursor::getCursorPreprocessingDirective(C);
+
+  if (C.kind == CXCursor_MacroExpansion) {
+    ASTUnit *TU = getCursorASTUnit(C);
+    SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+    return TU->mapRangeFromPreamble(Range);
+  }
+
+  if (C.kind == CXCursor_MacroDefinition) {
+    ASTUnit *TU = getCursorASTUnit(C);
+    SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+    return TU->mapRangeFromPreamble(Range);
+  }
+
+  if (C.kind == CXCursor_InclusionDirective) {
+    ASTUnit *TU = getCursorASTUnit(C);
+    SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
+    return TU->mapRangeFromPreamble(Range);
+  }
+
+  if (C.kind == CXCursor_TranslationUnit) {
+    ASTUnit *TU = getCursorASTUnit(C);
+    FileID MainID = TU->getSourceManager().getMainFileID();
+    SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
+    SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
+    return SourceRange(Start, End);
+  }
+
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return SourceRange();
+
+    SourceRange R = D->getSourceRange();
+    // FIXME: Multiple variables declared in a single declaration
+    // currently lack the information needed to correctly determine their
+    // ranges when accounting for the type-specifier.  We use context
+    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+    // and if so, whether it is the first decl.
+    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (!cxcursor::isFirstInDeclGroup(C))
+        R.setBegin(VD->getLocation());
+    }
+    return R;
+  }
+  return SourceRange();
+}
+
+/// \brief Retrieves the "raw" cursor extent, which is then extended to include
+/// the decl-specifier-seq for declarations.
+static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return SourceRange();
+
+    SourceRange R = D->getSourceRange();
+
+    // Adjust the start of the location for declarations preceded by
+    // declaration specifiers.
+    SourceLocation StartLoc;
+    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
+      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
+        StartLoc = TI->getTypeLoc().getLocStart();
+    } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
+      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
+        StartLoc = TI->getTypeLoc().getLocStart();
+    }
+
+    if (StartLoc.isValid() && R.getBegin().isValid() &&
+        SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
+      R.setBegin(StartLoc);
+
+    // FIXME: Multiple variables declared in a single declaration
+    // currently lack the information needed to correctly determine their
+    // ranges when accounting for the type-specifier.  We use context
+    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+    // and if so, whether it is the first decl.
+    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (!cxcursor::isFirstInDeclGroup(C))
+        R.setBegin(VD->getLocation());
+    }
+
+    return R;    
+  }
+  
+  return getRawCursorExtent(C);
+}
+
+extern "C" {
+
+CXSourceRange clang_getCursorExtent(CXCursor C) {
+  SourceRange R = getRawCursorExtent(C);
+  if (R.isInvalid())
+    return clang_getNullRange();
+
+  return cxloc::translateSourceRange(getCursorContext(C), R);
+}
+
+CXCursor clang_getCursorReferenced(CXCursor C) {
+  if (clang_isInvalid(C.kind))
+    return clang_getNullCursor();
+
+  CXTranslationUnit tu = getCursorTU(C);
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = getCursorDecl(C);
+    if (!D)
+      return clang_getNullCursor();
+    if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+      return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
+    if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
+      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
+        return MakeCXCursor(Property, tu);
+    
+    return C;
+  }
+  
+  if (clang_isExpression(C.kind)) {
+    Expr *E = getCursorExpr(C);
+    Decl *D = getDeclFromExpr(E);
+    if (D) {
+      CXCursor declCursor = MakeCXCursor(D, tu);
+      declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
+                                               declCursor);
+      return declCursor;
+    }
+    
+    if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
+      return MakeCursorOverloadedDeclRef(Ovl, tu);
+        
+    return clang_getNullCursor();
+  }
+
+  if (clang_isStatement(C.kind)) {
+    Stmt *S = getCursorStmt(C);
+    if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
+      if (LabelDecl *label = Goto->getLabel())
+        if (LabelStmt *labelS = label->getStmt())
+        return MakeCXCursor(labelS, getCursorDecl(C), tu);
+
+    return clang_getNullCursor();
+  }
+  
+  if (C.kind == CXCursor_MacroExpansion) {
+    if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition())
+      return MakeMacroDefinitionCursor(Def, tu);
+  }
+
+  if (!clang_isReference(C.kind))
+    return clang_getNullCursor();
+
+  switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef:
+      return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
+
+    case CXCursor_ObjCProtocolRef: {
+      ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
+      if (ObjCProtocolDecl *Def = Prot->getDefinition())
+        return MakeCXCursor(Def, tu);
+
+      return MakeCXCursor(Prot, tu);
+    }
+
+    case CXCursor_ObjCClassRef: {
+      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+      if (ObjCInterfaceDecl *Def = Class->getDefinition())
+        return MakeCXCursor(Def, tu);
+
+      return MakeCXCursor(Class, tu);
+    }
+
+    case CXCursor_TypeRef:
+      return MakeCXCursor(getCursorTypeRef(C).first, tu );
+
+    case CXCursor_TemplateRef:
+      return MakeCXCursor(getCursorTemplateRef(C).first, tu );
+
+    case CXCursor_NamespaceRef:
+      return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
+
+    case CXCursor_MemberRef:
+      return MakeCXCursor(getCursorMemberRef(C).first, tu );
+
+    case CXCursor_CXXBaseSpecifier: {
+      CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+      return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
+                                                         tu ));
+    }
+
+    case CXCursor_LabelRef:
+      // FIXME: We end up faking the "parent" declaration here because we
+      // don't want to make CXCursor larger.
+      return MakeCXCursor(getCursorLabelRef(C).first, 
+               static_cast<ASTUnit*>(tu->TUData)->getASTContext()
+                          .getTranslationUnitDecl(),
+                          tu);
+
+    case CXCursor_OverloadedDeclRef:
+      return C;
+      
+    case CXCursor_VariableRef:
+      return MakeCXCursor(getCursorVariableRef(C).first, tu);
+
+    default:
+      // We would prefer to enumerate all non-reference cursor kinds here.
+      llvm_unreachable("Unhandled reference cursor kind");
+  }
+}
+
+CXCursor clang_getCursorDefinition(CXCursor C) {
+  if (clang_isInvalid(C.kind))
+    return clang_getNullCursor();
+
+  CXTranslationUnit TU = getCursorTU(C);
+
+  bool WasReference = false;
+  if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
+    C = clang_getCursorReferenced(C);
+    WasReference = true;
+  }
+
+  if (C.kind == CXCursor_MacroExpansion)
+    return clang_getCursorReferenced(C);
+
+  if (!clang_isDeclaration(C.kind))
+    return clang_getNullCursor();
+
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return clang_getNullCursor();
+
+  switch (D->getKind()) {
+  // Declaration kinds that don't really separate the notions of
+  // declaration and definition.
+  case Decl::Namespace:
+  case Decl::Typedef:
+  case Decl::TypeAlias:
+  case Decl::TypeAliasTemplate:
+  case Decl::TemplateTypeParm:
+  case Decl::EnumConstant:
+  case Decl::Field:
+  case Decl::IndirectField:
+  case Decl::ObjCIvar:
+  case Decl::ObjCAtDefsField:
+  case Decl::ImplicitParam:
+  case Decl::ParmVar:
+  case Decl::NonTypeTemplateParm:
+  case Decl::TemplateTemplateParm:
+  case Decl::ObjCCategoryImpl:
+  case Decl::ObjCImplementation:
+  case Decl::AccessSpec:
+  case Decl::LinkageSpec:
+  case Decl::ObjCPropertyImpl:
+  case Decl::FileScopeAsm:
+  case Decl::StaticAssert:
+  case Decl::Block:
+  case Decl::Label:  // FIXME: Is this right??
+  case Decl::ClassScopeFunctionSpecialization:
+  case Decl::Import:
+    return C;
+
+  // Declaration kinds that don't make any sense here, but are
+  // nonetheless harmless.
+  case Decl::TranslationUnit:
+    break;
+
+  // Declaration kinds for which the definition is not resolvable.
+  case Decl::UnresolvedUsingTypename:
+  case Decl::UnresolvedUsingValue:
+    break;
+
+  case Decl::UsingDirective:
+    return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
+                        TU);
+
+  case Decl::NamespaceAlias:
+    return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
+
+  case Decl::Enum:
+  case Decl::Record:
+  case Decl::CXXRecord:
+  case Decl::ClassTemplateSpecialization:
+  case Decl::ClassTemplatePartialSpecialization:
+    if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
+      return MakeCXCursor(Def, TU);
+    return clang_getNullCursor();
+
+  case Decl::Function:
+  case Decl::CXXMethod:
+  case Decl::CXXConstructor:
+  case Decl::CXXDestructor:
+  case Decl::CXXConversion: {
+    const FunctionDecl *Def = 0;
+    if (cast<FunctionDecl>(D)->getBody(Def))
+      return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
+    return clang_getNullCursor();
+  }
+
+  case Decl::Var: {
+    // Ask the variable if it has a definition.
+    if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
+      return MakeCXCursor(Def, TU);
+    return clang_getNullCursor();
+  }
+
+  case Decl::FunctionTemplate: {
+    const FunctionDecl *Def = 0;
+    if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
+      return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
+    return clang_getNullCursor();
+  }
+
+  case Decl::ClassTemplate: {
+    if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
+                                                            ->getDefinition())
+      return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
+                          TU);
+    return clang_getNullCursor();
+  }
+
+  case Decl::Using:
+    return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 
+                                       D->getLocation(), TU);
+
+  case Decl::UsingShadow:
+    return clang_getCursorDefinition(
+                       MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
+                                    TU));
+
+  case Decl::ObjCMethod: {
+    ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
+    if (Method->isThisDeclarationADefinition())
+      return C;
+
+    // Dig out the method definition in the associated
+    // @implementation, if we have it.
+    // FIXME: The ASTs should make finding the definition easier.
+    if (ObjCInterfaceDecl *Class
+                       = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
+      if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
+        if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
+                                                  Method->isInstanceMethod()))
+          if (Def->isThisDeclarationADefinition())
+            return MakeCXCursor(Def, TU);
+
+    return clang_getNullCursor();
+  }
+
+  case Decl::ObjCCategory:
+    if (ObjCCategoryImplDecl *Impl
+                               = cast<ObjCCategoryDecl>(D)->getImplementation())
+      return MakeCXCursor(Impl, TU);
+    return clang_getNullCursor();
+
+  case Decl::ObjCProtocol:
+    if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
+      return MakeCXCursor(Def, TU);
+    return clang_getNullCursor();
+
+  case Decl::ObjCInterface: {
+    // There are two notions of a "definition" for an Objective-C
+    // class: the interface and its implementation. When we resolved a
+    // reference to an Objective-C class, produce the @interface as
+    // the definition; when we were provided with the interface,
+    // produce the @implementation as the definition.
+    ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
+    if (WasReference) {
+      if (ObjCInterfaceDecl *Def = IFace->getDefinition())
+        return MakeCXCursor(Def, TU);
+    } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
+      return MakeCXCursor(Impl, TU);
+    return clang_getNullCursor();
+  }
+
+  case Decl::ObjCProperty:
+    // FIXME: We don't really know where to find the
+    // ObjCPropertyImplDecls that implement this property.
+    return clang_getNullCursor();
+
+  case Decl::ObjCCompatibleAlias:
+    if (ObjCInterfaceDecl *Class
+          = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
+      if (ObjCInterfaceDecl *Def = Class->getDefinition())
+        return MakeCXCursor(Def, TU);
+
+    return clang_getNullCursor();
+
+  case Decl::Friend:
+    if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
+      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
+    return clang_getNullCursor();
+
+  case Decl::FriendTemplate:
+    if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
+      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
+    return clang_getNullCursor();
+  }
+
+  return clang_getNullCursor();
+}
+
+unsigned clang_isCursorDefinition(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+
+  return clang_getCursorDefinition(C) == C;
+}
+
+CXCursor clang_getCanonicalCursor(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return C;
+  
+  if (Decl *D = getCursorDecl(C)) {
+    if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
+      if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
+        return MakeCXCursor(CatD, getCursorTU(C));
+
+    if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+      if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+        return MakeCXCursor(IFD, getCursorTU(C));
+
+    return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
+  }
+  
+  return C;
+}
+
+int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
+  return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
+}
+  
+unsigned clang_getNumOverloadedDecls(CXCursor C) {
+  if (C.kind != CXCursor_OverloadedDeclRef)
+    return 0;
+  
+  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
+  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+    return E->getNumDecls();
+  
+  if (OverloadedTemplateStorage *S
+                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
+    return S->size();
+  
+  Decl *D = Storage.get<Decl*>();
+  if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+    return Using->shadow_size();
+  
+  return 0;
+}
+
+CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
+  if (cursor.kind != CXCursor_OverloadedDeclRef)
+    return clang_getNullCursor();
+
+  if (index >= clang_getNumOverloadedDecls(cursor))
+    return clang_getNullCursor();
+  
+  CXTranslationUnit TU = getCursorTU(cursor);
+  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
+  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+    return MakeCXCursor(E->decls_begin()[index], TU);
+  
+  if (OverloadedTemplateStorage *S
+                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
+    return MakeCXCursor(S->begin()[index], TU);
+  
+  Decl *D = Storage.get<Decl*>();
+  if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
+    // FIXME: This is, unfortunately, linear time.
+    UsingDecl::shadow_iterator Pos = Using->shadow_begin();
+    std::advance(Pos, index);
+    return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
+  }
+  
+  return clang_getNullCursor();
+}
+  
+void clang_getDefinitionSpellingAndExtent(CXCursor C,
+                                          const char **startBuf,
+                                          const char **endBuf,
+                                          unsigned *startLine,
+                                          unsigned *startColumn,
+                                          unsigned *endLine,
+                                          unsigned *endColumn) {
+  assert(getCursorDecl(C) && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+  CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
+
+  SourceManager &SM = FD->getASTContext().getSourceManager();
+  *startBuf = SM.getCharacterData(Body->getLBracLoc());
+  *endBuf = SM.getCharacterData(Body->getRBracLoc());
+  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
+  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
+  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
+  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
+}
+
+
+CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
+                                                unsigned PieceIndex) {
+  RefNamePieces Pieces;
+  
+  switch (C.kind) {
+  case CXCursor_MemberRefExpr:
+    if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
+      Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
+                           E->getQualifierLoc().getSourceRange());
+    break;
+  
+  case CXCursor_DeclRefExpr:
+    if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
+      Pieces = buildPieces(NameFlags, false, E->getNameInfo(), 
+                           E->getQualifierLoc().getSourceRange(),
+                           E->getOptionalExplicitTemplateArgs());
+    break;
+    
+  case CXCursor_CallExpr:
+    if (CXXOperatorCallExpr *OCE = 
+        dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
+      Expr *Callee = OCE->getCallee();
+      if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
+        Callee = ICE->getSubExpr();
+
+      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
+        Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
+                             DRE->getQualifierLoc().getSourceRange());
+    }
+    break;
+    
+  default:
+    break;
+  }
+
+  if (Pieces.empty()) {
+    if (PieceIndex == 0)
+      return clang_getCursorExtent(C);
+  } else if (PieceIndex < Pieces.size()) {
+      SourceRange R = Pieces[PieceIndex];
+      if (R.isValid())
+        return cxloc::translateSourceRange(getCursorContext(C), R);
+  }
+  
+  return clang_getNullRange();
+}
+
+void clang_enableStackTraces(void) {
+  llvm::sys::PrintStackTraceOnErrorSignal();
+}
+
+void clang_executeOnThread(void (*fn)(void*), void *user_data,
+                           unsigned stack_size) {
+  llvm::llvm_execute_on_thread(fn, user_data, stack_size);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Token-based Operations.
+//===----------------------------------------------------------------------===//
+
+/* CXToken layout:
+ *   int_data[0]: a CXTokenKind
+ *   int_data[1]: starting token location
+ *   int_data[2]: token length
+ *   int_data[3]: reserved
+ *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
+ *   otherwise unused.
+ */
+extern "C" {
+
+CXTokenKind clang_getTokenKind(CXToken CXTok) {
+  return static_cast<CXTokenKind>(CXTok.int_data[0]);
+}
+
+CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
+  switch (clang_getTokenKind(CXTok)) {
+  case CXToken_Identifier:
+  case CXToken_Keyword:
+    // We know we have an IdentifierInfo*, so use that.
+    return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
+                            ->getNameStart());
+
+  case CXToken_Literal: {
+    // We have stashed the starting pointer in the ptr_data field. Use it.
+    const char *Text = static_cast<const char *>(CXTok.ptr_data);
+    return createCXString(StringRef(Text, CXTok.int_data[2]));
+  }
+
+  case CXToken_Punctuation:
+  case CXToken_Comment:
+    break;
+  }
+
+  // We have to find the starting buffer pointer the hard way, by
+  // deconstructing the source location.
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  if (!CXXUnit)
+    return createCXString("");
+
+  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
+  std::pair<FileID, unsigned> LocInfo
+    = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
+  bool Invalid = false;
+  StringRef Buffer
+    = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+    return createCXString("");
+
+  return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
+}
+
+CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  if (!CXXUnit)
+    return clang_getNullLocation();
+
+  return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
+                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
+}
+
+CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  if (!CXXUnit)
+    return clang_getNullRange();
+
+  return cxloc::translateSourceRange(CXXUnit->getASTContext(),
+                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
+}
+
+static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
+                      SmallVectorImpl<CXToken> &CXTokens) {
+  SourceManager &SourceMgr = CXXUnit->getSourceManager();
+  std::pair<FileID, unsigned> BeginLocInfo
+    = SourceMgr.getDecomposedLoc(Range.getBegin());
+  std::pair<FileID, unsigned> EndLocInfo
+    = SourceMgr.getDecomposedLoc(Range.getEnd());
+
+  // Cannot tokenize across files.
+  if (BeginLocInfo.first != EndLocInfo.first)
+    return;
+
+  // Create a lexer
+  bool Invalid = false;
+  StringRef Buffer
+    = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
+  if (Invalid)
+    return;
+  
+  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
+            CXXUnit->getASTContext().getLangOpts(),
+            Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
+  Lex.SetCommentRetentionState(true);
+
+  // Lex tokens until we hit the end of the range.
+  const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
+  Token Tok;
+  bool previousWasAt = false;
+  do {
+    // Lex the next token
+    Lex.LexFromRawLexer(Tok);
+    if (Tok.is(tok::eof))
+      break;
+
+    // Initialize the CXToken.
+    CXToken CXTok;
+
+    //   - Common fields
+    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
+    CXTok.int_data[2] = Tok.getLength();
+    CXTok.int_data[3] = 0;
+
+    //   - Kind-specific fields
+    if (Tok.isLiteral()) {
+      CXTok.int_data[0] = CXToken_Literal;
+      CXTok.ptr_data = (void *)Tok.getLiteralData();
+    } else if (Tok.is(tok::raw_identifier)) {
+      // Lookup the identifier to determine whether we have a keyword.
+      IdentifierInfo *II
+        = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
+
+      if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
+        CXTok.int_data[0] = CXToken_Keyword;
+      }
+      else {
+        CXTok.int_data[0] = Tok.is(tok::identifier)
+          ? CXToken_Identifier
+          : CXToken_Keyword;
+      }
+      CXTok.ptr_data = II;
+    } else if (Tok.is(tok::comment)) {
+      CXTok.int_data[0] = CXToken_Comment;
+      CXTok.ptr_data = 0;
+    } else {
+      CXTok.int_data[0] = CXToken_Punctuation;
+      CXTok.ptr_data = 0;
+    }
+    CXTokens.push_back(CXTok);
+    previousWasAt = Tok.is(tok::at);
+  } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
+}
+
+void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+                    CXToken **Tokens, unsigned *NumTokens) {
+  if (Tokens)
+    *Tokens = 0;
+  if (NumTokens)
+    *NumTokens = 0;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  if (!CXXUnit || !Tokens || !NumTokens)
+    return;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  
+  SourceRange R = cxloc::translateCXSourceRange(Range);
+  if (R.isInvalid())
+    return;
+
+  SmallVector<CXToken, 32> CXTokens;
+  getTokens(CXXUnit, R, CXTokens);
+
+  if (CXTokens.empty())
+    return;
+
+  *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
+  memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
+  *NumTokens = CXTokens.size();
+}
+
+void clang_disposeTokens(CXTranslationUnit TU,
+                         CXToken *Tokens, unsigned NumTokens) {
+  free(Tokens);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Token annotation APIs.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
+static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
+                                                     CXCursor parent,
+                                                     CXClientData client_data);
+static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
+                                              CXClientData client_data);
+
+namespace {
+class AnnotateTokensWorker {
+  AnnotateTokensData &Annotated;
+  CXToken *Tokens;
+  CXCursor *Cursors;
+  unsigned NumTokens;
+  unsigned TokIdx;
+  unsigned PreprocessingTokIdx;
+  CursorVisitor AnnotateVis;
+  SourceManager &SrcMgr;
+  bool HasContextSensitiveKeywords;
+
+  struct PostChildrenInfo {
+    CXCursor Cursor;
+    SourceRange CursorRange;
+    unsigned BeforeChildrenTokenIdx;
+  };
+  llvm::SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
+  
+  bool MoreTokens() const { return TokIdx < NumTokens; }
+  unsigned NextToken() const { return TokIdx; }
+  void AdvanceToken() { ++TokIdx; }
+  SourceLocation GetTokenLoc(unsigned tokI) {
+    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+  }
+  bool isFunctionMacroToken(unsigned tokI) const {
+    return Tokens[tokI].int_data[3] != 0;
+  }
+  SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
+    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
+  }
+
+  void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
+  void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
+                                             SourceRange);
+
+public:
+  AnnotateTokensWorker(AnnotateTokensData &annotated,
+                       CXToken *tokens, CXCursor *cursors, unsigned numTokens,
+                       CXTranslationUnit tu, SourceRange RegionOfInterest)
+    : Annotated(annotated), Tokens(tokens), Cursors(cursors),
+      NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
+      AnnotateVis(tu,
+                  AnnotateTokensVisitor, this,
+                  /*VisitPreprocessorLast=*/true,
+                  /*VisitIncludedEntities=*/false,
+                  RegionOfInterest,
+                  /*VisitDeclsOnly=*/false,
+                  AnnotateTokensPostChildrenVisitor),
+      SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
+      HasContextSensitiveKeywords(false) { }
+
+  void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
+  enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
+  bool postVisitChildren(CXCursor cursor);
+  void AnnotateTokens();
+  
+  /// \brief Determine whether the annotator saw any cursors that have 
+  /// context-sensitive keywords.
+  bool hasContextSensitiveKeywords() const {
+    return HasContextSensitiveKeywords;
+  }
+
+  ~AnnotateTokensWorker() {
+    assert(PostChildrenInfos.empty());
+  }
+};
+}
+
+void AnnotateTokensWorker::AnnotateTokens() {
+  // Walk the AST within the region of interest, annotating tokens
+  // along the way.
+  AnnotateVis.visitFileRegion();
+
+  for (unsigned I = 0 ; I < TokIdx ; ++I) {
+    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
+    if (Pos != Annotated.end() && !clang_isPreprocessing(Cursors[I].kind))
+      Cursors[I] = Pos->second;
+  }
+
+  // Finish up annotating any tokens left.
+  if (!MoreTokens())
+    return;
+
+  const CXCursor &C = clang_getNullCursor();
+  for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
+    if (I < PreprocessingTokIdx && clang_isPreprocessing(Cursors[I].kind))
+      continue;
+
+    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
+    Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
+  }
+}
+
+/// \brief It annotates and advances tokens with a cursor until the comparison
+//// between the cursor location and the source range is the same as
+/// \arg compResult.
+///
+/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
+/// Pass RangeOverlap to annotate tokens inside a range.
+void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
+                                               RangeComparisonResult compResult,
+                                               SourceRange range) {
+  while (MoreTokens()) {
+    const unsigned I = NextToken();
+    if (isFunctionMacroToken(I))
+      return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
+
+    SourceLocation TokLoc = GetTokenLoc(I);
+    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
+      Cursors[I] = updateC;
+      AdvanceToken();
+      continue;
+    }
+    break;
+  }
+}
+
+/// \brief Special annotation handling for macro argument tokens.
+void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
+                                               CXCursor updateC,
+                                               RangeComparisonResult compResult,
+                                               SourceRange range) {
+  assert(MoreTokens());
+  assert(isFunctionMacroToken(NextToken()) &&
+         "Should be called only for macro arg tokens");
+
+  // This works differently than annotateAndAdvanceTokens; because expanded
+  // macro arguments can have arbitrary translation-unit source order, we do not
+  // advance the token index one by one until a token fails the range test.
+  // We only advance once past all of the macro arg tokens if all of them
+  // pass the range test. If one of them fails we keep the token index pointing
+  // at the start of the macro arg tokens so that the failing token will be
+  // annotated by a subsequent annotation try.
+
+  bool atLeastOneCompFail = false;
+  
+  unsigned I = NextToken();
+  for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
+    SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
+    if (TokLoc.isFileID())
+      continue; // not macro arg token, it's parens or comma.
+    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
+      if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
+        Cursors[I] = updateC;
+    } else
+      atLeastOneCompFail = true;
+  }
+
+  if (!atLeastOneCompFail)
+    TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+}
+
+enum CXChildVisitResult
+AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {  
+  CXSourceLocation Loc = clang_getCursorLocation(cursor);
+  SourceRange cursorRange = getRawCursorExtent(cursor);
+  if (cursorRange.isInvalid())
+    return CXChildVisit_Recurse;
+      
+  if (!HasContextSensitiveKeywords) {
+    // Objective-C properties can have context-sensitive keywords.
+    if (cursor.kind == CXCursor_ObjCPropertyDecl) {
+      if (ObjCPropertyDecl *Property 
+                  = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
+        HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
+    }
+    // Objective-C methods can have context-sensitive keywords.
+    else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
+             cursor.kind == CXCursor_ObjCClassMethodDecl) {
+      if (ObjCMethodDecl *Method
+            = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
+        if (Method->getObjCDeclQualifier())
+          HasContextSensitiveKeywords = true;
+        else {
+          for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
+                                           PEnd = Method->param_end();
+               P != PEnd; ++P) {
+            if ((*P)->getObjCDeclQualifier()) {
+              HasContextSensitiveKeywords = true;
+              break;
+            }
+          }
+        }
+      }
+    }    
+    // C++ methods can have context-sensitive keywords.
+    else if (cursor.kind == CXCursor_CXXMethod) {
+      if (CXXMethodDecl *Method
+                  = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
+        if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
+          HasContextSensitiveKeywords = true;
+      }
+    }
+    // C++ classes can have context-sensitive keywords.
+    else if (cursor.kind == CXCursor_StructDecl ||
+             cursor.kind == CXCursor_ClassDecl ||
+             cursor.kind == CXCursor_ClassTemplate ||
+             cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
+      if (Decl *D = getCursorDecl(cursor))
+        if (D->hasAttr<FinalAttr>())
+          HasContextSensitiveKeywords = true;
+    }
+  }
+  
+  if (clang_isPreprocessing(cursor.kind)) {    
+    // Items in the preprocessing record are kept separate from items in
+    // declarations, so we keep a separate token index.
+    unsigned SavedTokIdx = TokIdx;
+    TokIdx = PreprocessingTokIdx;
+
+    // Skip tokens up until we catch up to the beginning of the preprocessing
+    // entry.
+    while (MoreTokens()) {
+      const unsigned I = NextToken();
+      SourceLocation TokLoc = GetTokenLoc(I);
+      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
+      case RangeBefore:
+        AdvanceToken();
+        continue;
+      case RangeAfter:
+      case RangeOverlap:
+        break;
+      }
+      break;
+    }
+    
+    // Look at all of the tokens within this range.
+    while (MoreTokens()) {
+      const unsigned I = NextToken();
+      SourceLocation TokLoc = GetTokenLoc(I);
+      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
+      case RangeBefore:
+        llvm_unreachable("Infeasible");
+      case RangeAfter:
+        break;
+      case RangeOverlap:
+        Cursors[I] = cursor;
+        AdvanceToken();
+        // For macro expansions, just note where the beginning of the macro
+        // expansion occurs.
+        if (cursor.kind == CXCursor_MacroExpansion)
+          break;
+        continue;
+      }
+      break;
+    }
+
+    // Save the preprocessing token index; restore the non-preprocessing
+    // token index.
+    PreprocessingTokIdx = TokIdx;
+    TokIdx = SavedTokIdx;
+    return CXChildVisit_Recurse;
+  }
+
+  if (cursorRange.isInvalid())
+    return CXChildVisit_Continue;
+  
+  SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
+
+  // Adjust the annotated range based specific declarations.
+  const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
+  if (clang_isDeclaration(cursorK)) {
+    Decl *D = cxcursor::getCursorDecl(cursor);
+    
+    SourceLocation StartLoc;
+    if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(D)) {
+      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
+        StartLoc = TI->getTypeLoc().getLocStart();
+    } else if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(D)) {
+      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
+        StartLoc = TI->getTypeLoc().getLocStart();
+    }
+
+    if (StartLoc.isValid() && L.isValid() &&
+        SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
+      cursorRange.setBegin(StartLoc);
+  }
+  
+  // If the location of the cursor occurs within a macro instantiation, record
+  // the spelling location of the cursor in our annotation map.  We can then
+  // paper over the token labelings during a post-processing step to try and
+  // get cursor mappings for tokens that are the *arguments* of a macro
+  // instantiation.
+  if (L.isMacroID()) {
+    unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
+    // Only invalidate the old annotation if it isn't part of a preprocessing
+    // directive.  Here we assume that the default construction of CXCursor
+    // results in CXCursor.kind being an initialized value (i.e., 0).  If
+    // this isn't the case, we can fix by doing lookup + insertion.
+    
+    CXCursor &oldC = Annotated[rawEncoding];
+    if (!clang_isPreprocessing(oldC.kind))
+      oldC = cursor;
+  }
+  
+  const enum CXCursorKind K = clang_getCursorKind(parent);
+  const CXCursor updateC =
+    (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
+     ? clang_getNullCursor() : parent;
+
+  annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
+
+  // Avoid having the cursor of an expression "overwrite" the annotation of the
+  // variable declaration that it belongs to.
+  // This can happen for C++ constructor expressions whose range generally
+  // include the variable declaration, e.g.:
+  //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
+  if (clang_isExpression(cursorK)) {
+    Expr *E = getCursorExpr(cursor);
+    if (Decl *D = getCursorParentDecl(cursor)) {
+      const unsigned I = NextToken();
+      if (E->getLocStart().isValid() && D->getLocation().isValid() &&
+          E->getLocStart() == D->getLocation() &&
+          E->getLocStart() == GetTokenLoc(I)) {
+        Cursors[I] = updateC;
+        AdvanceToken();
+      }
+    }
+  }
+
+  // Before recursing into the children keep some state that we are going
+  // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
+  // extra work after the child nodes are visited.
+  // Note that we don't call VisitChildren here to avoid traversing statements
+  // code-recursively which can blow the stack.
+
+  PostChildrenInfo Info;
+  Info.Cursor = cursor;
+  Info.CursorRange = cursorRange;
+  Info.BeforeChildrenTokenIdx = NextToken();
+  PostChildrenInfos.push_back(Info);
+
+  return CXChildVisit_Recurse;
+}
+
+bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
+  if (PostChildrenInfos.empty())
+    return false;
+  const PostChildrenInfo &Info = PostChildrenInfos.back();
+  if (!clang_equalCursors(Info.Cursor, cursor))
+    return false;
+
+  const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
+  const unsigned AfterChildren = NextToken();
+  SourceRange cursorRange = Info.CursorRange;
+
+  // Scan the tokens that are at the end of the cursor, but are not captured
+  // but the child cursors.
+  annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
+
+  // Scan the tokens that are at the beginning of the cursor, but are not
+  // capture by the child cursors.
+  for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
+    if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
+      break;
+
+    Cursors[I] = cursor;
+  }
+
+  PostChildrenInfos.pop_back();
+  return false;
+}
+
+static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
+                                                     CXCursor parent,
+                                                     CXClientData client_data) {
+  return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
+}
+
+static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
+                                              CXClientData client_data) {
+  return static_cast<AnnotateTokensWorker*>(client_data)->
+                                                      postVisitChildren(cursor);
+}
+
+namespace {
+
+/// \brief Uses the macro expansions in the preprocessing record to find
+/// and mark tokens that are macro arguments. This info is used by the
+/// AnnotateTokensWorker.
+class MarkMacroArgTokensVisitor {
+  SourceManager &SM;
+  CXToken *Tokens;
+  unsigned NumTokens;
+  unsigned CurIdx;
+  
+public:
+  MarkMacroArgTokensVisitor(SourceManager &SM,
+                            CXToken *tokens, unsigned numTokens)
+    : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
+
+  CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
+    if (cursor.kind != CXCursor_MacroExpansion)
+      return CXChildVisit_Continue;
+
+    SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
+    if (macroRange.getBegin() == macroRange.getEnd())
+      return CXChildVisit_Continue; // it's not a function macro.
+
+    for (; CurIdx < NumTokens; ++CurIdx) {
+      if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
+                                        macroRange.getBegin()))
+        break;
+    }
+    
+    if (CurIdx == NumTokens)
+      return CXChildVisit_Break;
+
+    for (; CurIdx < NumTokens; ++CurIdx) {
+      SourceLocation tokLoc = getTokenLoc(CurIdx);
+      if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
+        break;
+
+      setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
+    }
+
+    if (CurIdx == NumTokens)
+      return CXChildVisit_Break;
+
+    return CXChildVisit_Continue;
+  }
+
+private:
+  SourceLocation getTokenLoc(unsigned tokI) {
+    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+  }
+
+  void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
+    // The third field is reserved and currently not used. Use it here
+    // to mark macro arg expanded tokens with their expanded locations.
+    Tokens[tokI].int_data[3] = loc.getRawEncoding();
+  }
+};
+
+} // end anonymous namespace
+
+static CXChildVisitResult
+MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
+                                  CXClientData client_data) {
+  return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
+                                                                     parent);
+}
+
+namespace {
+  struct clang_annotateTokens_Data {
+    CXTranslationUnit TU;
+    ASTUnit *CXXUnit;
+    CXToken *Tokens;
+    unsigned NumTokens;
+    CXCursor *Cursors;
+  };
+}
+
+static void annotatePreprocessorTokens(CXTranslationUnit TU,
+                                       SourceRange RegionOfInterest,
+                                       AnnotateTokensData &Annotated) {
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+
+  SourceManager &SourceMgr = CXXUnit->getSourceManager();
+  std::pair<FileID, unsigned> BeginLocInfo
+    = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
+  std::pair<FileID, unsigned> EndLocInfo
+    = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+
+  if (BeginLocInfo.first != EndLocInfo.first)
+    return;
+
+  StringRef Buffer;
+  bool Invalid = false;
+  Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
+  if (Buffer.empty() || Invalid)
+    return;
+
+  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
+            CXXUnit->getASTContext().getLangOpts(),
+            Buffer.begin(), Buffer.data() + BeginLocInfo.second,
+            Buffer.end());
+  Lex.SetCommentRetentionState(true);
+  
+  // Lex tokens in raw mode until we hit the end of the range, to avoid
+  // entering #includes or expanding macros.
+  while (true) {
+    Token Tok;
+    Lex.LexFromRawLexer(Tok);
+    
+  reprocess:
+    if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
+      // We have found a preprocessing directive. Gobble it up so that we
+      // don't see it while preprocessing these tokens later, but keep track
+      // of all of the token locations inside this preprocessing directive so
+      // that we can annotate them appropriately.
+      //
+      // FIXME: Some simple tests here could identify macro definitions and
+      // #undefs, to provide specific cursor kinds for those.
+      SmallVector<SourceLocation, 32> Locations;
+      do {
+        Locations.push_back(Tok.getLocation());
+        Lex.LexFromRawLexer(Tok);
+      } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
+      
+      using namespace cxcursor;
+      CXCursor Cursor
+      = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
+                                                     Locations.back()),
+                                         TU);
+      for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
+        Annotated[Locations[I].getRawEncoding()] = Cursor;
+      }
+      
+      if (Tok.isAtStartOfLine())
+        goto reprocess;
+      
+      continue;
+    }
+    
+    if (Tok.is(tok::eof))
+      break;
+  }
+}
+
+// This gets run a separate thread to avoid stack blowout.
+static void clang_annotateTokensImpl(void *UserData) {
+  CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
+  ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
+  CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
+  const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
+  CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
+
+  CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
+    setThreadBackgroundPriority();
+
+  // Determine the region of interest, which contains all of the tokens.
+  SourceRange RegionOfInterest;
+  RegionOfInterest.setBegin(
+    cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
+  RegionOfInterest.setEnd(
+    cxloc::translateSourceLocation(clang_getTokenLocation(TU,
+                                                         Tokens[NumTokens-1])));
+
+  // A mapping from the source locations found when re-lexing or traversing the
+  // region of interest to the corresponding cursors.
+  AnnotateTokensData Annotated;
+
+  // Relex the tokens within the source range to look for preprocessing
+  // directives.
+  annotatePreprocessorTokens(TU, RegionOfInterest, Annotated);
+  
+  if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
+    // Search and mark tokens that are macro argument expansions.
+    MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
+                                      Tokens, NumTokens);
+    CursorVisitor MacroArgMarker(TU,
+                                 MarkMacroArgTokensVisitorDelegate, &Visitor,
+                                 /*VisitPreprocessorLast=*/true,
+                                 /*VisitIncludedEntities=*/false,
+                                 RegionOfInterest);
+    MacroArgMarker.visitPreprocessedEntitiesInRegion();
+  }
+  
+  // Annotate all of the source locations in the region of interest that map to
+  // a specific cursor.
+  AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
+                         TU, RegionOfInterest);
+  
+  // FIXME: We use a ridiculous stack size here because the data-recursion
+  // algorithm uses a large stack frame than the non-data recursive version,
+  // and AnnotationTokensWorker currently transforms the data-recursion
+  // algorithm back into a traditional recursion by explicitly calling
+  // VisitChildren().  We will need to remove this explicit recursive call.
+  W.AnnotateTokens();
+
+  // If we ran into any entities that involve context-sensitive keywords,
+  // take another pass through the tokens to mark them as such.
+  if (W.hasContextSensitiveKeywords()) {
+    for (unsigned I = 0; I != NumTokens; ++I) {
+      if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
+        continue;
+      
+      if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
+        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
+        if (ObjCPropertyDecl *Property
+            = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
+          if (Property->getPropertyAttributesAsWritten() != 0 &&
+              llvm::StringSwitch<bool>(II->getName())
+              .Case("readonly", true)
+              .Case("assign", true)
+              .Case("unsafe_unretained", true)
+              .Case("readwrite", true)
+              .Case("retain", true)
+              .Case("copy", true)
+              .Case("nonatomic", true)
+              .Case("atomic", true)
+              .Case("getter", true)
+              .Case("setter", true)
+              .Case("strong", true)
+              .Case("weak", true)
+              .Default(false))
+            Tokens[I].int_data[0] = CXToken_Keyword;
+        }
+        continue;
+      }
+      
+      if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
+          Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
+        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
+        if (llvm::StringSwitch<bool>(II->getName())
+            .Case("in", true)
+            .Case("out", true)
+            .Case("inout", true)
+            .Case("oneway", true)
+            .Case("bycopy", true)
+            .Case("byref", true)
+            .Default(false))
+          Tokens[I].int_data[0] = CXToken_Keyword;
+        continue;
+      }
+
+      if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
+          Cursors[I].kind == CXCursor_CXXOverrideAttr) {
+        Tokens[I].int_data[0] = CXToken_Keyword;
+        continue;
+      }
+    }
+  }
+}
+
+extern "C" {
+
+void clang_annotateTokens(CXTranslationUnit TU,
+                          CXToken *Tokens, unsigned NumTokens,
+                          CXCursor *Cursors) {
+
+  if (NumTokens == 0 || !Tokens || !Cursors)
+    return;
+
+  // Any token we don't specifically annotate will have a NULL cursor.
+  CXCursor C = clang_getNullCursor();
+  for (unsigned I = 0; I != NumTokens; ++I)
+    Cursors[I] = C;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  if (!CXXUnit)
+    return;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  
+  clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
+  llvm::CrashRecoveryContext CRC;
+  if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
+                 GetSafetyThreadStackSize() * 2)) {
+    fprintf(stderr, "libclang: crash detected while annotating tokens\n");
+  }
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Operations for querying linkage of a cursor.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
+  if (!clang_isDeclaration(cursor.kind))
+    return CXLinkage_Invalid;
+
+  Decl *D = cxcursor::getCursorDecl(cursor);
+  if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
+    switch (ND->getLinkage()) {
+      case NoLinkage: return CXLinkage_NoLinkage;
+      case InternalLinkage: return CXLinkage_Internal;
+      case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
+      case ExternalLinkage: return CXLinkage_External;
+    };
+
+  return CXLinkage_Invalid;
+}
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Operations for querying language of a cursor.
+//===----------------------------------------------------------------------===//
+
+static CXLanguageKind getDeclLanguage(const Decl *D) {
+  if (!D)
+    return CXLanguage_C;
+
+  switch (D->getKind()) {
+    default:
+      break;
+    case Decl::ImplicitParam:
+    case Decl::ObjCAtDefsField:
+    case Decl::ObjCCategory:
+    case Decl::ObjCCategoryImpl:
+    case Decl::ObjCCompatibleAlias:
+    case Decl::ObjCImplementation:
+    case Decl::ObjCInterface:
+    case Decl::ObjCIvar:
+    case Decl::ObjCMethod:
+    case Decl::ObjCProperty:
+    case Decl::ObjCPropertyImpl:
+    case Decl::ObjCProtocol:
+      return CXLanguage_ObjC;
+    case Decl::CXXConstructor:
+    case Decl::CXXConversion:
+    case Decl::CXXDestructor:
+    case Decl::CXXMethod:
+    case Decl::CXXRecord:
+    case Decl::ClassTemplate:
+    case Decl::ClassTemplatePartialSpecialization:
+    case Decl::ClassTemplateSpecialization:
+    case Decl::Friend:
+    case Decl::FriendTemplate:
+    case Decl::FunctionTemplate:
+    case Decl::LinkageSpec:
+    case Decl::Namespace:
+    case Decl::NamespaceAlias:
+    case Decl::NonTypeTemplateParm:
+    case Decl::StaticAssert:
+    case Decl::TemplateTemplateParm:
+    case Decl::TemplateTypeParm:
+    case Decl::UnresolvedUsingTypename:
+    case Decl::UnresolvedUsingValue:
+    case Decl::Using:
+    case Decl::UsingDirective:
+    case Decl::UsingShadow:
+      return CXLanguage_CPlusPlus;
+  }
+
+  return CXLanguage_C;
+}
+
+extern "C" {
+  
+enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    if (Decl *D = cxcursor::getCursorDecl(cursor)) {
+      if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
+        return CXAvailability_Available;
+      
+      switch (D->getAvailability()) {
+      case AR_Available:
+      case AR_NotYetIntroduced:
+        return CXAvailability_Available;
+
+      case AR_Deprecated:
+        return CXAvailability_Deprecated;
+
+      case AR_Unavailable:
+        return CXAvailability_NotAvailable;
+      }
+    }
+
+  return CXAvailability_Available;
+}
+
+static CXVersion convertVersion(VersionTuple In) {
+  CXVersion Out = { -1, -1, -1 };
+  if (In.empty())
+    return Out;
+
+  Out.Major = In.getMajor();
+  
+  if (llvm::Optional<unsigned> Minor = In.getMinor())
+    Out.Minor = *Minor;
+  else
+    return Out;
+
+  if (llvm::Optional<unsigned> Subminor = In.getSubminor())
+    Out.Subminor = *Subminor;
+  
+  return Out;
+}
+  
+int clang_getCursorPlatformAvailability(CXCursor cursor,
+                                        int *always_deprecated,
+                                        CXString *deprecated_message,
+                                        int *always_unavailable,
+                                        CXString *unavailable_message,
+                                        CXPlatformAvailability *availability,
+                                        int availability_size) {
+  if (always_deprecated)
+    *always_deprecated = 0;
+  if (deprecated_message)
+    *deprecated_message = cxstring::createCXString("", /*DupString=*/false);
+  if (always_unavailable)
+    *always_unavailable = 0;
+  if (unavailable_message)
+    *unavailable_message = cxstring::createCXString("", /*DupString=*/false);
+  
+  if (!clang_isDeclaration(cursor.kind))
+    return 0;
+  
+  Decl *D = cxcursor::getCursorDecl(cursor);
+  if (!D)
+    return 0;
+  
+  int N = 0;
+  for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
+       ++A) {
+    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+      if (always_deprecated)
+        *always_deprecated = 1;
+      if (deprecated_message)
+        *deprecated_message = cxstring::createCXString(Deprecated->getMessage());
+      continue;
+    }
+    
+    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+      if (always_unavailable)
+        *always_unavailable = 1;
+      if (unavailable_message) {
+        *unavailable_message
+          = cxstring::createCXString(Unavailable->getMessage());
+      }
+      continue;
+    }
+    
+    if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
+      if (N < availability_size) {
+        availability[N].Platform
+          = cxstring::createCXString(Avail->getPlatform()->getName());
+        availability[N].Introduced = convertVersion(Avail->getIntroduced());
+        availability[N].Deprecated = convertVersion(Avail->getDeprecated());
+        availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
+        availability[N].Unavailable = Avail->getUnavailable();
+        availability[N].Message = cxstring::createCXString(Avail->getMessage());
+      }
+      ++N;
+    }
+  }
+  
+  return N;
+}
+  
+void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
+  clang_disposeString(availability->Platform);
+  clang_disposeString(availability->Message);
+}
+
+CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    return getDeclLanguage(cxcursor::getCursorDecl(cursor));
+
+  return CXLanguage_Invalid;
+}
+
+ /// \brief If the given cursor is the "templated" declaration
+ /// descibing a class or function template, return the class or
+ /// function template.
+static Decl *maybeGetTemplateCursor(Decl *D) {
+  if (!D)
+    return 0;
+
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
+      return FunTmpl;
+
+  if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+    if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
+      return ClassTmpl;
+
+  return D;
+}
+
+CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind)) {
+    if (Decl *D = getCursorDecl(cursor)) {
+      DeclContext *DC = D->getDeclContext();
+      if (!DC)
+        return clang_getNullCursor();
+
+      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 
+                          getCursorTU(cursor));
+    }
+  }
+  
+  if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
+    if (Decl *D = getCursorDecl(cursor))
+      return MakeCXCursor(D, getCursorTU(cursor));
+  }
+  
+  return clang_getNullCursor();
+}
+
+CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind)) {
+    if (Decl *D = getCursorDecl(cursor)) {
+      DeclContext *DC = D->getLexicalDeclContext();
+      if (!DC)
+        return clang_getNullCursor();
+
+      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 
+                          getCursorTU(cursor));
+    }
+  }
+
+  // FIXME: Note that we can't easily compute the lexical context of a 
+  // statement or expression, so we return nothing.
+  return clang_getNullCursor();
+}
+
+CXFile clang_getIncludedFile(CXCursor cursor) {
+  if (cursor.kind != CXCursor_InclusionDirective)
+    return 0;
+  
+  InclusionDirective *ID = getCursorInclusionDirective(cursor);
+  return (void *)ID->getFile();
+}
+
+CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return clang_getNullRange();
+
+  const Decl *D = getCursorDecl(C);
+  ASTContext &Context = getCursorContext(C);
+  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
+  if (!RC)
+    return clang_getNullRange();
+
+  return cxloc::translateSourceRange(Context, RC->getSourceRange());
+}
+
+CXString clang_Cursor_getRawCommentText(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return createCXString((const char *) NULL);
+
+  const Decl *D = getCursorDecl(C);
+  ASTContext &Context = getCursorContext(C);
+  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
+  StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
+                           StringRef();
+
+  // Don't duplicate the string because RawText points directly into source
+  // code.
+  return createCXString(RawText, false);
+}
+
+CXString clang_Cursor_getBriefCommentText(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return createCXString((const char *) NULL);
+
+  const Decl *D = getCursorDecl(C);
+  const ASTContext &Context = getCursorContext(C);
+  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
+
+  if (RC) {
+    StringRef BriefText = RC->getBriefText(Context);
+
+    // Don't duplicate the string because RawComment ensures that this memory
+    // will not go away.
+    return createCXString(BriefText, false);
+  }
+
+  return createCXString((const char *) NULL);
+}
+
+CXComment clang_Cursor_getParsedComment(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return cxcomment::createCXComment(NULL, NULL);
+
+  const Decl *D = getCursorDecl(C);
+  const ASTContext &Context = getCursorContext(C);
+  const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
+
+  return cxcomment::createCXComment(FC, getCursorTU(C));
+}
+
+CXModule clang_Cursor_getModule(CXCursor C) {
+  if (C.kind == CXCursor_ModuleImportDecl) {
+    if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
+      return ImportD->getImportedModule();
+  }
+
+  return 0;
+}
+
+CXModule clang_Module_getParent(CXModule CXMod) {
+  if (!CXMod)
+    return 0;
+  Module *Mod = static_cast<Module*>(CXMod);
+  return Mod->Parent;
+}
+
+CXString clang_Module_getName(CXModule CXMod) {
+  if (!CXMod)
+    return createCXString("");
+  Module *Mod = static_cast<Module*>(CXMod);
+  return createCXString(Mod->Name);
+}
+
+CXString clang_Module_getFullName(CXModule CXMod) {
+  if (!CXMod)
+    return createCXString("");
+  Module *Mod = static_cast<Module*>(CXMod);
+  return createCXString(Mod->getFullModuleName());
+}
+
+unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
+  if (!CXMod)
+    return 0;
+  Module *Mod = static_cast<Module*>(CXMod);
+  return Mod->TopHeaders.size();
+}
+
+CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
+  if (!CXMod)
+    return 0;
+  Module *Mod = static_cast<Module*>(CXMod);
+
+  if (Index < Mod->TopHeaders.size())
+    return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
+
+  return 0;
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// C++ AST instrospection.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+unsigned clang_CXXMethod_isStatic(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+  
+  CXXMethodDecl *Method = 0;
+  Decl *D = cxcursor::getCursorDecl(C);
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
+    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+  else
+    Method = dyn_cast_or_null<CXXMethodDecl>(D);
+  return (Method && Method->isStatic()) ? 1 : 0;
+}
+
+unsigned clang_CXXMethod_isVirtual(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+  
+  CXXMethodDecl *Method = 0;
+  Decl *D = cxcursor::getCursorDecl(C);
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
+    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+  else
+    Method = dyn_cast_or_null<CXXMethodDecl>(D);
+  return (Method && Method->isVirtual()) ? 1 : 0;
+}
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Attribute introspection.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXType clang_getIBOutletCollectionType(CXCursor C) {
+  if (C.kind != CXCursor_IBOutletCollectionAttr)
+    return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
+  
+  IBOutletCollectionAttr *A =
+    cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
+  
+  return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));  
+}
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Inspecting memory usage.
+//===----------------------------------------------------------------------===//
+
+typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
+
+static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
+                                              enum CXTUResourceUsageKind k,
+                                              unsigned long amount) {
+  CXTUResourceUsageEntry entry = { k, amount };
+  entries.push_back(entry);
+}
+
+extern "C" {
+
+const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
+  const char *str = "";
+  switch (kind) {
+    case CXTUResourceUsage_AST:
+      str = "ASTContext: expressions, declarations, and types"; 
+      break;
+    case CXTUResourceUsage_Identifiers:
+      str = "ASTContext: identifiers";
+      break;
+    case CXTUResourceUsage_Selectors:
+      str = "ASTContext: selectors";
+      break;
+    case CXTUResourceUsage_GlobalCompletionResults:
+      str = "Code completion: cached global results";
+      break;
+    case CXTUResourceUsage_SourceManagerContentCache:
+      str = "SourceManager: content cache allocator";
+      break;
+    case CXTUResourceUsage_AST_SideTables:
+      str = "ASTContext: side tables";
+      break;
+    case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
+      str = "SourceManager: malloc'ed memory buffers";
+      break;
+    case CXTUResourceUsage_SourceManager_Membuffer_MMap:
+      str = "SourceManager: mmap'ed memory buffers";
+      break;
+    case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
+      str = "ExternalASTSource: malloc'ed memory buffers";
+      break;
+    case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
+      str = "ExternalASTSource: mmap'ed memory buffers";
+      break;
+    case CXTUResourceUsage_Preprocessor:
+      str = "Preprocessor: malloc'ed memory";
+      break;
+    case CXTUResourceUsage_PreprocessingRecord:
+      str = "Preprocessor: PreprocessingRecord";
+      break;
+    case CXTUResourceUsage_SourceManager_DataStructures:
+      str = "SourceManager: data structures and tables";
+      break;
+    case CXTUResourceUsage_Preprocessor_HeaderSearch:
+      str = "Preprocessor: header search tables";
+      break;
+  }
+  return str;
+}
+
+CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
+  if (!TU) {
+    CXTUResourceUsage usage = { (void*) 0, 0, 0 };
+    return usage;
+  }
+  
+  ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
+  OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
+  ASTContext &astContext = astUnit->getASTContext();
+  
+  // How much memory is used by AST nodes and types?
+  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
+    (unsigned long) astContext.getASTAllocatedMemory());
+
+  // How much memory is used by identifiers?
+  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
+    (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
+
+  // How much memory is used for selectors?
+  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
+    (unsigned long) astContext.Selectors.getTotalMemory());
+  
+  // How much memory is used by ASTContext's side tables?
+  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
+    (unsigned long) astContext.getSideTableAllocatedMemory());
+  
+  // How much memory is used for caching global code completion results?
+  unsigned long completionBytes = 0;
+  if (GlobalCodeCompletionAllocator *completionAllocator =
+      astUnit->getCachedCompletionAllocator().getPtr()) {
+    completionBytes = completionAllocator->getTotalMemory();
+  }
+  createCXTUResourceUsageEntry(*entries,
+                               CXTUResourceUsage_GlobalCompletionResults,
+                               completionBytes);
+  
+  // How much memory is being used by SourceManager's content cache?
+  createCXTUResourceUsageEntry(*entries,
+          CXTUResourceUsage_SourceManagerContentCache,
+          (unsigned long) astContext.getSourceManager().getContentCacheSize());
+  
+  // How much memory is being used by the MemoryBuffer's in SourceManager?
+  const SourceManager::MemoryBufferSizes &srcBufs =
+    astUnit->getSourceManager().getMemoryBufferSizes();
+  
+  createCXTUResourceUsageEntry(*entries,
+                               CXTUResourceUsage_SourceManager_Membuffer_Malloc,
+                               (unsigned long) srcBufs.malloc_bytes);
+  createCXTUResourceUsageEntry(*entries,
+                               CXTUResourceUsage_SourceManager_Membuffer_MMap,
+                               (unsigned long) srcBufs.mmap_bytes);
+  createCXTUResourceUsageEntry(*entries,
+                               CXTUResourceUsage_SourceManager_DataStructures,
+                               (unsigned long) astContext.getSourceManager()
+                                .getDataStructureSizes());
+  
+  // How much memory is being used by the ExternalASTSource?
+  if (ExternalASTSource *esrc = astContext.getExternalSource()) {
+    const ExternalASTSource::MemoryBufferSizes &sizes =
+      esrc->getMemoryBufferSizes();
+    
+    createCXTUResourceUsageEntry(*entries,
+      CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
+                                 (unsigned long) sizes.malloc_bytes);
+    createCXTUResourceUsageEntry(*entries,
+      CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
+                                 (unsigned long) sizes.mmap_bytes);
+  }
+  
+  // How much memory is being used by the Preprocessor?
+  Preprocessor &pp = astUnit->getPreprocessor();
+  createCXTUResourceUsageEntry(*entries,
+                               CXTUResourceUsage_Preprocessor,
+                               pp.getTotalMemory());
+  
+  if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
+    createCXTUResourceUsageEntry(*entries,
+                                 CXTUResourceUsage_PreprocessingRecord,
+                                 pRec->getTotalMemory());    
+  }
+  
+  createCXTUResourceUsageEntry(*entries,
+                               CXTUResourceUsage_Preprocessor_HeaderSearch,
+                               pp.getHeaderSearchInfo().getTotalMemory());
+  
+  CXTUResourceUsage usage = { (void*) entries.get(),
+                            (unsigned) entries->size(),
+                            entries->size() ? &(*entries)[0] : 0 };
+  entries.take();
+  return usage;
+}
+
+void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
+  if (usage.data)
+    delete (MemUsageEntries*) usage.data;
+}
+
+} // end extern "C"
+
+void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
+  CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
+  for (unsigned I = 0; I != Usage.numEntries; ++I)
+    fprintf(stderr, "  %s: %lu\n", 
+            clang_getTUResourceUsageName(Usage.entries[I].kind),
+            Usage.entries[I].amount);
+  
+  clang_disposeCXTUResourceUsage(Usage);
+}
+
+//===----------------------------------------------------------------------===//
+// Misc. utility functions.
+//===----------------------------------------------------------------------===//
+
+/// Default to using an 8 MB stack size on "safety" threads.
+static unsigned SafetyStackThreadSize = 8 << 20;
+
+namespace clang {
+
+bool RunSafely(llvm::CrashRecoveryContext &CRC,
+               void (*Fn)(void*), void *UserData,
+               unsigned Size) {
+  if (!Size)
+    Size = GetSafetyThreadStackSize();
+  if (Size)
+    return CRC.RunSafelyOnThread(Fn, UserData, Size);
+  return CRC.RunSafely(Fn, UserData);
+}
+
+unsigned GetSafetyThreadStackSize() {
+  return SafetyStackThreadSize;
+}
+
+void SetSafetyThreadStackSize(unsigned Value) {
+  SafetyStackThreadSize = Value;
+}
+
+}
+
+void clang::setThreadBackgroundPriority() {
+  if (getenv("LIBCLANG_BGPRIO_DISABLE"))
+    return;
+
+  // FIXME: Move to llvm/Support and make it cross-platform.
+#ifdef __APPLE__
+  setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
+#endif
+}
+
+void cxindex::printDiagsToStderr(ASTUnit *Unit) {
+  if (!Unit)
+    return;
+
+  for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 
+                                  DEnd = Unit->stored_diag_end();
+       D != DEnd; ++D) {
+    CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
+    CXString Msg = clang_formatDiagnostic(&Diag,
+                                clang_defaultDiagnosticDisplayOptions());
+    fprintf(stderr, "%s\n", clang_getCString(Msg));
+    clang_disposeString(Msg);
+  }
+#ifdef LLVM_ON_WIN32
+  // On Windows, force a flush, since there may be multiple copies of
+  // stderr and stdout in the file system, all with different buffers
+  // but writing to the same device.
+  fflush(stderr);
+#endif
+}
+
+extern "C" {
+
+CXString clang_getClangVersion() {
+  return createCXString(getClangFullVersion());
+}
+
+} // end: extern "C"
+
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index f88862b..b76363e 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -1,912 +1,906 @@
-//===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===//
-//
-//                     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 generation and use of USRs from CXEntities.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CIndexer.h"
-#include "CXCursor.h"
-#include "CXString.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/Frontend/ASTUnit.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace clang::cxstring;
-
-//===----------------------------------------------------------------------===//
-// USR generation.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class USRGenerator : public DeclVisitor<USRGenerator> {
-  OwningPtr<SmallString<128> > OwnedBuf;
-  SmallVectorImpl<char> &Buf;
-  llvm::raw_svector_ostream Out;
-  bool IgnoreResults;
-  ASTContext *Context;
-  bool generatedLoc;
-  
-  llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
-  
-public:
-  explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
-  : OwnedBuf(extBuf ? 0 : new SmallString<128>()),
-    Buf(extBuf ? *extBuf : *OwnedBuf.get()),
-    Out(Buf),
-    IgnoreResults(false),
-    Context(Ctx),
-    generatedLoc(false)
-  {
-    // Add the USR space prefix.
-    Out << "c:";
-  }
-
-  StringRef str() {
-    return Out.str();
-  }
-
-  USRGenerator* operator->() { return this; }
-
-  template <typename T>
-  llvm::raw_svector_ostream &operator<<(const T &x) {
-    Out << x;
-    return Out;
-  }
-
-  bool ignoreResults() const { return IgnoreResults; }
-
-  // Visitation methods from generating USRs from AST elements.
-  void VisitDeclContext(DeclContext *D);
-  void VisitFieldDecl(FieldDecl *D);
-  void VisitFunctionDecl(FunctionDecl *D);
-  void VisitNamedDecl(NamedDecl *D);
-  void VisitNamespaceDecl(NamespaceDecl *D);
-  void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
-  void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
-  void VisitClassTemplateDecl(ClassTemplateDecl *D);
-  void VisitObjCContainerDecl(ObjCContainerDecl *CD);
-  void VisitObjCMethodDecl(ObjCMethodDecl *MD);
-  void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
-  void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
-  void VisitTagDecl(TagDecl *D);
-  void VisitTypedefDecl(TypedefDecl *D);
-  void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
-  void VisitVarDecl(VarDecl *D);
-  void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
-  void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
-  void VisitLinkageSpecDecl(LinkageSpecDecl *D) {
-    IgnoreResults = true;
-  }
-  void VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
-    IgnoreResults = true;
-  }
-  void VisitUsingDecl(UsingDecl *D) { 
-    IgnoreResults = true;
-  }
-  void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 
-    IgnoreResults = true;
-  }
-  void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { 
-    IgnoreResults = true;
-  }
-  
-  /// Generate the string component containing the location of the
-  ///  declaration.
-  bool GenLoc(const Decl *D);
-
-  /// String generation methods used both by the visitation methods
-  /// and from other clients that want to directly generate USRs.  These
-  /// methods do not construct complete USRs (which incorporate the parents
-  /// of an AST element), but only the fragments concerning the AST element
-  /// itself.
-
-  /// Generate a USR for an Objective-C class.
-  void GenObjCClass(StringRef cls);
-  /// Generate a USR for an Objective-C class category.
-  void GenObjCCategory(StringRef cls, StringRef cat);
-  /// Generate a USR fragment for an Objective-C instance variable.  The
-  /// complete USR can be created by concatenating the USR for the
-  /// encompassing class with this USR fragment.
-  void GenObjCIvar(StringRef ivar);
-  /// Generate a USR fragment for an Objective-C method.
-  void GenObjCMethod(StringRef sel, bool isInstanceMethod);
-  /// Generate a USR fragment for an Objective-C property.
-  void GenObjCProperty(StringRef prop);
-  /// Generate a USR for an Objective-C protocol.
-  void GenObjCProtocol(StringRef prot);
-
-  void VisitType(QualType T);
-  void VisitTemplateParameterList(const TemplateParameterList *Params);
-  void VisitTemplateName(TemplateName Name);
-  void VisitTemplateArgument(const TemplateArgument &Arg);
-  
-  /// Emit a Decl's name using NamedDecl::printName() and return true if
-  ///  the decl had no name.
-  bool EmitDeclName(const NamedDecl *D);
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Generating USRs from ASTS.
-//===----------------------------------------------------------------------===//
-
-bool USRGenerator::EmitDeclName(const NamedDecl *D) {
-  Out.flush();
-  const unsigned startSize = Buf.size();
-  D->printName(Out);
-  Out.flush();
-  const unsigned endSize = Buf.size();
-  return startSize == endSize;
-}
-
-static inline bool ShouldGenerateLocation(const NamedDecl *D) {
-  return D->getLinkage() != ExternalLinkage;
-}
-
-void USRGenerator::VisitDeclContext(DeclContext *DC) {
-  if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
-    Visit(D);
-}
-
-void USRGenerator::VisitFieldDecl(FieldDecl *D) {
-  // The USR for an ivar declared in a class extension is based on the
-  // ObjCInterfaceDecl, not the ObjCCategoryDecl.
-  if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
-    Visit(ID);
-  else
-    VisitDeclContext(D->getDeclContext());
-  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
-  if (EmitDeclName(D)) {
-    // Bit fields can be anonymous.
-    IgnoreResults = true;
-    return;
-  }
-}
-
-void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
-  if (ShouldGenerateLocation(D) && GenLoc(D))
-    return;
-
-  VisitDeclContext(D->getDeclContext());
-  if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
-    Out << "@FT@";
-    VisitTemplateParameterList(FunTmpl->getTemplateParameters());
-  } else
-    Out << "@F@";
-  D->printName(Out);
-
-  ASTContext &Ctx = *Context;
-  if (!Ctx.getLangOpts().CPlusPlus || D->isExternC())
-    return;
-
-  if (const TemplateArgumentList *
-        SpecArgs = D->getTemplateSpecializationArgs()) {
-    Out << '<';
-    for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
-      Out << '#';
-      VisitTemplateArgument(SpecArgs->get(I));
-    }
-    Out << '>';
-  }
-
-  // Mangle in type information for the arguments.
-  for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
-       I != E; ++I) {
-    Out << '#';
-    if (ParmVarDecl *PD = *I)
-      VisitType(PD->getType());
-  }
-  if (D->isVariadic())
-    Out << '.';
-  Out << '#';
-  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
-    if (MD->isStatic())
-      Out << 'S';
-    if (unsigned quals = MD->getTypeQualifiers())
-      Out << (char)('0' + quals);
-  }
-}
-
-void USRGenerator::VisitNamedDecl(NamedDecl *D) {
-  VisitDeclContext(D->getDeclContext());
-  Out << "@";
-
-  if (EmitDeclName(D)) {
-    // The string can be empty if the declaration has no name; e.g., it is
-    // the ParmDecl with no name for declaration of a function pointer type,
-    // e.g.: void  (*f)(void *);
-    // In this case, don't generate a USR.
-    IgnoreResults = true;
-  }
-}
-
-void USRGenerator::VisitVarDecl(VarDecl *D) {
-  // VarDecls can be declared 'extern' within a function or method body,
-  // but their enclosing DeclContext is the function, not the TU.  We need
-  // to check the storage class to correctly generate the USR.
-  if (ShouldGenerateLocation(D) && GenLoc(D))
-    return;
-
-  VisitDeclContext(D->getDeclContext());
-
-  // Variables always have simple names.
-  StringRef s = D->getName();
-
-  // The string can be empty if the declaration has no name; e.g., it is
-  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
-  //    void  (*f)(void *);
-  // In this case, don't generate a USR.
-  if (s.empty())
-    IgnoreResults = true;
-  else
-    Out << '@' << s;
-}
-
-void USRGenerator::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
-  GenLoc(D);
-  return;
-}
-
-void USRGenerator::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
-  GenLoc(D);
-  return;
-}
-
-void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
-  if (D->isAnonymousNamespace()) {
-    Out << "@aN";
-    return;
-  }
-
-  VisitDeclContext(D->getDeclContext());
-  if (!IgnoreResults)
-    Out << "@N@" << D->getName();
-}
-
-void USRGenerator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
-  VisitFunctionDecl(D->getTemplatedDecl());
-}
-
-void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
-  VisitTagDecl(D->getTemplatedDecl());
-}
-
-void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
-  VisitDeclContext(D->getDeclContext());
-  if (!IgnoreResults)
-    Out << "@NA@" << D->getName();  
-}
-
-void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
-  DeclContext *container = D->getDeclContext();
-  if (ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
-    Visit(pd);
-  }
-  else {
-    // The USR for a method declared in a class extension or category is based on
-    // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
-    ObjCInterfaceDecl *ID = D->getClassInterface();
-    if (!ID) {
-      IgnoreResults = true;
-      return;
-    }
-    Visit(ID);
-  }
-  // Ideally we would use 'GenObjCMethod', but this is such a hot path
-  // for Objective-C code that we don't want to use
-  // DeclarationName::getAsString().
-  Out << (D->isInstanceMethod() ? "(im)" : "(cm)");
-  DeclarationName N(D->getSelector());
-  N.printName(Out);
-}
-
-void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
-  switch (D->getKind()) {
-    default:
-      llvm_unreachable("Invalid ObjC container.");
-    case Decl::ObjCInterface:
-    case Decl::ObjCImplementation:
-      GenObjCClass(D->getName());
-      break;
-    case Decl::ObjCCategory: {
-      ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
-      ObjCInterfaceDecl *ID = CD->getClassInterface();
-      if (!ID) {
-        // Handle invalid code where the @interface might not
-        // have been specified.
-        // FIXME: We should be able to generate this USR even if the
-        // @interface isn't available.
-        IgnoreResults = true;
-        return;
-      }
-      // Specially handle class extensions, which are anonymous categories.
-      // We want to mangle in the location to uniquely distinguish them.
-      if (CD->IsClassExtension()) {
-        Out << "objc(ext)" << ID->getName() << '@';
-        GenLoc(CD);
-      }
-      else
-        GenObjCCategory(ID->getName(), CD->getName());
-
-      break;
-    }
-    case Decl::ObjCCategoryImpl: {
-      ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
-      ObjCInterfaceDecl *ID = CD->getClassInterface();
-      if (!ID) {
-        // Handle invalid code where the @interface might not
-        // have been specified.
-        // FIXME: We should be able to generate this USR even if the
-        // @interface isn't available.
-        IgnoreResults = true;
-        return;
-      }
-      GenObjCCategory(ID->getName(), CD->getName());
-      break;
-    }
-    case Decl::ObjCProtocol:
-      GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
-      break;
-  }
-}
-
-void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
-  // The USR for a property declared in a class extension or category is based
-  // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
-  if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
-    Visit(ID);
-  else
-    Visit(cast<Decl>(D->getDeclContext()));
-  GenObjCProperty(D->getName());
-}
-
-void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
-  if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
-    VisitObjCPropertyDecl(PD);
-    return;
-  }
-
-  IgnoreResults = true;
-}
-
-void USRGenerator::VisitTagDecl(TagDecl *D) {
-  // Add the location of the tag decl to handle resolution across
-  // translation units.
-  if (ShouldGenerateLocation(D) && GenLoc(D))
-    return;
-
-  D = D->getCanonicalDecl();
-  VisitDeclContext(D->getDeclContext());
-
-  bool AlreadyStarted = false;
-  if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
-    if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
-      AlreadyStarted = true;
-      
-      switch (D->getTagKind()) {
-      case TTK_Interface:
-      case TTK_Struct: Out << "@ST"; break;
-      case TTK_Class:  Out << "@CT"; break;
-      case TTK_Union:  Out << "@UT"; break;
-      case TTK_Enum: llvm_unreachable("enum template");
-      }
-      VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
-    } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
-                = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
-      AlreadyStarted = true;
-      
-      switch (D->getTagKind()) {
-      case TTK_Interface:
-      case TTK_Struct: Out << "@SP"; break;
-      case TTK_Class:  Out << "@CP"; break;
-      case TTK_Union:  Out << "@UP"; break;
-      case TTK_Enum: llvm_unreachable("enum partial specialization");
-      }      
-      VisitTemplateParameterList(PartialSpec->getTemplateParameters());
-    }
-  }
-  
-  if (!AlreadyStarted) {
-    switch (D->getTagKind()) {
-      case TTK_Interface:
-      case TTK_Struct: Out << "@S"; break;
-      case TTK_Class:  Out << "@C"; break;
-      case TTK_Union:  Out << "@U"; break;
-      case TTK_Enum:   Out << "@E"; break;
-    }
-  }
-  
-  Out << '@';
-  Out.flush();
-  assert(Buf.size() > 0);
-  const unsigned off = Buf.size() - 1;
-
-  if (EmitDeclName(D)) {
-    if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
-      Buf[off] = 'A';
-      Out << '@' << *TD;
-    }
-    else
-      Buf[off] = 'a';
-  }
-  
-  // For a class template specialization, mangle the template arguments.
-  if (ClassTemplateSpecializationDecl *Spec
-                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
-    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
-    Out << '>';
-    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
-      Out << '#';
-      VisitTemplateArgument(Args.get(I));
-    }
-  }
-}
-
-void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
-  if (ShouldGenerateLocation(D) && GenLoc(D))
-    return;
-  DeclContext *DC = D->getDeclContext();
-  if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
-    Visit(DCN);
-  Out << "@T@";
-  Out << D->getName();
-}
-
-void USRGenerator::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
-  GenLoc(D);
-  return;
-}
-
-bool USRGenerator::GenLoc(const Decl *D) {
-  if (generatedLoc)
-    return IgnoreResults;
-  generatedLoc = true;
-  
-  // Guard against null declarations in invalid code.
-  if (!D) {
-    IgnoreResults = true;
-    return true;
-  }
-
-  // Use the location of canonical decl.
-  D = D->getCanonicalDecl();
-
-  const SourceManager &SM = Context->getSourceManager();
-  SourceLocation L = D->getLocStart();
-  if (L.isInvalid()) {
-    IgnoreResults = true;
-    return true;
-  }
-  L = SM.getExpansionLoc(L);
-  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
-  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
-  if (FE) {
-    Out << llvm::sys::path::filename(FE->getName());
-  }
-  else {
-    // This case really isn't interesting.
-    IgnoreResults = true;
-    return true;
-  }
-  // Use the offest into the FileID to represent the location.  Using
-  // a line/column can cause us to look back at the original source file,
-  // which is expensive.
-  Out << '@' << Decomposed.second;
-  return IgnoreResults;
-}
-
-void USRGenerator::VisitType(QualType T) {
-  // This method mangles in USR information for types.  It can possibly
-  // just reuse the naming-mangling logic used by codegen, although the
-  // requirements for USRs might not be the same.
-  ASTContext &Ctx = *Context;
-
-  do {
-    T = Ctx.getCanonicalType(T);
-    Qualifiers Q = T.getQualifiers();
-    unsigned qVal = 0;
-    if (Q.hasConst())
-      qVal |= 0x1;
-    if (Q.hasVolatile())
-      qVal |= 0x2;
-    if (Q.hasRestrict())
-      qVal |= 0x4;
-    if(qVal)
-      Out << ((char) ('0' + qVal));
-
-    // Mangle in ObjC GC qualifiers?
-
-    if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
-      Out << 'P';
-      T = Expansion->getPattern();
-    }
-    
-    if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
-      unsigned char c = '\0';
-      switch (BT->getKind()) {
-        case BuiltinType::Void:
-          c = 'v'; break;
-        case BuiltinType::Bool:
-          c = 'b'; break;
-        case BuiltinType::Char_U:
-        case BuiltinType::UChar:
-          c = 'c'; break;
-        case BuiltinType::Char16:
-          c = 'q'; break;
-        case BuiltinType::Char32:
-          c = 'w'; break;
-        case BuiltinType::UShort:
-          c = 's'; break;
-        case BuiltinType::UInt:
-          c = 'i'; break;
-        case BuiltinType::ULong:
-          c = 'l'; break;
-        case BuiltinType::ULongLong:
-          c = 'k'; break;
-        case BuiltinType::UInt128:
-          c = 'j'; break;
-        case BuiltinType::Char_S:
-        case BuiltinType::SChar:
-          c = 'C'; break;
-        case BuiltinType::WChar_S:
-        case BuiltinType::WChar_U:
-          c = 'W'; break;
-        case BuiltinType::Short:
-          c = 'S'; break;
-        case BuiltinType::Int:
-          c = 'I'; break;
-        case BuiltinType::Long:
-          c = 'L'; break;
-        case BuiltinType::LongLong:
-          c = 'K'; break;
-        case BuiltinType::Int128:
-          c = 'J'; break;
-        case BuiltinType::Half:
-          c = 'h'; break;
-        case BuiltinType::Float:
-          c = 'f'; break;
-        case BuiltinType::Double:
-          c = 'd'; break;
-        case BuiltinType::LongDouble:
-          c = 'D'; break;
-        case BuiltinType::NullPtr:
-          c = 'n'; break;
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-        case BuiltinType::Dependent:
-        case BuiltinType::OCLImage1d:
-        case BuiltinType::OCLImage1dArray:
-        case BuiltinType::OCLImage1dBuffer:
-        case BuiltinType::OCLImage2d:
-        case BuiltinType::OCLImage2dArray:
-        case BuiltinType::OCLImage3d:
-          IgnoreResults = true;
-          return;
-        case BuiltinType::ObjCId:
-          c = 'o'; break;
-        case BuiltinType::ObjCClass:
-          c = 'O'; break;
-        case BuiltinType::ObjCSel:
-          c = 'e'; break;
-      }
-      Out << c;
-      return;
-    }
-
-    // If we have already seen this (non-built-in) type, use a substitution
-    // encoding.
-    llvm::DenseMap<const Type *, unsigned>::iterator Substitution
-      = TypeSubstitutions.find(T.getTypePtr());
-    if (Substitution != TypeSubstitutions.end()) {
-      Out << 'S' << Substitution->second << '_';
-      return;
-    } else {
-      // Record this as a substitution.
-      unsigned Number = TypeSubstitutions.size();
-      TypeSubstitutions[T.getTypePtr()] = Number;
-    }
-    
-    if (const PointerType *PT = T->getAs<PointerType>()) {
-      Out << '*';
-      T = PT->getPointeeType();
-      continue;
-    }
-    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
-      Out << '&';
-      T = RT->getPointeeType();
-      continue;
-    }
-    if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
-      Out << 'F';
-      VisitType(FT->getResultType());
-      for (FunctionProtoType::arg_type_iterator
-            I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) {
-        VisitType(*I);
-      }
-      if (FT->isVariadic())
-        Out << '.';
-      return;
-    }
-    if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
-      Out << 'B';
-      T = BT->getPointeeType();
-      continue;
-    }
-    if (const ComplexType *CT = T->getAs<ComplexType>()) {
-      Out << '<';
-      T = CT->getElementType();
-      continue;
-    }
-    if (const TagType *TT = T->getAs<TagType>()) {
-      Out << '$';
-      VisitTagDecl(TT->getDecl());
-      return;
-    }
-    if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
-      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
-      return;
-    }
-    if (const TemplateSpecializationType *Spec
-                                    = T->getAs<TemplateSpecializationType>()) {
-      Out << '>';
-      VisitTemplateName(Spec->getTemplateName());
-      Out << Spec->getNumArgs();
-      for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
-        VisitTemplateArgument(Spec->getArg(I));
-      return;
-    }
-    
-    // Unhandled type.
-    Out << ' ';
-    break;
-  } while (true);
-}
-
-void USRGenerator::VisitTemplateParameterList(
-                                         const TemplateParameterList *Params) {
-  if (!Params)
-    return;
-  Out << '>' << Params->size();
-  for (TemplateParameterList::const_iterator P = Params->begin(),
-                                          PEnd = Params->end();
-       P != PEnd; ++P) {
-    Out << '#';
-    if (isa<TemplateTypeParmDecl>(*P)) {
-      if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
-        Out<< 'p';
-      Out << 'T';
-      continue;
-    }
-    
-    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
-      if (NTTP->isParameterPack())
-        Out << 'p';
-      Out << 'N';
-      VisitType(NTTP->getType());
-      continue;
-    }
-    
-    TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
-    if (TTP->isParameterPack())
-      Out << 'p';
-    Out << 't';
-    VisitTemplateParameterList(TTP->getTemplateParameters());
-  }
-}
-
-void USRGenerator::VisitTemplateName(TemplateName Name) {
-  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
-    if (TemplateTemplateParmDecl *TTP
-                              = dyn_cast<TemplateTemplateParmDecl>(Template)) {
-      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
-      return;
-    }
-    
-    Visit(Template);
-    return;
-  }
-  
-  // FIXME: Visit dependent template names.
-}
-
-void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
-  switch (Arg.getKind()) {
-  case TemplateArgument::Null:
-    break;
-
-  case TemplateArgument::Declaration:
-    Visit(Arg.getAsDecl());
-    break;
-
-  case TemplateArgument::NullPtr:
-    break;
-
-  case TemplateArgument::TemplateExpansion:
-    Out << 'P'; // pack expansion of...
-    // Fall through
-  case TemplateArgument::Template:
-    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
-    break;
-      
-  case TemplateArgument::Expression:
-    // FIXME: Visit expressions.
-    break;
-      
-  case TemplateArgument::Pack:
-    Out << 'p' << Arg.pack_size();
-    for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end();
-         P != PEnd; ++P)
-      VisitTemplateArgument(*P);
-    break;
-      
-  case TemplateArgument::Type:
-    VisitType(Arg.getAsType());
-    break;
-      
-  case TemplateArgument::Integral:
-    Out << 'V';
-    VisitType(Arg.getIntegralType());
-    Out << Arg.getAsIntegral();
-    break;
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// General purpose USR generation methods.
-//===----------------------------------------------------------------------===//
-
-void USRGenerator::GenObjCClass(StringRef cls) {
-  Out << "objc(cs)" << cls;
-}
-
-void USRGenerator::GenObjCCategory(StringRef cls, StringRef cat) {
-  Out << "objc(cy)" << cls << '@' << cat;
-}
-
-void USRGenerator::GenObjCIvar(StringRef ivar) {
-  Out << '@' << ivar;
-}
-
-void USRGenerator::GenObjCMethod(StringRef meth, bool isInstanceMethod) {
-  Out << (isInstanceMethod ? "(im)" : "(cm)") << meth;
-}
-
-void USRGenerator::GenObjCProperty(StringRef prop) {
-  Out << "(py)" << prop;
-}
-
-void USRGenerator::GenObjCProtocol(StringRef prot) {
-  Out << "objc(pl)" << prot;
-}
-
-//===----------------------------------------------------------------------===//
-// API hooks.
-//===----------------------------------------------------------------------===//
-
-static inline StringRef extractUSRSuffix(StringRef s) {
-  return s.startswith("c:") ? s.substr(2) : "";
-}
-
-bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
-  // Don't generate USRs for things with invalid locations.
-  if (!D || D->getLocStart().isInvalid())
-    return true;
-
-  USRGenerator UG(&D->getASTContext(), &Buf);
-  UG->Visit(const_cast<Decl*>(D));
-
-  if (UG->ignoreResults())
-    return true;
-
-  return false;
-}
-
-extern "C" {
-
-CXString clang_getCursorUSR(CXCursor C) {
-  const CXCursorKind &K = clang_getCursorKind(C);
-
-  if (clang_isDeclaration(K)) {
-    Decl *D = cxcursor::getCursorDecl(C);
-    if (!D)
-      return createCXString("");
-
-    CXTranslationUnit TU = cxcursor::getCursorTU(C);
-    if (!TU)
-      return createCXString("");
-
-    CXStringBuf *buf = cxstring::getCXStringBuf(TU);
-    if (!buf)
-      return createCXString("");
-
-    bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
-    if (Ignore) {
-      disposeCXStringBuf(buf);
-      return createCXString("");
-    }
-
-    // Return the C-string, but don't make a copy since it is already in
-    // the string buffer.
-    buf->Data.push_back('\0');
-    return createCXString(buf);
-  }
-
-  if (K == CXCursor_MacroDefinition) {
-    CXTranslationUnit TU = cxcursor::getCursorTU(C);
-    if (!TU)
-      return createCXString("");
-
-    CXStringBuf *buf = cxstring::getCXStringBuf(TU);
-    if (!buf)
-      return createCXString("");
-
-    {
-      USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
-                      &buf->Data);
-      UG << "macro@"
-        << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
-    }
-    buf->Data.push_back('\0');
-    return createCXString(buf);
-  }
-
-  return createCXString("");
-}
-
-CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
-  USRGenerator UG;
-  UG << extractUSRSuffix(clang_getCString(classUSR));
-  UG->GenObjCIvar(name);
-  return createCXString(UG.str(), true);
-}
-
-CXString clang_constructUSR_ObjCMethod(const char *name,
-                                       unsigned isInstanceMethod,
-                                       CXString classUSR) {
-  USRGenerator UG;
-  UG << extractUSRSuffix(clang_getCString(classUSR));
-  UG->GenObjCMethod(name, isInstanceMethod);
-  return createCXString(UG.str(), true);
-}
-
-CXString clang_constructUSR_ObjCClass(const char *name) {
-  USRGenerator UG;
-  UG->GenObjCClass(name);
-  return createCXString(UG.str(), true);
-}
-
-CXString clang_constructUSR_ObjCProtocol(const char *name) {
-  USRGenerator UG;
-  UG->GenObjCProtocol(name);
-  return createCXString(UG.str(), true);
-}
-
-CXString clang_constructUSR_ObjCCategory(const char *class_name,
-                                         const char *category_name) {
-  USRGenerator UG;
-  UG->GenObjCCategory(class_name, category_name);
-  return createCXString(UG.str(), true);
-}
-
-CXString clang_constructUSR_ObjCProperty(const char *property,
-                                         CXString classUSR) {
-  USRGenerator UG;
-  UG << extractUSRSuffix(clang_getCString(classUSR));
-  UG->GenObjCProperty(property);
-  return createCXString(UG.str(), true);
-}
-
-} // end extern "C"
+//===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===//
+//
+//                     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 generation and use of USRs from CXEntities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CXCursor.h"
+#include "CXString.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::cxstring;
+
+//===----------------------------------------------------------------------===//
+// USR generation.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class USRGenerator : public DeclVisitor<USRGenerator> {
+  OwningPtr<SmallString<128> > OwnedBuf;
+  SmallVectorImpl<char> &Buf;
+  llvm::raw_svector_ostream Out;
+  bool IgnoreResults;
+  ASTContext *Context;
+  bool generatedLoc;
+  
+  llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
+  
+public:
+  explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
+  : OwnedBuf(extBuf ? 0 : new SmallString<128>()),
+    Buf(extBuf ? *extBuf : *OwnedBuf.get()),
+    Out(Buf),
+    IgnoreResults(false),
+    Context(Ctx),
+    generatedLoc(false)
+  {
+    // Add the USR space prefix.
+    Out << "c:";
+  }
+
+  StringRef str() {
+    return Out.str();
+  }
+
+  USRGenerator* operator->() { return this; }
+
+  template <typename T>
+  llvm::raw_svector_ostream &operator<<(const T &x) {
+    Out << x;
+    return Out;
+  }
+
+  bool ignoreResults() const { return IgnoreResults; }
+
+  // Visitation methods from generating USRs from AST elements.
+  void VisitDeclContext(DeclContext *D);
+  void VisitFieldDecl(FieldDecl *D);
+  void VisitFunctionDecl(FunctionDecl *D);
+  void VisitNamedDecl(NamedDecl *D);
+  void VisitNamespaceDecl(NamespaceDecl *D);
+  void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+  void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+  void VisitClassTemplateDecl(ClassTemplateDecl *D);
+  void VisitObjCContainerDecl(ObjCContainerDecl *CD);
+  void VisitObjCMethodDecl(ObjCMethodDecl *MD);
+  void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+  void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+  void VisitTagDecl(TagDecl *D);
+  void VisitTypedefDecl(TypedefDecl *D);
+  void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+  void VisitVarDecl(VarDecl *D);
+  void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+  void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+  void VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+    IgnoreResults = true;
+  }
+  void VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+    IgnoreResults = true;
+  }
+  void VisitUsingDecl(UsingDecl *D) { 
+    IgnoreResults = true;
+  }
+  void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 
+    IgnoreResults = true;
+  }
+  void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { 
+    IgnoreResults = true;
+  }
+  
+  /// Generate the string component containing the location of the
+  ///  declaration.
+  bool GenLoc(const Decl *D);
+
+  /// String generation methods used both by the visitation methods
+  /// and from other clients that want to directly generate USRs.  These
+  /// methods do not construct complete USRs (which incorporate the parents
+  /// of an AST element), but only the fragments concerning the AST element
+  /// itself.
+
+  /// Generate a USR for an Objective-C class.
+  void GenObjCClass(StringRef cls);
+  /// Generate a USR for an Objective-C class category.
+  void GenObjCCategory(StringRef cls, StringRef cat);
+  /// Generate a USR fragment for an Objective-C instance variable.  The
+  /// complete USR can be created by concatenating the USR for the
+  /// encompassing class with this USR fragment.
+  void GenObjCIvar(StringRef ivar);
+  /// Generate a USR fragment for an Objective-C method.
+  void GenObjCMethod(StringRef sel, bool isInstanceMethod);
+  /// Generate a USR fragment for an Objective-C property.
+  void GenObjCProperty(StringRef prop);
+  /// Generate a USR for an Objective-C protocol.
+  void GenObjCProtocol(StringRef prot);
+
+  void VisitType(QualType T);
+  void VisitTemplateParameterList(const TemplateParameterList *Params);
+  void VisitTemplateName(TemplateName Name);
+  void VisitTemplateArgument(const TemplateArgument &Arg);
+  
+  /// Emit a Decl's name using NamedDecl::printName() and return true if
+  ///  the decl had no name.
+  bool EmitDeclName(const NamedDecl *D);
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Generating USRs from ASTS.
+//===----------------------------------------------------------------------===//
+
+bool USRGenerator::EmitDeclName(const NamedDecl *D) {
+  Out.flush();
+  const unsigned startSize = Buf.size();
+  D->printName(Out);
+  Out.flush();
+  const unsigned endSize = Buf.size();
+  return startSize == endSize;
+}
+
+static inline bool ShouldGenerateLocation(const NamedDecl *D) {
+  return D->getLinkage() != ExternalLinkage;
+}
+
+void USRGenerator::VisitDeclContext(DeclContext *DC) {
+  if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
+    Visit(D);
+}
+
+void USRGenerator::VisitFieldDecl(FieldDecl *D) {
+  // The USR for an ivar declared in a class extension is based on the
+  // ObjCInterfaceDecl, not the ObjCCategoryDecl.
+  if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+    Visit(ID);
+  else
+    VisitDeclContext(D->getDeclContext());
+  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
+  if (EmitDeclName(D)) {
+    // Bit fields can be anonymous.
+    IgnoreResults = true;
+    return;
+  }
+}
+
+void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  VisitDeclContext(D->getDeclContext());
+  if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
+    Out << "@FT@";
+    VisitTemplateParameterList(FunTmpl->getTemplateParameters());
+  } else
+    Out << "@F@";
+  D->printName(Out);
+
+  ASTContext &Ctx = *Context;
+  if (!Ctx.getLangOpts().CPlusPlus || D->isExternC())
+    return;
+
+  if (const TemplateArgumentList *
+        SpecArgs = D->getTemplateSpecializationArgs()) {
+    Out << '<';
+    for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
+      Out << '#';
+      VisitTemplateArgument(SpecArgs->get(I));
+    }
+    Out << '>';
+  }
+
+  // Mangle in type information for the arguments.
+  for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    Out << '#';
+    if (ParmVarDecl *PD = *I)
+      VisitType(PD->getType());
+  }
+  if (D->isVariadic())
+    Out << '.';
+  Out << '#';
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+    if (MD->isStatic())
+      Out << 'S';
+    if (unsigned quals = MD->getTypeQualifiers())
+      Out << (char)('0' + quals);
+  }
+}
+
+void USRGenerator::VisitNamedDecl(NamedDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  Out << "@";
+
+  if (EmitDeclName(D)) {
+    // The string can be empty if the declaration has no name; e.g., it is
+    // the ParmDecl with no name for declaration of a function pointer type,
+    // e.g.: void  (*f)(void *);
+    // In this case, don't generate a USR.
+    IgnoreResults = true;
+  }
+}
+
+void USRGenerator::VisitVarDecl(VarDecl *D) {
+  // VarDecls can be declared 'extern' within a function or method body,
+  // but their enclosing DeclContext is the function, not the TU.  We need
+  // to check the storage class to correctly generate the USR.
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  VisitDeclContext(D->getDeclContext());
+
+  // Variables always have simple names.
+  StringRef s = D->getName();
+
+  // The string can be empty if the declaration has no name; e.g., it is
+  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
+  //    void  (*f)(void *);
+  // In this case, don't generate a USR.
+  if (s.empty())
+    IgnoreResults = true;
+  else
+    Out << '@' << s;
+}
+
+void USRGenerator::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  GenLoc(D);
+  return;
+}
+
+void USRGenerator::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  GenLoc(D);
+  return;
+}
+
+void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
+  if (D->isAnonymousNamespace()) {
+    Out << "@aN";
+    return;
+  }
+
+  VisitDeclContext(D->getDeclContext());
+  if (!IgnoreResults)
+    Out << "@N@" << D->getName();
+}
+
+void USRGenerator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  VisitFunctionDecl(D->getTemplatedDecl());
+}
+
+void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  VisitTagDecl(D->getTemplatedDecl());
+}
+
+void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  if (!IgnoreResults)
+    Out << "@NA@" << D->getName();  
+}
+
+void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  DeclContext *container = D->getDeclContext();
+  if (ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
+    Visit(pd);
+  }
+  else {
+    // The USR for a method declared in a class extension or category is based on
+    // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
+    ObjCInterfaceDecl *ID = D->getClassInterface();
+    if (!ID) {
+      IgnoreResults = true;
+      return;
+    }
+    Visit(ID);
+  }
+  // Ideally we would use 'GenObjCMethod', but this is such a hot path
+  // for Objective-C code that we don't want to use
+  // DeclarationName::getAsString().
+  Out << (D->isInstanceMethod() ? "(im)" : "(cm)");
+  DeclarationName N(D->getSelector());
+  N.printName(Out);
+}
+
+void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  switch (D->getKind()) {
+    default:
+      llvm_unreachable("Invalid ObjC container.");
+    case Decl::ObjCInterface:
+    case Decl::ObjCImplementation:
+      GenObjCClass(D->getName());
+      break;
+    case Decl::ObjCCategory: {
+      ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
+      ObjCInterfaceDecl *ID = CD->getClassInterface();
+      if (!ID) {
+        // Handle invalid code where the @interface might not
+        // have been specified.
+        // FIXME: We should be able to generate this USR even if the
+        // @interface isn't available.
+        IgnoreResults = true;
+        return;
+      }
+      // Specially handle class extensions, which are anonymous categories.
+      // We want to mangle in the location to uniquely distinguish them.
+      if (CD->IsClassExtension()) {
+        Out << "objc(ext)" << ID->getName() << '@';
+        GenLoc(CD);
+      }
+      else
+        GenObjCCategory(ID->getName(), CD->getName());
+
+      break;
+    }
+    case Decl::ObjCCategoryImpl: {
+      ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
+      ObjCInterfaceDecl *ID = CD->getClassInterface();
+      if (!ID) {
+        // Handle invalid code where the @interface might not
+        // have been specified.
+        // FIXME: We should be able to generate this USR even if the
+        // @interface isn't available.
+        IgnoreResults = true;
+        return;
+      }
+      GenObjCCategory(ID->getName(), CD->getName());
+      break;
+    }
+    case Decl::ObjCProtocol:
+      GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
+      break;
+  }
+}
+
+void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  // The USR for a property declared in a class extension or category is based
+  // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
+  if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+    Visit(ID);
+  else
+    Visit(cast<Decl>(D->getDeclContext()));
+  GenObjCProperty(D->getName());
+}
+
+void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
+    VisitObjCPropertyDecl(PD);
+    return;
+  }
+
+  IgnoreResults = true;
+}
+
+void USRGenerator::VisitTagDecl(TagDecl *D) {
+  // Add the location of the tag decl to handle resolution across
+  // translation units.
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  D = D->getCanonicalDecl();
+  VisitDeclContext(D->getDeclContext());
+
+  bool AlreadyStarted = false;
+  if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+    if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
+      AlreadyStarted = true;
+      
+      switch (D->getTagKind()) {
+      case TTK_Interface:
+      case TTK_Struct: Out << "@ST"; break;
+      case TTK_Class:  Out << "@CT"; break;
+      case TTK_Union:  Out << "@UT"; break;
+      case TTK_Enum: llvm_unreachable("enum template");
+      }
+      VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
+    } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
+                = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
+      AlreadyStarted = true;
+      
+      switch (D->getTagKind()) {
+      case TTK_Interface:
+      case TTK_Struct: Out << "@SP"; break;
+      case TTK_Class:  Out << "@CP"; break;
+      case TTK_Union:  Out << "@UP"; break;
+      case TTK_Enum: llvm_unreachable("enum partial specialization");
+      }      
+      VisitTemplateParameterList(PartialSpec->getTemplateParameters());
+    }
+  }
+  
+  if (!AlreadyStarted) {
+    switch (D->getTagKind()) {
+      case TTK_Interface:
+      case TTK_Struct: Out << "@S"; break;
+      case TTK_Class:  Out << "@C"; break;
+      case TTK_Union:  Out << "@U"; break;
+      case TTK_Enum:   Out << "@E"; break;
+    }
+  }
+  
+  Out << '@';
+  Out.flush();
+  assert(Buf.size() > 0);
+  const unsigned off = Buf.size() - 1;
+
+  if (EmitDeclName(D)) {
+    if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
+      Buf[off] = 'A';
+      Out << '@' << *TD;
+    }
+    else
+      Buf[off] = 'a';
+  }
+  
+  // For a class template specialization, mangle the template arguments.
+  if (ClassTemplateSpecializationDecl *Spec
+                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    Out << '>';
+    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+      Out << '#';
+      VisitTemplateArgument(Args.get(I));
+    }
+  }
+}
+
+void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+  DeclContext *DC = D->getDeclContext();
+  if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
+    Visit(DCN);
+  Out << "@T@";
+  Out << D->getName();
+}
+
+void USRGenerator::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  GenLoc(D);
+  return;
+}
+
+bool USRGenerator::GenLoc(const Decl *D) {
+  if (generatedLoc)
+    return IgnoreResults;
+  generatedLoc = true;
+  
+  // Guard against null declarations in invalid code.
+  if (!D) {
+    IgnoreResults = true;
+    return true;
+  }
+
+  // Use the location of canonical decl.
+  D = D->getCanonicalDecl();
+
+  const SourceManager &SM = Context->getSourceManager();
+  SourceLocation L = D->getLocStart();
+  if (L.isInvalid()) {
+    IgnoreResults = true;
+    return true;
+  }
+  L = SM.getExpansionLoc(L);
+  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
+  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
+  if (FE) {
+    Out << llvm::sys::path::filename(FE->getName());
+  }
+  else {
+    // This case really isn't interesting.
+    IgnoreResults = true;
+    return true;
+  }
+  // Use the offest into the FileID to represent the location.  Using
+  // a line/column can cause us to look back at the original source file,
+  // which is expensive.
+  Out << '@' << Decomposed.second;
+  return IgnoreResults;
+}
+
+void USRGenerator::VisitType(QualType T) {
+  // This method mangles in USR information for types.  It can possibly
+  // just reuse the naming-mangling logic used by codegen, although the
+  // requirements for USRs might not be the same.
+  ASTContext &Ctx = *Context;
+
+  do {
+    T = Ctx.getCanonicalType(T);
+    Qualifiers Q = T.getQualifiers();
+    unsigned qVal = 0;
+    if (Q.hasConst())
+      qVal |= 0x1;
+    if (Q.hasVolatile())
+      qVal |= 0x2;
+    if (Q.hasRestrict())
+      qVal |= 0x4;
+    if(qVal)
+      Out << ((char) ('0' + qVal));
+
+    // Mangle in ObjC GC qualifiers?
+
+    if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
+      Out << 'P';
+      T = Expansion->getPattern();
+    }
+    
+    if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
+      unsigned char c = '\0';
+      switch (BT->getKind()) {
+        case BuiltinType::Void:
+          c = 'v'; break;
+        case BuiltinType::Bool:
+          c = 'b'; break;
+        case BuiltinType::Char_U:
+        case BuiltinType::UChar:
+          c = 'c'; break;
+        case BuiltinType::Char16:
+          c = 'q'; break;
+        case BuiltinType::Char32:
+          c = 'w'; break;
+        case BuiltinType::UShort:
+          c = 's'; break;
+        case BuiltinType::UInt:
+          c = 'i'; break;
+        case BuiltinType::ULong:
+          c = 'l'; break;
+        case BuiltinType::ULongLong:
+          c = 'k'; break;
+        case BuiltinType::UInt128:
+          c = 'j'; break;
+        case BuiltinType::Char_S:
+        case BuiltinType::SChar:
+          c = 'C'; break;
+        case BuiltinType::WChar_S:
+        case BuiltinType::WChar_U:
+          c = 'W'; break;
+        case BuiltinType::Short:
+          c = 'S'; break;
+        case BuiltinType::Int:
+          c = 'I'; break;
+        case BuiltinType::Long:
+          c = 'L'; break;
+        case BuiltinType::LongLong:
+          c = 'K'; break;
+        case BuiltinType::Int128:
+          c = 'J'; break;
+        case BuiltinType::Half:
+          c = 'h'; break;
+        case BuiltinType::Float:
+          c = 'f'; break;
+        case BuiltinType::Double:
+          c = 'd'; break;
+        case BuiltinType::LongDouble:
+          c = 'D'; break;
+        case BuiltinType::NullPtr:
+          c = 'n'; break;
+#define BUILTIN_TYPE(Id, SingletonId)
+#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
+#include "clang/AST/BuiltinTypes.def"
+        case BuiltinType::Dependent:
+          IgnoreResults = true;
+          return;
+        case BuiltinType::ObjCId:
+          c = 'o'; break;
+        case BuiltinType::ObjCClass:
+          c = 'O'; break;
+        case BuiltinType::ObjCSel:
+          c = 'e'; break;
+      }
+      Out << c;
+      return;
+    }
+
+    // If we have already seen this (non-built-in) type, use a substitution
+    // encoding.
+    llvm::DenseMap<const Type *, unsigned>::iterator Substitution
+      = TypeSubstitutions.find(T.getTypePtr());
+    if (Substitution != TypeSubstitutions.end()) {
+      Out << 'S' << Substitution->second << '_';
+      return;
+    } else {
+      // Record this as a substitution.
+      unsigned Number = TypeSubstitutions.size();
+      TypeSubstitutions[T.getTypePtr()] = Number;
+    }
+    
+    if (const PointerType *PT = T->getAs<PointerType>()) {
+      Out << '*';
+      T = PT->getPointeeType();
+      continue;
+    }
+    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
+      Out << '&';
+      T = RT->getPointeeType();
+      continue;
+    }
+    if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
+      Out << 'F';
+      VisitType(FT->getResultType());
+      for (FunctionProtoType::arg_type_iterator
+            I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) {
+        VisitType(*I);
+      }
+      if (FT->isVariadic())
+        Out << '.';
+      return;
+    }
+    if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
+      Out << 'B';
+      T = BT->getPointeeType();
+      continue;
+    }
+    if (const ComplexType *CT = T->getAs<ComplexType>()) {
+      Out << '<';
+      T = CT->getElementType();
+      continue;
+    }
+    if (const TagType *TT = T->getAs<TagType>()) {
+      Out << '$';
+      VisitTagDecl(TT->getDecl());
+      return;
+    }
+    if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
+      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
+      return;
+    }
+    if (const TemplateSpecializationType *Spec
+                                    = T->getAs<TemplateSpecializationType>()) {
+      Out << '>';
+      VisitTemplateName(Spec->getTemplateName());
+      Out << Spec->getNumArgs();
+      for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
+        VisitTemplateArgument(Spec->getArg(I));
+      return;
+    }
+    
+    // Unhandled type.
+    Out << ' ';
+    break;
+  } while (true);
+}
+
+void USRGenerator::VisitTemplateParameterList(
+                                         const TemplateParameterList *Params) {
+  if (!Params)
+    return;
+  Out << '>' << Params->size();
+  for (TemplateParameterList::const_iterator P = Params->begin(),
+                                          PEnd = Params->end();
+       P != PEnd; ++P) {
+    Out << '#';
+    if (isa<TemplateTypeParmDecl>(*P)) {
+      if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
+        Out<< 'p';
+      Out << 'T';
+      continue;
+    }
+    
+    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+      if (NTTP->isParameterPack())
+        Out << 'p';
+      Out << 'N';
+      VisitType(NTTP->getType());
+      continue;
+    }
+    
+    TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+    if (TTP->isParameterPack())
+      Out << 'p';
+    Out << 't';
+    VisitTemplateParameterList(TTP->getTemplateParameters());
+  }
+}
+
+void USRGenerator::VisitTemplateName(TemplateName Name) {
+  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+    if (TemplateTemplateParmDecl *TTP
+                              = dyn_cast<TemplateTemplateParmDecl>(Template)) {
+      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
+      return;
+    }
+    
+    Visit(Template);
+    return;
+  }
+  
+  // FIXME: Visit dependent template names.
+}
+
+void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    break;
+
+  case TemplateArgument::Declaration:
+    Visit(Arg.getAsDecl());
+    break;
+
+  case TemplateArgument::NullPtr:
+    break;
+
+  case TemplateArgument::TemplateExpansion:
+    Out << 'P'; // pack expansion of...
+    // Fall through
+  case TemplateArgument::Template:
+    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
+    break;
+      
+  case TemplateArgument::Expression:
+    // FIXME: Visit expressions.
+    break;
+      
+  case TemplateArgument::Pack:
+    Out << 'p' << Arg.pack_size();
+    for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end();
+         P != PEnd; ++P)
+      VisitTemplateArgument(*P);
+    break;
+      
+  case TemplateArgument::Type:
+    VisitType(Arg.getAsType());
+    break;
+      
+  case TemplateArgument::Integral:
+    Out << 'V';
+    VisitType(Arg.getIntegralType());
+    Out << Arg.getAsIntegral();
+    break;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// General purpose USR generation methods.
+//===----------------------------------------------------------------------===//
+
+void USRGenerator::GenObjCClass(StringRef cls) {
+  Out << "objc(cs)" << cls;
+}
+
+void USRGenerator::GenObjCCategory(StringRef cls, StringRef cat) {
+  Out << "objc(cy)" << cls << '@' << cat;
+}
+
+void USRGenerator::GenObjCIvar(StringRef ivar) {
+  Out << '@' << ivar;
+}
+
+void USRGenerator::GenObjCMethod(StringRef meth, bool isInstanceMethod) {
+  Out << (isInstanceMethod ? "(im)" : "(cm)") << meth;
+}
+
+void USRGenerator::GenObjCProperty(StringRef prop) {
+  Out << "(py)" << prop;
+}
+
+void USRGenerator::GenObjCProtocol(StringRef prot) {
+  Out << "objc(pl)" << prot;
+}
+
+//===----------------------------------------------------------------------===//
+// API hooks.
+//===----------------------------------------------------------------------===//
+
+static inline StringRef extractUSRSuffix(StringRef s) {
+  return s.startswith("c:") ? s.substr(2) : "";
+}
+
+bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
+  // Don't generate USRs for things with invalid locations.
+  if (!D || D->getLocStart().isInvalid())
+    return true;
+
+  USRGenerator UG(&D->getASTContext(), &Buf);
+  UG->Visit(const_cast<Decl*>(D));
+
+  if (UG->ignoreResults())
+    return true;
+
+  return false;
+}
+
+extern "C" {
+
+CXString clang_getCursorUSR(CXCursor C) {
+  const CXCursorKind &K = clang_getCursorKind(C);
+
+  if (clang_isDeclaration(K)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return createCXString("");
+
+    CXTranslationUnit TU = cxcursor::getCursorTU(C);
+    if (!TU)
+      return createCXString("");
+
+    CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+    if (!buf)
+      return createCXString("");
+
+    bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
+    if (Ignore) {
+      disposeCXStringBuf(buf);
+      return createCXString("");
+    }
+
+    // Return the C-string, but don't make a copy since it is already in
+    // the string buffer.
+    buf->Data.push_back('\0');
+    return createCXString(buf);
+  }
+
+  if (K == CXCursor_MacroDefinition) {
+    CXTranslationUnit TU = cxcursor::getCursorTU(C);
+    if (!TU)
+      return createCXString("");
+
+    CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+    if (!buf)
+      return createCXString("");
+
+    {
+      USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
+                      &buf->Data);
+      UG << "macro@"
+        << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+    }
+    buf->Data.push_back('\0');
+    return createCXString(buf);
+  }
+
+  return createCXString("");
+}
+
+CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCIvar(name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCMethod(const char *name,
+                                       unsigned isInstanceMethod,
+                                       CXString classUSR) {
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCMethod(name, isInstanceMethod);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCClass(const char *name) {
+  USRGenerator UG;
+  UG->GenObjCClass(name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCProtocol(const char *name) {
+  USRGenerator UG;
+  UG->GenObjCProtocol(name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCCategory(const char *class_name,
+                                         const char *category_name) {
+  USRGenerator UG;
+  UG->GenObjCCategory(class_name, category_name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCProperty(const char *property,
+                                         CXString classUSR) {
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCProperty(property);
+  return createCXString(UG.str(), true);
+}
+
+} // end extern "C"
