Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-09-13 Thread Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL281355: ObjectiveC generics: Add ObjCTypeParamType in the 
type system. (authored by mren).

Changed prior to commit:
  https://reviews.llvm.org/D23079?vs=69764=71197#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D23079

Files:
  cfe/trunk/include/clang/AST/ASTContext.h
  cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
  cfe/trunk/include/clang/AST/Type.h
  cfe/trunk/include/clang/AST/TypeLoc.h
  cfe/trunk/include/clang/AST/TypeNodes.def
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/include/clang/Serialization/ASTBitCodes.h
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/ASTImporter.cpp
  cfe/trunk/lib/AST/ItaniumMangle.cpp
  cfe/trunk/lib/AST/Type.cpp
  cfe/trunk/lib/AST/TypeLoc.cpp
  cfe/trunk/lib/AST/TypePrinter.cpp
  cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
  cfe/trunk/lib/CodeGen/CGDebugInfo.h
  cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/lib/Sema/SemaType.cpp
  cfe/trunk/lib/Sema/TreeTransform.h
  cfe/trunk/lib/Serialization/ASTReader.cpp
  cfe/trunk/lib/Serialization/ASTWriter.cpp
  cfe/trunk/tools/libclang/CIndex.cpp

Index: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
===
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h
@@ -902,7 +902,9 @@
   /// \brief An AdjustedType record.
   TYPE_ADJUSTED  = 42,
   /// \brief A PipeType record.
-  TYPE_PIPE  = 43
+  TYPE_PIPE  = 43,
+  /// \brief An ObjCTypeParamType record.
+  TYPE_OBJC_TYPE_PARAM   = 44
 };
 
 /// \brief The type IDs for special types constructed by semantic
Index: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
===
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
@@ -1044,6 +1044,8 @@
 
 DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
 
+DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
+
 DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
 
 DEF_TRAVERSE_TYPE(ObjCObjectType, {
@@ -1275,6 +1277,8 @@
 DEF_TRAVERSE_TYPELOC(PackExpansionType,
  { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
 
+DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
+
 DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
 
 DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
Index: cfe/trunk/include/clang/AST/ASTContext.h
===
--- cfe/trunk/include/clang/AST/ASTContext.h
+++ cfe/trunk/include/clang/AST/ASTContext.h
@@ -114,6 +114,7 @@
   mutable llvm::FoldingSet DependentTypeOfExprTypes;
   mutable llvm::FoldingSet DependentDecltypeTypes;
   mutable llvm::FoldingSet TemplateTypeParmTypes;
+  mutable llvm::FoldingSet ObjCTypeParamTypes;
   mutable llvm::FoldingSet
 SubstTemplateTypeParmTypes;
   mutable llvm::FoldingSet
@@ -1328,6 +1329,10 @@
  ArrayRef typeArgs,
  ArrayRef protocols,
  bool isKindOf) const;
+
+  QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
+ArrayRef protocols,
+QualType Canonical = QualType()) const;
   
   bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
   /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
Index: cfe/trunk/include/clang/AST/TypeNodes.def
===
--- cfe/trunk/include/clang/AST/TypeNodes.def
+++ cfe/trunk/include/clang/AST/TypeNodes.def
@@ -101,6 +101,7 @@
 DEPENDENT_TYPE(DependentName, Type)
 DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
+NON_CANONICAL_TYPE(ObjCTypeParam, Type)
 TYPE(ObjCObject, Type)
 TYPE(ObjCInterface, ObjCObjectType)
 TYPE(ObjCObjectPointer, Type)
Index: cfe/trunk/include/clang/AST/Type.h
===
--- cfe/trunk/include/clang/AST/Type.h
+++ cfe/trunk/include/clang/AST/Type.h
@@ -88,6 +88,7 @@
   class ObjCInterfaceDecl;
   class ObjCProtocolDecl;
   class ObjCMethodDecl;
+  class ObjCTypeParamDecl;
   class UnresolvedUsingTypenameDecl;
   class Expr;
   class Stmt;
@@ -4752,6 +4753,49 @@
   }
 };
 
+/// Represents a type parameter type in Objective C. It can take
+/// a list of protocols.
+class ObjCTypeParamType : public Type,
+  public ObjCProtocolQualifiers,
+  public llvm::FoldingSetNode {
+  friend class ASTContext;
+  friend class ObjCProtocolQualifiers;
+
+  /// The number of protocols stored on this type.
+  unsigned NumProtocols : 6;
+
+  ObjCTypeParamDecl *OTPDecl;
+  /// The protocols are stored after the 

Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-09-12 Thread Doug Gregor via cfe-commits
doug.gregor accepted this revision.
doug.gregor added a comment.
This revision is now accepted and ready to land.

This looks great, thank you!


https://reviews.llvm.org/D23079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-09-09 Thread Manman Ren via cfe-commits
manmanren added a comment.

Hi Doug,

Can you take a look at the updated version?

Thanks,
Manman


https://reviews.llvm.org/D23079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-08-30 Thread Manman Ren via cfe-commits
manmanren updated this revision to Diff 69764.
manmanren added a comment.

Address Doug's comment. ObjCTypeParamType is a non-canonical type now, it is 
canonicalized to the underlying type with protocol qualifiers.


https://reviews.llvm.org/D23079

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Type.h
  include/clang/AST/TypeLoc.h
  include/clang/AST/TypeNodes.def
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -1534,6 +1534,18 @@
   return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
 }
 
+bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+  if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getLocStart(), TU)))
+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::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
   if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
 return true;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -450,6 +450,14 @@
   Code = TYPE_OBJC_INTERFACE;
 }
 
+void ASTTypeWriter::VisitObjCTypeParamType(const ObjCTypeParamType *T) {
+  Record.AddDeclRef(T->getDecl());
+  Record.push_back(T->getNumProtocols());
+  for (const auto *I : T->quals())
+Record.AddDeclRef(I);
+  Code = TYPE_OBJC_TYPE_PARAM;
+}
+
 void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
   Record.AddTypeRef(T->getBaseType());
   Record.push_back(T->getTypeArgsAsWritten().size());
@@ -587,6 +595,14 @@
 void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
   Record.AddSourceLocation(TL.getNameLoc());
 }
+void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+  if (TL.getNumProtocols()) {
+Record.AddSourceLocation(TL.getProtocolLAngleLoc());
+Record.AddSourceLocation(TL.getProtocolRAngleLoc());
+  }
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+Record.AddSourceLocation(TL.getProtocolLoc(i));
+}
 void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
   Record.AddSourceLocation(TL.getTypeofLoc());
   Record.AddSourceLocation(TL.getLParenLoc());
@@ -1066,6 +1082,7 @@
   RECORD(TYPE_ATOMIC);
   RECORD(TYPE_DECAYED);
   RECORD(TYPE_ADJUSTED);
+  RECORD(TYPE_OBJC_TYPE_PARAM);
   RECORD(LOCAL_REDECLARATIONS);
   RECORD(DECL_TYPEDEF);
   RECORD(DECL_TYPEALIAS);
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -5546,6 +5546,16 @@
 return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
   }
 
+  case TYPE_OBJC_TYPE_PARAM: {
+unsigned Idx = 0;
+ObjCTypeParamDecl *Decl
+  = ReadDeclAs(*Loc.F, Record, Idx);
+unsigned NumProtos = Record[Idx++];
+SmallVector Protos;
+for (unsigned I = 0; I != NumProtos; ++I)
+  Protos.push_back(ReadDeclAs(*Loc.F, Record, Idx));
+return Context.getObjCTypeParamType(Decl, Protos);
+  }
   case TYPE_OBJC_OBJECT: {
 unsigned Idx = 0;
 QualType Base = readType(*Loc.F, Record, Idx);
@@ -5944,6 +5954,15 @@
 void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   TL.setNameLoc(ReadSourceLocation(Record, Idx));
 }
+void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+  if (TL.getNumProtocols()) {
+TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));
+TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));
+  }
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
+}
+
 void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
   TL.setHasBaseTypeAsWritten(Record[Idx++]);
   TL.setTypeArgsLAngleLoc(ReadSourceLocation(Record, Idx));
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -699,6 +699,12 @@
   QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
 SourceLocation 

Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-08-23 Thread Doug Gregor via cfe-commits
doug.gregor added inline comments.


Comment at: include/clang/AST/RecursiveASTVisitor.h:1037
@@ -1036,1 +1036,3 @@
 
+DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
+

manmanren wrote:
> doug.gregor wrote:
> > I'm sorta shocked that we don't visit the protocol qualifiers here, but I 
> > guess we haven't been doing that for ObjCObjectType all along. Weird.
> Right below, we don't visit the protocol qualifiers for ObjCObjectType :]
> If you think we should, I can patch it up for both types.
Yes, I think we should.


Comment at: include/clang/AST/Type.h:4786
@@ +4785,3 @@
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+

manmanren wrote:
> doug.gregor wrote:
> > This is an interesting choice. Objective-C type parameters were treated 
> > like typedefs before, so they always act like their underlying type (e.g., 
> > because they are typedef name declarations). Why isn't ObjCTypeParamType 
> > sugar for the underlying type of the type parameter (I.e., the bound) w/ 
> > the protocol qualifiers?
> Are you suggesting to canonicalize ObjCTypeParamType to the underlying type 
> with the protocol qualifiers as well? Or just desugaring?
> 
> I think I have tried to set ObjCTypeParamType as NON_CANONICAL_TYPE in 
> TypeNodes.def, but had some issues.
Canonicalize to the underlying type + protocol qualifiers. We don't need the 
desugaring part.


https://reviews.llvm.org/D23079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-08-19 Thread Manman Ren via cfe-commits
manmanren added a comment.

Thanks for reviewing!

Manman



Comment at: include/clang/AST/RecursiveASTVisitor.h:1037
@@ -1036,1 +1036,3 @@
 
+DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
+

doug.gregor wrote:
> I'm sorta shocked that we don't visit the protocol qualifiers here, but I 
> guess we haven't been doing that for ObjCObjectType all along. Weird.
Right below, we don't visit the protocol qualifiers for ObjCObjectType :]
If you think we should, I can patch it up for both types.


Comment at: include/clang/AST/RecursiveASTVisitor.h:1270
@@ -1267,1 +1269,3 @@
 
+DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
+

doug.gregor wrote:
> Same shock at not visiting the protocol qualifiers here :)
Same here.


Comment at: include/clang/AST/Type.h:4786
@@ +4785,3 @@
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+

doug.gregor wrote:
> This is an interesting choice. Objective-C type parameters were treated like 
> typedefs before, so they always act like their underlying type (e.g., because 
> they are typedef name declarations). Why isn't ObjCTypeParamType sugar for 
> the underlying type of the type parameter (I.e., the bound) w/ the protocol 
> qualifiers?
Are you suggesting to canonicalize ObjCTypeParamType to the underlying type 
with the protocol qualifiers as well? Or just desugaring?

I think I have tried to set ObjCTypeParamType as NON_CANONICAL_TYPE in 
TypeNodes.def, but had some issues.


https://reviews.llvm.org/D23079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-08-19 Thread Doug Gregor via cfe-commits
doug.gregor requested changes to this revision.
doug.gregor added a comment.
This revision now requires changes to proceed.

A couple of comments above, but this is looking very good.



Comment at: include/clang/AST/RecursiveASTVisitor.h:1037
@@ -1036,1 +1036,3 @@
 
+DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
+

I'm sorta shocked that we don't visit the protocol qualifiers here, but I guess 
we haven't been doing that for ObjCObjectType all along. Weird.


Comment at: include/clang/AST/RecursiveASTVisitor.h:1270
@@ -1267,1 +1269,3 @@
 
+DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
+

Same shock at not visiting the protocol qualifiers here :)


Comment at: include/clang/AST/Type.h:4786
@@ +4785,3 @@
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+

This is an interesting choice. Objective-C type parameters were treated like 
typedefs before, so they always act like their underlying type (e.g., because 
they are typedef name declarations). Why isn't ObjCTypeParamType sugar for the 
underlying type of the type parameter (I.e., the bound) w/ the protocol 
qualifiers?


Comment at: include/clang/AST/TypeLoc.h:696
@@ -695,1 +695,3 @@
 
+struct ObjCTypeParamTypeLocInfo {
+  SourceLocation ProtocolLAngleLoc;

The angle bracket locations don't exist if you don't have any protocols, so you 
could conceivably put them into the extra local data.


Comment at: include/clang/Serialization/ASTBitCodes.h:906
@@ -906,1 +905,3 @@
+  TYPE_PIPE  = 43,
+  TYPE_OBJC_TYPE_PARAM   = 44
 };

Comment please, even if it's trivial.


Comment at: lib/AST/ItaniumMangle.cpp:2916
@@ +2915,3 @@
+  }
+  mangleSourceName(T->getDecl()->getIdentifier());
+}

This doesn't look right. Typedef names aren't mangled; we should mangle based 
on building the ObjCPointerType with the canonical type of 
T->getDecl()->getUnderlyingType() w/ the protocol qualifiers added to it.

That said, I don't think this case will ever come up, because you can't define 
something that would C++ mangling within an Objective-C @interface.


Comment at: lib/AST/MicrosoftMangle.cpp:2318
@@ +2317,3 @@
+ SourceRange Range) {
+  mangleType(T->getDecl()->getUnderlyingType(), Range);
+}

I'd expect this to have the same implementation as the Itanium one: the 
canonical type w/ the underlying type + protocol qualifiers. Again, I don't 
think this code path can ever get triggered.


https://reviews.llvm.org/D23079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)

2016-08-02 Thread Manman Ren via cfe-commits
manmanren created this revision.
manmanren added a reviewer: doug.gregor.
manmanren added a subscriber: cfe-commits.

This depends on https://reviews.llvm.org/D23078

ObjC generics: Add ObjCTypeParamType in the type system.

We also need to add ObjCTypeParamTypeLoc. ObjCTypeParamType supports the
representation of "T " where T is a type parameter. Before this,
we use TypedefType to represent the type parameter for ObjC.

ObjCTypeParamType has "ObjCTypeParamDecl *OTPDecl" and it extends from
ObjCProtocolQualifiers.

The last patch (patch #3) will start using this new type.

https://reviews.llvm.org/D23079

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Type.h
  include/clang/AST/TypeLoc.h
  include/clang/AST/TypeNodes.def
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -1534,6 +1534,18 @@
   return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
 }
 
+bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+  if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getLocStart(), TU)))
+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::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
   if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
 return true;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -450,6 +450,14 @@
   Code = TYPE_OBJC_INTERFACE;
 }
 
+void ASTTypeWriter::VisitObjCTypeParamType(const ObjCTypeParamType *T) {
+  Record.AddDeclRef(T->getDecl());
+  Record.push_back(T->getNumProtocols());
+  for (const auto *I : T->quals())
+Record.AddDeclRef(I);
+  Code = TYPE_OBJC_TYPE_PARAM;
+}
+
 void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
   Record.AddTypeRef(T->getBaseType());
   Record.push_back(T->getTypeArgsAsWritten().size());
@@ -587,6 +595,12 @@
 void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
   Record.AddSourceLocation(TL.getNameLoc());
 }
+void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+  Record.AddSourceLocation(TL.getProtocolLAngleLoc());
+  Record.AddSourceLocation(TL.getProtocolRAngleLoc());
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+Record.AddSourceLocation(TL.getProtocolLoc(i));
+}
 void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
   Record.AddSourceLocation(TL.getTypeofLoc());
   Record.AddSourceLocation(TL.getLParenLoc());
@@ -1066,6 +1080,7 @@
   RECORD(TYPE_ATOMIC);
   RECORD(TYPE_DECAYED);
   RECORD(TYPE_ADJUSTED);
+  RECORD(TYPE_OBJC_TYPE_PARAM);
   RECORD(LOCAL_REDECLARATIONS);
   RECORD(DECL_TYPEDEF);
   RECORD(DECL_TYPEALIAS);
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -5542,6 +5542,16 @@
 return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
   }
 
+  case TYPE_OBJC_TYPE_PARAM: {
+unsigned Idx = 0;
+ObjCTypeParamDecl *Decl
+  = ReadDeclAs(*Loc.F, Record, Idx);
+unsigned NumProtos = Record[Idx++];
+SmallVector Protos;
+for (unsigned I = 0; I != NumProtos; ++I)
+  Protos.push_back(ReadDeclAs(*Loc.F, Record, Idx));
+return Context.getObjCTypeParamType(Decl, Protos);
+  }
   case TYPE_OBJC_OBJECT: {
 unsigned Idx = 0;
 QualType Base = readType(*Loc.F, Record, Idx);
@@ -5940,6 +5950,13 @@
 void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   TL.setNameLoc(ReadSourceLocation(Record, Idx));
 }
+void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+  TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));
+  TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));