Re: [PATCH] D23079: ObjC: Use a new type for ObjC type parameter (patch 2 out of 3)
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)
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)
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)
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++]; +SmallVectorProtos; +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)
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)
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)
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)
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++]; +SmallVectorProtos; +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));