Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h	(revision 160944)
+++ include/clang/AST/Type.h	(working copy)
@@ -1008,7 +1008,18 @@
   friend class QualType;
   friend class Type;
   friend class ExtQuals;
+  friend class PlacementDummyType;
 };
+  
+class PlacementDummyType : public ExtQualsTypeCommonBase {
+  Type *this_() { return (Type *)this; }
+public:
+  PlacementDummyType(QualType canon)
+    : ExtQualsTypeCommonBase(this_(),
+                           canon.isNull() ? QualType(this_(), 0) : canon)
+  {
+  }
+};
 
 /// ExtQuals - We can encode up to four bits in the low bits of a
 /// type pointer, but there are many more type qualifiers that we want
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h	(revision 160944)
+++ include/clang/AST/ASTContext.h	(working copy)
@@ -673,6 +673,14 @@
   QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
 
 public:
+  /// getPlacementType - Return a type of the right size for placement new
+  template <typename PlacementType>
+  PlacementType *getPlacementType(QualType Canonical = QualType()) const{
+    void *Memory = Allocate(sizeof(PlacementType), TypeAlignment);
+    memset(Memory, 0, sizeof(PlacementType));
+    return (PlacementType *)new (Memory) PlacementDummyType(Canonical);
+  }
+
   /// getAddSpaceQualType - Return the uniqued reference to the type for an
   /// address space qualified type with the specified type and address space.
   /// The resulting type has a union of the qualifiers from T and the address
@@ -931,7 +939,8 @@
   QualType getTypeOfType(QualType t) const;
 
   /// getDecltypeType - C++0x decltype.
-  QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
+  QualType getDecltypeType(Expr *e, QualType UnderlyingType,
+                           void *Placement = 0) const;
 
   /// getUnaryTransformType - unary type transforms
   QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp	(revision 160944)
+++ lib/AST/ASTContext.cpp	(working copy)
@@ -3124,7 +3124,8 @@
 /// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
 /// an issue. This doesn't effect the type checker, since it operates
 /// on canonical types (which are always unique).
-QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
+QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType,
+                                     void *Placement) const {
   DecltypeType *dt;
   
   // C++0x [temp.type]p2:
@@ -3141,17 +3142,28 @@
     if (Canon) {
       // We already have a "canonical" version of an equivalent, dependent
       // decltype type. Use that as our canonical type.
-      dt = new (*this, TypeAlignment) DecltypeType(e, DependentTy,
-                                       QualType((DecltypeType*)Canon, 0));
+      if (Placement)
+        dt = new (Placement) DecltypeType(e, DependentTy,
+                                          QualType((DecltypeType*)Canon, 0));
+      else
+        dt = new (*this, TypeAlignment) DecltypeType(e, DependentTy,
+                                         QualType((DecltypeType*)Canon, 0));
     } else {
       // Build a new, canonical typeof(expr) type.
-      Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
+      if (Placement)
+        Canon = new (Placement) DependentDecltypeType(*this, e);
+      else
+        Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
       DependentDecltypeTypes.InsertNode(Canon, InsertPos);
       dt = Canon;
     }
   } else {
-    dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, 
-                                      getCanonicalType(UnderlyingType));
+    if (Placement)
+      dt = new (Placement) DecltypeType(e, UnderlyingType,
+                                        getCanonicalType(UnderlyingType));
+    else
+      dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
+                                              getCanonicalType(UnderlyingType));
   }
   Types.push_back(dt);
   return QualType(dt, 0);
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp	(revision 160944)
+++ lib/Serialization/ASTWriter.cpp	(working copy)
@@ -2135,6 +2135,10 @@
     TypeOffsets.resize(Index + 1);
     TypeOffsets[Index] = Stream.GetCurrentBitNo();
   }
+  else {
+    assert(false && "Types written in incorrect order");
+    TypeOffsets[Index] = Stream.GetCurrentBitNo();
+  }
 
   RecordData Record;
 
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp	(revision 160944)
+++ lib/Serialization/ASTReader.cpp	(working copy)
@@ -3945,8 +3945,21 @@
   }
 
   case TYPE_DECLTYPE: {
+    DependentDecltypeType *pTemp =
+      Context.getPlacementType<DependentDecltypeType>();
+    // Prevent recursive reads from loading this type again to stop
+    // the profile of the recursive decltype from accessing data that
+    // hasn't finished loading.
+    TypesLoaded[Index] = QualType(pTemp, 0);
+    
     QualType UnderlyingType = readType(*Loc.F, Record, Idx);
-    return Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType);
+    QualType T = Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType,
+                                         pTemp);
+    if (T.getTypePtrOrNull() != pTemp)
+      Context.Deallocate(pTemp);
+    TypesLoaded[Index] = QualType(); // Reset TypeLoaded so right logic is
+                                     // applied in GetType.
+    return T;
   }
 
   case TYPE_UNARY_TRANSFORM: {
@@ -4138,6 +4151,12 @@
     ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);
     QualType Underlying = readType(*Loc.F, Record, Idx);
     QualType T;
+    if (!TypesLoaded[Index].isNull()) {
+      // Type has been loaded recursively, so lets return it as is.
+      // Otherwise there will be two pointers to the same type referenced
+      // in different places.
+      return TypesLoaded[Index];
+    }
     if (Underlying.isNull())
       T = Context.getCanonicalTemplateSpecializationType(Name, Args.data(),
                                                           Args.size());
@@ -4477,8 +4496,17 @@
   Index -= NUM_PREDEF_TYPE_IDS;
   assert(Index < TypesLoaded.size() && "Type index out-of-range");
   if (TypesLoaded[Index].isNull()) {
-    TypesLoaded[Index] = readTypeRecord(Index);
+    QualType ReadType = readTypeRecord(Index);
     if (TypesLoaded[Index].isNull())
+      TypesLoaded[Index] = ReadType;
+    else
+    {
+      assert(ReadType == TypesLoaded[Index]
+             && "Different type pointers returned for recursive load");
+      // Type was loaded recursively, lets just return.
+      return TypesLoaded[Index].withFastQualifiers(FastQuals);
+    }
+    if (TypesLoaded[Index].isNull())
       return QualType();
 
     TypesLoaded[Index]->setFromAST();
Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp	(revision 160944)
+++ lib/Serialization/ASTWriterDecl.cpp	(working copy)
@@ -1699,6 +1699,12 @@
       DeclOffsets[Index].setLocation(Loc);
       DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
     }
+    else
+    {
+      assert(false && "Decls written in incorrect order");
+      DeclOffsets[Index].setLocation(Loc);
+      DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
+    }
     
     SourceManager &SM = Context.getSourceManager();
     if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
