diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 09fb9185095ed15a3b5a3aee23c47922479ce819..bcd22460a864bdf8540ab897b56291f5ff78fa06 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -82,7 +82,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
   mutable llvm::FoldingSet<ComplexType> ComplexTypes;
   mutable llvm::FoldingSet<PointerType> PointerTypes;
-  mutable llvm::FoldingSet<DecayedType> DecayedTypes;
+  mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
   mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
   mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
   mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
@@ -915,6 +915,14 @@ public:
     return CanQualType::CreateUnsafe(getPointerType((QualType) T));
   }
 
+  /// \brief Return the uniqued reference to a type adjusted from the original
+  /// type to a new type.
+  QualType getAdjustedType(QualType Orig, QualType New) const;
+  CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
+    return CanQualType::CreateUnsafe(
+        getAdjustedType((QualType)Orig, (QualType)New));
+  }
+
   /// \brief Return the uniqued reference to the decayed version of the given
   /// type.  Can only be called on array and function types which decay to
   /// pointer types.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index d09550f0e2c2ccc954d4ab3b5b291e5cb1bffb2a..3c615c3035f4991244979780a49d429ed441023c 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -874,6 +874,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, {
     TRY_TO(TraverseType(T->getPointeeType()));
   })
 
+DEF_TRAVERSE_TYPE(AdjustedType, {
+    TRY_TO(TraverseType(T->getOriginalType()));
+  })
+
 DEF_TRAVERSE_TYPE(DecayedType, {
     TRY_TO(TraverseType(T->getOriginalType()));
   })
@@ -1084,6 +1088,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType, {
     TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
   })
 
+DEF_TRAVERSE_TYPELOC(AdjustedType, {
+    TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
+  })
+
 DEF_TRAVERSE_TYPELOC(DecayedType, {
     TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
   })
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index fb829e4d41039a95ef9a83b095a44bdb6050e050..9e5507bcf7ebc1c56ed83c75107d9e6c7392d104 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1996,39 +1996,59 @@ public:
   static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
 };
 
-/// \brief Represents a pointer type decayed from an array or function type.
-class DecayedType : public Type, public llvm::FoldingSetNode {
-  QualType OriginalType;
-  QualType DecayedPointer;
+/// \brief Represents a type which was implicitly adjusted by the semantic
+/// engine for arbitrary reasons.  For example, array and function types can
+/// decay, and function types can have their calling conventions adjusted.
+class AdjustedType : public Type, public llvm::FoldingSetNode {
+  QualType OriginalTy;
+  QualType AdjustedTy;
 
-  DecayedType(QualType OriginalType, QualType DecayedPointer,
-              QualType CanonicalPtr)
-      : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(),
-             OriginalType->isInstantiationDependentType(),
-             OriginalType->isVariablyModifiedType(),
-             OriginalType->containsUnexpandedParameterPack()),
-        OriginalType(OriginalType), DecayedPointer(DecayedPointer) {
-    assert(isa<PointerType>(DecayedPointer));
-  }
+protected:
+  AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
+               QualType CanonicalPtr)
+      : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
+             OriginalTy->isInstantiationDependentType(),
+             OriginalTy->isVariablyModifiedType(),
+             OriginalTy->containsUnexpandedParameterPack()),
+        OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
 
   friend class ASTContext;  // ASTContext creates these.
 
 public:
-  QualType getDecayedType() const { return DecayedPointer; }
-  QualType getOriginalType() const { return OriginalType; }
-
-  QualType getPointeeType() const {
-    return cast<PointerType>(DecayedPointer)->getPointeeType();
-  }
+  QualType getOriginalType() const { return OriginalTy; }
+  QualType getAdjustedType() const { return AdjustedTy; }
 
   bool isSugared() const { return true; }
-  QualType desugar() const { return DecayedPointer; }
+  QualType desugar() const { return AdjustedTy; }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, OriginalType);
+    Profile(ID, OriginalTy, AdjustedTy);
   }
-  static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) {
-    ID.AddPointer(OriginalType.getAsOpaquePtr());
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
+    ID.AddPointer(Orig.getAsOpaquePtr());
+    ID.AddPointer(New.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
+  }
+};
+
+/// \brief Represents a pointer type decayed from an array or function type.
+class DecayedType : public AdjustedType {
+
+  DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
+      : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
+    assert(isa<PointerType>(getAdjustedType()));
+  }
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  QualType getDecayedType() const { return getAdjustedType(); }
+
+  QualType getPointeeType() const {
+    return cast<PointerType>(getDecayedType())->getPointeeType();
   }
 
   static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 8ddfac7ad373b40e0a68a2fba3dc1385b9d5abde..e080c428896faeec65b4738191b58d43c0c52907 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -978,12 +978,10 @@ inline TypeLoc TypeLoc::IgnoreParens() const {
 }
 
 
-struct DecayedLocInfo { }; // Nothing.
+struct AdjustedLocInfo { }; // Nothing.
 
-/// \brief Wrapper for source info for pointers decayed from arrays and
-/// functions.
-class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc,
-                                              DecayedType, DecayedLocInfo> {
+class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
+                                               AdjustedType, AdjustedLocInfo> {
 public:
   TypeLoc getOriginalLoc() const {
     return getInnerTypeLoc();
@@ -1004,12 +1002,17 @@ public:
   }
 
   unsigned getLocalDataSize() const {
-    // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique
+    // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
     // anyway.  TypeLocBuilder can't handle data sizes of 1.
     return 0;  // No data.
   }
 };
 
+/// \brief Wrapper for source info for pointers decayed from arrays and
+/// functions.
+class DecayedTypeLoc : public InheritingConcreteTypeLoc<
+                           AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
+};
 
 struct PointerLikeLocInfo {
   SourceLocation StarLoc;
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 3126f48c644a846f945fa760a61584d59c3a4cb9..3b2665bb88e04fe37dc41953ad5d3fb7509f4b29 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -81,7 +81,8 @@ TYPE(FunctionNoProto, FunctionType)
 DEPENDENT_TYPE(UnresolvedUsing, Type)
 NON_CANONICAL_TYPE(Paren, Type)
 NON_CANONICAL_TYPE(Typedef, Type)
-NON_CANONICAL_TYPE(Decayed, Type)
+NON_CANONICAL_TYPE(Adjusted, Type)
+NON_CANONICAL_TYPE(Decayed, AdjustedType)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 03d905054aea1983c504d262acae7a106c2eb55d..440e9a714d93763709983f770f4a989e7fafa7f8 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -841,7 +841,9 @@ namespace clang {
       /// \brief An AtomicType record.
       TYPE_ATOMIC                = 40,
       /// \brief A DecayedType record.
-      TYPE_DECAYED               = 41
+      TYPE_DECAYED               = 41,
+      /// \brief An AdjustedType record.
+      TYPE_ADJUSTED              = 42
     };
 
     /// \brief The type IDs for special types constructed by semantic
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 0528a58f894445da97e9b2b3887c7101bad76cbb..79b8770e0b7b6c5f2ae643eb226b90eee964e830 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1632,8 +1632,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
   }
   case Type::ObjCObject:
     return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
+  case Type::Adjusted:
   case Type::Decayed:
-    return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());
+    return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
   case Type::ObjCInterface: {
     const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
     const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -2163,14 +2164,29 @@ QualType ASTContext::getPointerType(QualType T) const {
   return QualType(New, 0);
 }
 
-QualType ASTContext::getDecayedType(QualType T) const {
-  assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");
-
+QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
   llvm::FoldingSetNodeID ID;
-  DecayedType::Profile(ID, T);
+  AdjustedType::Profile(ID, Orig, New);
   void *InsertPos = 0;
-  if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos))
-    return QualType(DT, 0);
+  AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (AT)
+    return QualType(AT, 0);
+
+  QualType Canonical = getCanonicalType(New);
+
+  // Get the new insert position for the node we care about.
+  AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  assert(AT == 0 && "Shouldn't be in the map!");
+
+  AT = new (*this, TypeAlignment)
+      AdjustedType(Type::Adjusted, Orig, New, Canonical);
+  Types.push_back(AT);
+  AdjustedTypes.InsertNode(AT, InsertPos);
+  return QualType(AT, 0);
+}
+
+QualType ASTContext::getDecayedType(QualType T) const {
+  assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");
 
   QualType Decayed;
 
@@ -2189,17 +2205,23 @@ QualType ASTContext::getDecayedType(QualType T) const {
   if (T->isFunctionType())
     Decayed = getPointerType(T);
 
+  llvm::FoldingSetNodeID ID;
+  AdjustedType::Profile(ID, T, Decayed);
+  void *InsertPos = 0;
+  AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (AT)
+    return QualType(AT, 0);
+
   QualType Canonical = getCanonicalType(Decayed);
 
   // Get the new insert position for the node we care about.
-  DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos);
-  assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+  AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  assert(AT == 0 && "Shouldn't be in the map!");
 
-  DecayedType *New =
-      new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
-  Types.push_back(New);
-  DecayedTypes.InsertNode(New, InsertPos);
-  return QualType(New, 0);
+  AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
+  Types.push_back(AT);
+  AdjustedTypes.InsertNode(AT, InsertPos);
+  return QualType(AT, 0);
 }
 
 /// getBlockPointerType - Return the uniqued reference to the type for
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index ff1aea8a98aff7063f8d93f4fcd030c412ab6d57..7f7221fc6ed1371b8a2c76f1202c5a0e3c049c63 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -51,6 +51,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
       QT = AT->desugar();
       continue;
     }
+    // ...or an adjusted type...
+    if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
+      QT = AT->desugar();
+      continue;
+    }
     // ... or an auto type.
     if (const AutoType *AT = dyn_cast<AutoType>(Ty)) {
       if (!AT->isSugared())
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index e16015b7c4ed0af56f58b536c84a10d156ee7b04..4292d358164f994f744485eff394a873c131c7f8 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -407,10 +407,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       return false;
     break;
   
+  case Type::Adjusted:
   case Type::Decayed:
     if (!IsStructurallyEquivalent(Context,
-                                  cast<DecayedType>(T1)->getPointeeType(),
-                                  cast<DecayedType>(T2)->getPointeeType()))
+                                  cast<AdjustedType>(T1)->getOriginalType(),
+                                  cast<AdjustedType>(T2)->getOriginalType()))
       return false;
     break;
 
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index f24a23d34c573ac6285f98d401956c84bad30fb1..e60eed9630c1d3eca41a0bf89fbc825522cc0516 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -251,6 +251,11 @@ void DeclInfo::fill() {
         TL = PointerTL.getPointeeLoc().getUnqualifiedLoc();
         continue;
       }
+      // Look through adjusted types.
+      if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) {
+        TL = ATL.getOriginalLoc();
+        continue;
+      }
       if (BlockPointerTypeLoc BlockPointerTL =
               TL.getAs<BlockPointerTypeLoc>()) {
         TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc();
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index db3ab9536eb34ce73ddc9a52ce5671b3fce0af2c..c75cf20eb38e29bffc646a1a887bd0418c559057 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2508,11 +2508,8 @@ unsigned FunctionDecl::getBuiltinID() const {
 /// based on its FunctionType.  This is the length of the ParamInfo array
 /// after it has been created.
 unsigned FunctionDecl::getNumParams() const {
-  const FunctionType *FT = getType()->castAs<FunctionType>();
-  if (isa<FunctionNoProtoType>(FT))
-    return 0;
-  return cast<FunctionProtoType>(FT)->getNumArgs();
-
+  const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>();
+  return FPT ? FPT->getNumArgs() : 0;
 }
 
 void FunctionDecl::setParams(ASTContext &C,
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 767f6620a29524aeebcce3d27cbae9118287f9bb..f024f4593ba11bb5e2d5000b1a27c1b80ea7b420 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -423,8 +423,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
     Ty = PT->getInnerType();
   }
 
-  if (isa<FunctionType>(Ty)) {
-    const FunctionType *AFT = Ty->getAs<FunctionType>();
+  if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
     const FunctionProtoType *FT = 0;
     if (D->hasWrittenPrototype())
       FT = dyn_cast<FunctionProtoType>(AFT);
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index ba67fad6489dda3615790d3f0ba2221a6d7d5815..e2d334b316db407433d821130fac70d10aa10275 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -833,6 +833,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
     switch (type->getTypeClass()) {
     case Type::Builtin:
     case Type::Complex:
+    case Type::Adjusted:
     case Type::Decayed:
     case Type::Pointer:
     case Type::BlockPointer:
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 7421bae7bf5435537e9f1af14bcbca4ae81de3aa..cbb8bc61313330515848f863a0189e53ab22a0b6 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -593,6 +593,9 @@ namespace {
     AutoType *VisitAttributedType(const AttributedType *T) {
       return Visit(T->getModifiedType());
     }
+    AutoType *VisitAdjustedType(const AdjustedType *T) {
+      return Visit(T->getOriginalType());
+    }
   };
 }
 
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 571e3db0289f2b318f3f9cde440154603bf7b3dd..082d027791fd866453a8641563b21a99d63eb223 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -204,6 +204,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
       NeedARCStrongQualifier = true;
       // Fall through
       
+    case Type::Adjusted:
     case Type::Decayed:
     case Type::Pointer:
     case Type::BlockPointer:
@@ -471,12 +472,21 @@ void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
   printAfter(T->getElementType(), OS);
 }
 
+void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
+  // Print the adjusted representation, otherwise the adjustment will be
+  // invisible.
+  printBefore(T->getAdjustedType(), OS);
+}
+void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
+  printAfter(T->getAdjustedType(), OS);
+}
+
 void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
   // Print as though it's a pointer.
-  printBefore(T->getDecayedType(), OS);
+  printAdjustedBefore(T, OS);
 }
 void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
-  printAfter(T->getDecayedType(), OS);
+  printAdjustedAfter(T, OS);
 }
 
 void TypePrinter::printDependentSizedArrayBefore(
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index fcb26f0da61531781162f93e8f6eded2ef7bf81a..451a6848bafc0cd284dabfe811188f610681d2f7 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2123,10 +2123,11 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
     return CreateType(cast<ComplexType>(Ty));
   case Type::Pointer:
     return CreateType(cast<PointerType>(Ty), Unit);
+  case Type::Adjusted:
   case Type::Decayed:
-    // Decayed types are just pointers in LLVM and DWARF.
+    // Decayed and adjusted types use the adjusted type in LLVM and DWARF.
     return CreateType(
-        cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit);
+        cast<PointerType>(cast<AdjustedType>(Ty)->getAdjustedType()), Unit);
   case Type::BlockPointer:
     return CreateType(cast<BlockPointerType>(Ty), Unit);
   case Type::Typedef:
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index c1dc0b3657f3247e95b0f5ce646bf0d13e44f492..ce2c9b05c47a1d8930552c316fd6aa146ada221c 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -1308,6 +1308,10 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
     case Type::ObjCObjectPointer:
       llvm_unreachable("type class is never variably-modified!");
 
+    case Type::Adjusted:
+      type = cast<AdjustedType>(ty)->getAdjustedType();
+      break;
+
     case Type::Decayed:
       type = cast<DecayedType>(ty)->getPointeeType();
       break;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index dd28bfcf7d2111f33cdc03b052d0ca4838009351..63ac15baeb6a0dda203672559677aa3efaccb73e 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1812,7 +1812,10 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
     }
   }
 
-  // FIXME: Adjust member function pointer calling conventions.
+  // Adjust the default free function calling convention to the default method
+  // calling convention.
+  if (T->isFunctionType())
+    adjustMemberFunctionCC(T, /*IsStatic=*/false);
 
   return Context.getMemberPointerType(T, Class.getTypePtr());
 }
@@ -3681,6 +3684,9 @@ namespace {
     void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
       fillAttributedTypeLoc(TL, Chunk.getAttrs());
     }
+    void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+      // nothing
+    }
     void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
       assert(Chunk.Kind == DeclaratorChunk::BlockPointer);
       TL.setCaretLoc(Chunk.Loc);
@@ -3836,6 +3842,10 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
       CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
     }
 
+    // FIXME: Ordering here?
+    while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())
+      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+
     DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL);
     CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
   }
@@ -4589,14 +4599,15 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) {
   const FunctionType *FT = T->castAs<FunctionType>();
   bool IsVariadic = (isa<FunctionProtoType>(FT) &&
                      cast<FunctionProtoType>(FT)->isVariadic());
-  CallingConv CC = FT->getCallConv();
 
   // Only adjust types with the default convention.  For example, on Windows we
   // should adjust a __cdecl type to __thiscall for instance methods, and a
   // __thiscall type to __cdecl for static methods.
-  CallingConv DefaultCC =
+  CallingConv CurCC = FT->getCallConv();
+  CallingConv FromCC =
       Context.getDefaultCallingConvention(IsVariadic, IsStatic);
-  if (CC != DefaultCC)
+  CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic);
+  if (CurCC != FromCC || FromCC == ToCC)
     return;
 
   // Check if there was an explicit attribute, but only look through parens.
@@ -4609,12 +4620,8 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) {
     R = AT->getModifiedType().IgnoreParens();
   }
 
-  // FIXME: This loses sugar.  This should probably be fixed with an implicit
-  // AttributedType node that adjusts the convention.
-  CC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic);
-  FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC));
-  FunctionTypeUnwrapper Unwrapped(*this, T);
-  T = Unwrapped.wrap(*this, FT);
+  FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(ToCC));
+  T = Context.getAdjustedType(T, QualType(FT, T.getQualifiers()));
 }
 
 /// Handle OpenCL image access qualifiers: read_only, write_only, read_write
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 44581fd4153320ab85a80ff5b09ea4469d70f983..e9cb95006fedfcd886cbd30c1d1e8723ed8b24ac 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -3664,6 +3664,13 @@ QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
   return TransformTypeSpecType(TLB, T);
 }
 
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
+                                                       AdjustedTypeLoc TL) {
+  // Adjustments applied during transformation are handled elsewhere.
+  return getDerived().TransformType(TLB, TL.getOriginalLoc());
+}
+
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
                                                       DecayedTypeLoc TL) {
@@ -3832,6 +3839,14 @@ TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
       return QualType();
   }
 
+  // If we had to adjust the pointee type when building a member pointer, make
+  // sure to push TypeLoc info for it.
+  const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
+  if (MPT && PointeeType != MPT->getPointeeType()) {
+    assert(isa<AdjustedType>(MPT->getPointeeType()));
+    TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
+  }
+
   MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
   NewTL.setSigilLoc(TL.getSigilLoc());
   NewTL.setClassTInfo(NewClsTInfo);
@@ -9391,8 +9406,8 @@ QualType
 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
                                                  QualType ClassType,
                                                  SourceLocation Sigil) {
-  return SemaRef.BuildMemberPointerType(PointeeType, ClassType,
-                                        Sigil, getDerived().getBaseEntity());
+  return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
+                                        getDerived().getBaseEntity());
 }
 
 template<typename Derived>
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 4d1b4b90b664291bccbece0b1ba1b2feb03c64bf..c531134a9748abca100e64c7a297e08172f344f7 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4548,6 +4548,16 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
     return DT;
   }
 
+  case TYPE_ADJUSTED: {
+    if (Record.size() != 2) {
+      Error("Incorrect encoding of adjusted type");
+      return QualType();
+    }
+    QualType OriginalTy = readType(*Loc.F, Record, Idx);
+    QualType AdjustedTy = readType(*Loc.F, Record, Idx);
+    return Context.getAdjustedType(OriginalTy, AdjustedTy);
+  }
+
   case TYPE_BLOCK_POINTER: {
     if (Record.size() != 1) {
       Error("Incorrect encoding of block pointer type");
@@ -4997,6 +5007,9 @@ void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
 void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
   // nothing to do
 }
+void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+  // nothing to do
+}
 void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
   TL.setCaretLoc(ReadSourceLocation(Record, Idx));
 }
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index fa5b83d98fbc51efe8bc25efc0e7e55552d0b94a..d8f170fd517c95af3dd38cc8b03b8eab9babca32 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -113,6 +113,12 @@ void ASTTypeWriter::VisitDecayedType(const DecayedType *T) {
   Code = TYPE_DECAYED;
 }
 
+void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) {
+  Writer.AddTypeRef(T->getOriginalType(), Record);
+  Writer.AddTypeRef(T->getAdjustedType(), Record);
+  Code = TYPE_ADJUSTED;
+}
+
 void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
   Writer.AddTypeRef(T->getPointeeType(), Record);
   Code = TYPE_BLOCK_POINTER;
@@ -455,6 +461,9 @@ void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
 void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
   // nothing to do
 }
+void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+  // nothing to do
+}
 void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
   Writer.AddSourceLocation(TL.getCaretLoc(), Record);
 }
diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp
index 2d52386add16ce3370cd55c6412d7c5735860da4..c55124c58050e43d2c7a6b8b5b3ba88cb585f64d 100644
--- a/test/SemaCXX/calling-conv-compat.cpp
+++ b/test/SemaCXX/calling-conv-compat.cpp
@@ -351,24 +351,25 @@ typedef void (__cdecl    fun_cdecl)();
 typedef void (__stdcall  fun_stdcall)();
 typedef void (__fastcall fun_fastcall)();
 
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//fun_default  A::*td1 = &A::method_thiscall;
-fun_cdecl    A::*td2 = &A::method_cdecl;
+fun_default  A::*td1 = &A::method_thiscall;
+fun_cdecl    A::*td2 = &A::method_thiscall;
 fun_stdcall  A::*td3 = &A::method_stdcall;
 fun_fastcall A::*td4 = &A::method_fastcall;
 
 // Round trip the function type through a template, and verify that only cdecl
 // gets adjusted.
-template<typename Fn> struct X {
-  typedef Fn A::*p;
-};
+template<typename Fn> struct X { typedef Fn A::*p; };
 
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//X<void            ()>::p tmpl1 = &A::method_thiscall;
-//X<void __cdecl    ()>::p tmpl2 = &A::method_thiscall;
+X<void            ()>::p tmpl1 = &A::method_thiscall;
+X<void __cdecl    ()>::p tmpl2 = &A::method_thiscall;
 X<void __stdcall  ()>::p tmpl3 = &A::method_stdcall;
 X<void __fastcall ()>::p tmpl4 = &A::method_fastcall;
 
+X<fun_default >::p tmpl5 = &A::method_thiscall;
+X<fun_cdecl   >::p tmpl6 = &A::method_thiscall;
+X<fun_stdcall >::p tmpl7 = &A::method_stdcall;
+X<fun_fastcall>::p tmpl8 = &A::method_fastcall;
+
 } // end namespace MemberPointers
 
 // Test that lambdas that capture nothing convert to cdecl function pointers.
diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp
index 9f1463245ba29c89b673a5cbd7df0104150e0874..fd20ae234ec53b0035815bafd8173f657c8bc0c2 100644
--- a/test/SemaCXX/decl-microsoft-call-conv.cpp
+++ b/test/SemaCXX/decl-microsoft-call-conv.cpp
@@ -191,3 +191,15 @@ namespace test5 {
   };
   extern template void valarray<int>::bar();
 }
+
+namespace test6 {
+  struct foo {
+    int bar();
+  };
+  typedef int bar_t();
+  void zed(bar_t foo::*) {
+  }
+  void baz() {
+    zed(&foo::bar);
+  }
+}
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index c7d3ea46494d02cc4710b959bcbcf2fde40d8c9d..656fbd1b1b7ff6737dc4e67a34c9d6388af9b98b 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1542,6 +1542,10 @@ bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
   return Visit(TL.getOriginalLoc());
 }
 
+bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+  return Visit(TL.getOriginalLoc());
+}
+
 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
                                              TemplateSpecializationTypeLoc TL) {
   // Visit the template name.
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
index 3ad5acbb041b211faac5974a16ab65531c74c5be..5907b1dd5a68125ff54ba8d08fcea171aff327f6 100644
--- a/tools/libclang/RecursiveASTVisitor.h
+++ b/tools/libclang/RecursiveASTVisitor.h
@@ -799,6 +799,10 @@ DEF_TRAVERSE_TYPE(DecayedType, {
     TRY_TO(TraverseType(T->getOriginalType()));
   })
 
+DEF_TRAVERSE_TYPE(AdjustedType, {
+    TRY_TO(TraverseType(T->getOriginalType()));
+  })
+
 DEF_TRAVERSE_TYPE(ConstantArrayType, {
     TRY_TO(TraverseType(T->getElementType()));
   })
@@ -1009,6 +1013,10 @@ DEF_TRAVERSE_TYPELOC(DecayedType, {
     TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
   })
 
+DEF_TRAVERSE_TYPELOC(AdjustedType, {
+    TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
+  })
+
 template<typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
   // This isn't available for ArrayType, but is for the ArrayTypeLoc.