<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Nice catch, thank you!<div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>- Doug</div><div class=""><br class=""><div style=""><blockquote type="cite" class=""><div class="">On Jul 8, 2015, at 11:32 AM, Justin Bogner <<a href="mailto:mail@justinbogner.com" class="">mail@justinbogner.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Douglas Gregor <</span><a href="mailto:dgregor@apple.com" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">dgregor@apple.com</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">> writes:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Author: dgregor<br class="">Date: Mon Jul  6 22:57:35 2015<br class="">New Revision: 241542<br class=""><br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D241542-26view-3Drev&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=w-3IguZwq-pNslBwo83yCF6WxeZADP2kdA3MiR0kpUk&e=" class="">http://llvm.org/viewvc/llvm-project?rev=241542&view=rev</a><br class="">Log:<br class="">Handle Objective-C type arguments.<br class=""><br class="">Objective-C type arguments can be provided in angle brackets following<br class="">an Objective-C interface type. Syntactically, this is the same<br class="">position as one would provide protocol qualifiers (e.g.,<br class="">id<NSCopying>), so parse both together and let Sema sort out the<br class="">ambiguous cases. This applies both when parsing types and when parsing<br class="">the superclass of an Objective-C class, which can now be a specialized<br class="">type (e.g., NSMutableArray<T> inherits from NSArray<T>).<br class=""><br class="">Check Objective-C type arguments against the type parameters of the<br class="">corresponding class. Verify the length of the type argument list and<br class="">that each type argument satisfies the corresponding bound.<br class=""><br class="">Specializations of parameterized Objective-C classes are represented<br class="">in the type system as distinct types. Both specialized types (e.g.,<br class="">NSArray<NSString *> *) and unspecialized types (NSArray *) are<br class="">represented, separately.<br class=""><br class="">Added:<br class="">   cfe/trunk/test/Index/annotate-parameterized-classes.m<br class="">   cfe/trunk/test/SemaObjCXX/parameterized_classes.mm<br class="">Modified:<br class="">   cfe/trunk/include/clang/AST/ASTContext.h<br class="">   cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br class="">   cfe/trunk/include/clang/AST/DeclObjC.h<br class="">   cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br class="">   cfe/trunk/include/clang/AST/Type.h<br class="">   cfe/trunk/include/clang/AST/TypeLoc.h<br class="">   cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br class="">   cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br class="">   cfe/trunk/include/clang/Parse/Parser.h<br class="">   cfe/trunk/include/clang/Sema/DeclSpec.h<br class="">   cfe/trunk/include/clang/Sema/Sema.h<br class="">   cfe/trunk/lib/AST/ASTContext.cpp<br class="">   cfe/trunk/lib/AST/ASTDiagnostic.cpp<br class="">   cfe/trunk/lib/AST/ASTImporter.cpp<br class="">   cfe/trunk/lib/AST/DeclObjC.cpp<br class="">   cfe/trunk/lib/AST/Type.cpp<br class="">   cfe/trunk/lib/AST/TypeLoc.cpp<br class="">   cfe/trunk/lib/AST/TypePrinter.cpp<br class="">   cfe/trunk/lib/Parse/ParseDecl.cpp<br class="">   cfe/trunk/lib/Parse/ParseObjc.cpp<br class="">   cfe/trunk/lib/Parse/ParseTentative.cpp<br class="">   cfe/trunk/lib/Sema/DeclSpec.cpp<br class="">   cfe/trunk/lib/Sema/SemaDeclObjC.cpp<br class="">   cfe/trunk/lib/Sema/SemaExpr.cpp<br class="">   cfe/trunk/lib/Sema/SemaExprObjC.cpp<br class="">   cfe/trunk/lib/Sema/SemaType.cpp<br class="">   cfe/trunk/lib/Serialization/ASTReader.cpp<br class="">   cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br class="">   cfe/trunk/lib/Serialization/ASTWriter.cpp<br class="">   cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br class="">   cfe/trunk/test/Index/complete-method-decls.m<br class="">   cfe/trunk/test/PCH/objc_parameterized_classes.m<br class="">   cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm<br class="">   cfe/trunk/test/SemaObjC/interface-1.m<br class="">   cfe/trunk/test/SemaObjC/parameterized_classes.m<br class="">   cfe/trunk/tools/libclang/CIndex.cpp<br class="">   cfe/trunk/tools/libclang/CursorVisitor.h<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/ASTContext.h<br class="">URL:<br class=""><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_AST_ASTContext.h-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=--kurmI9FZg9_T04KQs6gicWNEJA0px2xgc3SqZmruo&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/ASTContext.h (original)<br class="">+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jul  6 22:57:35 2015<br class="">@@ -236,6 +236,12 @@ class ASTContext : public RefCountedBase<br class="">  QualType ObjCClassRedefinitionType;<br class="">  QualType ObjCSelRedefinitionType;<br class=""><br class="">+  /// The identifier 'NSObject'.<br class="">+  IdentifierInfo *NSObjectName = nullptr;<br class="">+<br class="">+  /// The identifier 'NSCopying'.<br class="">+  IdentifierInfo *NSCopyingName = nullptr;<br class="">+<br class="">  QualType ObjCConstantStringType;<br class="">  mutable RecordDecl *CFConstantStringTypeDecl;<br class=""><br class="">@@ -1189,9 +1195,14 @@ public:<br class="">  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,<br class="">                                ObjCInterfaceDecl *PrevDecl = nullptr) const;<br class=""><br class="">+  /// Legacy interface: cannot provide type arguments.<br class="">  QualType getObjCObjectType(QualType Base,<br class="">                             ObjCProtocolDecl * const *Protocols,<br class="">                             unsigned NumProtocols) const;<br class="">+<br class="">+  QualType getObjCObjectType(QualType Base,<br class="">+                             ArrayRef<QualType> typeArgs,<br class="">+                             ArrayRef<ObjCProtocolDecl *> protocols) const;<br class=""><br class="">  bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);<br class="">  /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in<br class="">@@ -1351,6 +1362,24 @@ public:<br class="">    ObjCSelRedefinitionType = RedefType;<br class="">  }<br class=""><br class="">+  /// Retrieve the identifier 'NSObject'.<br class="">+  IdentifierInfo *getNSObjectName() {<br class="">+    if (!NSObjectName) {<br class="">+      NSObjectName = &Idents.get("NSObject");<br class="">+    }<br class="">+<br class="">+    return NSObjectName;<br class="">+  }<br class="">+<br class="">+  /// Retrieve the identifier 'NSCopying'.<br class="">+  IdentifierInfo *getNSCopyingName() {<br class="">+    if (!NSCopyingName) {<br class="">+      NSCopyingName = &Idents.get("NSCopying");<br class="">+    }<br class="">+<br class="">+    return NSCopyingName;<br class="">+  }<br class="">+<br class="">  /// \brief Retrieve the Objective-C "instancetype" type, if already known;<br class="">  /// otherwise, returns a NULL type;<br class="">  QualType getObjCInstanceType() {<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)<br class="">+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Mon Jul  6 22:57:35 2015<br class="">@@ -940,6 +940,8 @@ DEF_TRAVERSE_TYPE(ObjCObjectType, {<br class="">  // type is itself.<br class="">  if (T->getBaseType().getTypePtr() != T)<br class="">    TRY_TO(TraverseType(T->getBaseType()));<br class="">+  for (auto typeArg : T->getTypeArgsAsWritten())<br class="">+    TRY_TO(TraverseType(typeArg));<br class="">})<br class=""><br class="">DEF_TRAVERSE_TYPE(ObjCObjectPointerType,<br class="">@@ -1166,6 +1168,8 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectType, {<br class="">  // type is itself.<br class="">  if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())<br class="">    TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));<br class="">+  for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)<br class="">+    TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));<br class="">})<br class=""><br class="">DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,<br class="">@@ -1325,7 +1329,10 @@ DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {//<br class="">    for (auto typeParam : *typeParamList)<br class="">      TRY_TO(TraverseObjCTypeParamDecl(typeParam));<br class="">  }<br class="">-  return true;<br class="">+<br class="">+  if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {<br class="">+    TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));<br class="">+  }<br class="">})<br class=""><br class="">DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/DeclObjC.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/DeclObjC.h (original)<br class="">+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Jul  6 22:57:35 2015<br class="">@@ -794,9 +794,9 @@ class ObjCInterfaceDecl : public ObjCCon<br class="">    /// declaration.<br class="">    ObjCInterfaceDecl *Definition;<br class=""><br class="">-    /// Class's super class.<br class="">-    ObjCInterfaceDecl *SuperClass;<br class="">-<br class="">+    /// When non-null, this is always an ObjCObjectType.<br class="">+    TypeSourceInfo *SuperClassTInfo;<br class="">+    <br class="">    /// Protocols referenced in the \@interface  declaration<br class="">    ObjCProtocolList ReferencedProtocols;<br class=""><br class="">@@ -837,16 +837,13 @@ class ObjCInterfaceDecl : public ObjCCon<br class="">    };<br class="">    /// One of the \c InheritedDesignatedInitializersState enumeratos.<br class="">    mutable unsigned InheritedDesignatedInitializers : 2;<br class="">-<br class="">-    /// \brief The location of the superclass, if any.<br class="">-    SourceLocation SuperClassLoc;<br class=""><br class="">    /// \brief The location of the last location in this declaration, before<br class="">    /// the properties/methods. For example, this will be the '>', '}', or<span class="Apple-converted-space"> </span><br class="">    /// identifier,<span class="Apple-converted-space"> </span><br class="">    SourceLocation EndLoc;<span class="Apple-converted-space"> </span><br class=""><br class="">-    DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),<span class="Apple-converted-space"> </span><br class="">+    DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(),<span class="Apple-converted-space"> </span><br class="">                       ExternallyCompleted(),<br class="">                       IvarListMissingImplementation(true),<br class="">                       HasDesignatedInitializers(),<br class="">@@ -903,8 +900,8 @@ public:<br class="">  /// Retrieve the type parameters of this class.<br class="">  ///<br class="">  /// This function looks for a type parameter list for the given<br class="">-  /// class; if the class has been declared (with @class) but not<br class="">-  /// defined (with @interface), it will search for a declaration that<br class="">+  /// class; if the class has been declared (with \c \@class) but not<br class="">+  /// defined (with \c \@interface), it will search for a declaration that<br class="">  /// has type parameters, skipping any declarations that do not.<br class="">  ObjCTypeParamList *getTypeParamList() const;<br class=""><br class="">@@ -1160,7 +1157,16 @@ public:<br class="">  /// a forward declaration (\@class) to a definition (\@interface).<br class="">  void startDefinition();<br class=""><br class="">-  ObjCInterfaceDecl *getSuperClass() const {<br class="">+  /// Retrieve the superclass type.<br class="">+  const ObjCObjectType *getSuperClassType() const {<br class="">+    if (TypeSourceInfo *TInfo = getSuperClassTInfo())<br class="">+      return TInfo->getType()->castAs<ObjCObjectType>();<br class="">+<br class="">+    return nullptr;<br class="">+  }<br class="">+<br class="">+  // Retrieve the type source information for the superclass.<br class="">+  TypeSourceInfo *getSuperClassTInfo() const {<br class="">    // FIXME: Should make sure no callers ever do this.<br class="">    if (!hasDefinition())<br class="">      return nullptr;<br class="">@@ -1168,13 +1174,15 @@ public:<br class="">    if (data().ExternallyCompleted)<br class="">      LoadExternalDefinition();<br class=""><br class="">-    return data().SuperClass;<br class="">+    return data().SuperClassTInfo;<br class="">  }<br class=""><br class="">-  void setSuperClass(ObjCInterfaceDecl * superCls) {<span class="Apple-converted-space"> </span><br class="">-    data().SuperClass =<span class="Apple-converted-space"> </span><br class="">-      (superCls && superCls->hasDefinition()) ? superCls->getDefinition()<span class="Apple-converted-space"> </span><br class="">-                                              : superCls;<span class="Apple-converted-space"> </span><br class="">+  // Retrieve the declaration for the superclass of this class, which<br class="">+  // does not include any type arguments that apply to the superclass.<br class="">+  ObjCInterfaceDecl *getSuperClass() const;<br class="">+<br class="">+  void setSuperClass(TypeSourceInfo *superClass) {<span class="Apple-converted-space"> </span><br class="">+    data().SuperClassTInfo = superClass;<br class="">  }<br class=""><br class="">  /// \brief Iterator that walks over the list of categories, filtering out<br class="">@@ -1466,8 +1474,8 @@ public:<br class=""><br class="">  void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }<br class=""><br class="">-  void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }<br class="">-  SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }<br class="">+  /// Retrieve the starting location of the superclass.<br class="">+  SourceLocation getSuperClassLoc() const;<br class=""><br class="">  /// isImplicitInterfaceDecl - check that this is an implicitly declared<br class="">  /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br class="">+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jul  6 22:57:35 2015<br class="">@@ -1008,6 +1008,8 @@ DEF_TRAVERSE_TYPE(ObjCObjectType, {<br class="">  // type is itself.<br class="">  if (T->getBaseType().getTypePtr() != T)<br class="">    TRY_TO(TraverseType(T->getBaseType()));<br class="">+  for (auto typeArg : T->getTypeArgsAsWritten())<br class="">+    TRY_TO(TraverseType(typeArg));<br class="">})<br class=""><br class="">DEF_TRAVERSE_TYPE(ObjCObjectPointerType,<br class="">@@ -1234,6 +1236,8 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectType, {<br class="">  // type is itself.<br class="">  if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())<br class="">    TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));<br class="">+  for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)<br class="">+    TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));<br class="">})<br class=""><br class="">DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,<br class="">@@ -1399,6 +1403,10 @@ DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {//<br class="">    for (auto typeParam : *typeParamList)<br class="">      TRY_TO(TraverseObjCTypeParamDecl(typeParam));<br class="">  }<br class="">+<br class="">+  if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {<br class="">+    TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));<br class="">+  }<br class="">})<br class=""><br class="">DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/Type.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/Type.h (original)<br class="">+++ cfe/trunk/include/clang/AST/Type.h Mon Jul  6 22:57:35 2015<br class="">@@ -1288,10 +1288,14 @@ protected:<br class=""><br class="">    unsigned : NumTypeBits;<br class=""><br class="">+    /// The number of type arguments stored directly on this object type.<br class="">+    unsigned NumTypeArgs : 7;<br class="">+<br class="">    /// NumProtocols - The number of protocols stored directly on this<br class="">    /// object type.<br class="">-    unsigned NumProtocols : 32 - NumTypeBits;<br class="">+    unsigned NumProtocols : 7;<br class="">  };<br class="">+  static_assert(NumTypeBits + 7 + 7 <= 32, "Does not fit in an unsigned");<br class=""><br class="">  class ReferenceTypeBitfields {<br class="">    friend class ReferenceType;<br class="">@@ -1586,6 +1590,7 @@ public:<br class="">  bool isObjCObjectOrInterfaceType() const;<br class="">  bool isObjCIdType() const;                    // id<br class="">  bool isObjCClassType() const;                 // Class<br class="">+  bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const;<br class="">  bool isObjCSelType() const;                 // Class<br class="">  bool isObjCBuiltinType() const;               // 'id' or 'Class'<br class="">  bool isObjCARCBridgableType() const;<br class="">@@ -4369,19 +4374,25 @@ public:<br class="">};<br class=""><br class="">/// ObjCObjectType - Represents a class type in Objective C.<br class="">-/// Every Objective C type is a combination of a base type and a<br class="">-/// list of protocols.<br class="">+///<br class="">+/// Every Objective C type is a combination of a base type, a set of<br class="">+/// type arguments (optional, for parameterized classes) and a list of<br class="">+/// protocols.<br class="">///<br class="">/// Given the following declarations:<br class="">/// \code<br class="">-///   \@class C;<br class="">+///   \@class C<T>;<br class="">///   \@protocol P;<br class="">/// \endcode<br class="">///<br class="">/// 'C' is an ObjCInterfaceType C.  It is sugar for an ObjCObjectType<br class="">/// with base C and no protocols.<br class="">///<br class="">-/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].<br class="">+/// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P].<br class="">+/// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no<span class="Apple-converted-space"> </span><br class="">+/// protocol list.<br class="">+/// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*',<br class="">+/// and protocol list [P].<br class="">///<br class="">/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose<br class="">/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType<br class="">@@ -4391,8 +4402,10 @@ public:<br class="">/// with base BuiltinType::ObjCIdType and protocol list [P].  Eventually<br class="">/// this should get its own sugar class to better represent the source.<br class="">class ObjCObjectType : public Type {<br class="">-  // ObjCObjectType.NumProtocols - the number of protocols stored<br class="">+  // ObjCObjectType.NumTypeArgs - the number of type arguments stored<br class="">  // after the ObjCObjectPointerType node.<br class="">+  // ObjCObjectType.NumProtocols - the number of protocols stored<br class="">+  // after the type arguments of ObjCObjectPointerType node.<br class="">  //<br class="">  // These protocols are those written directly on the type.  If<br class="">  // protocol qualifiers ever become additive, the iterators will need<br class="">@@ -4408,17 +4421,24 @@ class ObjCObjectType : public Type {<br class="">    return const_cast<ObjCObjectType*>(this)->getProtocolStorage();<br class="">  }<br class=""><br class="">+  QualType *getTypeArgStorage();<br class="">+  const QualType *getTypeArgStorage() const {<br class="">+    return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();<br class="">+  }<br class="">+<br class="">  ObjCProtocolDecl **getProtocolStorage();<br class=""><br class="">protected:<br class="">  ObjCObjectType(QualType Canonical, QualType Base,<br class="">-                 ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);<br class="">+                 ArrayRef<QualType> typeArgs,<br class="">+                 ArrayRef<ObjCProtocolDecl *> protocols);<br class=""><br class="">  enum Nonce_ObjCInterface { Nonce_ObjCInterface };<br class="">  ObjCObjectType(enum Nonce_ObjCInterface)<br class="">        : Type(ObjCInterface, QualType(), false, false, false, false),<br class="">      BaseType(QualType(this_(), 0)) {<br class="">    ObjCObjectTypeBits.NumProtocols = 0;<br class="">+    ObjCObjectTypeBits.NumTypeArgs = 0;<br class="">  }<br class=""><br class="">public:<br class="">@@ -4452,6 +4472,33 @@ public:<br class="">  /// really is an interface.<br class="">  ObjCInterfaceDecl *getInterface() const;<br class=""><br class="">+  /// Determine whether this object type is "specialized", meaning<br class="">+  /// that it has type arguments.<br class="">+  bool isSpecialized() const;<br class="">+<br class="">+  /// Determine whether this object type was written with type arguments.<br class="">+  bool isSpecializedAsWritten() const {<span class="Apple-converted-space"> </span><br class="">+    return ObjCObjectTypeBits.NumTypeArgs > 0;<span class="Apple-converted-space"> </span><br class="">+  }<br class="">+<br class="">+  /// Determine whether this object type is "unspecialized", meaning<br class="">+  /// that it has no type arguments.<br class="">+  bool isUnspecialized() const { return !isSpecialized(); }<br class="">+<br class="">+  /// Determine whether this object type is "unspecialized" as<br class="">+  /// written, meaning that it has no type arguments.<br class="">+  bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }<br class="">+<br class="">+  /// Retrieve the type arguments of this object type (semantically).<br class="">+  ArrayRef<QualType> getTypeArgs() const;<br class="">+<br class="">+  /// Retrieve the type arguments of this object type as they were<br class="">+  /// written.<br class="">+  ArrayRef<QualType> getTypeArgsAsWritten() const {<span class="Apple-converted-space"> </span><br class="">+    return ArrayRef<QualType>(getTypeArgStorage(),<span class="Apple-converted-space"> </span><br class="">+                              ObjCObjectTypeBits.NumTypeArgs);<br class="">+  }<br class="">+<br class="">  typedef ObjCProtocolDecl * const *qual_iterator;<br class="">  typedef llvm::iterator_range<qual_iterator> qual_range;<br class=""><br class="">@@ -4491,21 +4538,25 @@ class ObjCObjectTypeImpl : public ObjCOb<br class="">  // will need to be modified.<br class=""><br class="">  ObjCObjectTypeImpl(QualType Canonical, QualType Base,<br class="">-                     ObjCProtocolDecl * const *Protocols,<br class="">-                     unsigned NumProtocols)<br class="">-    : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}<br class="">+                     ArrayRef<QualType> typeArgs,<br class="">+                     ArrayRef<ObjCProtocolDecl *> protocols)<br class="">+    : ObjCObjectType(Canonical, Base, typeArgs, protocols) {}<br class=""><br class="">public:<br class="">  void Profile(llvm::FoldingSetNodeID &ID);<br class="">  static void Profile(llvm::FoldingSetNodeID &ID,<br class="">                      QualType Base,<br class="">-                      ObjCProtocolDecl *const *protocols,<br class="">-                      unsigned NumProtocols);<br class="">+                      ArrayRef<QualType> typeArgs,<br class="">+                      ArrayRef<ObjCProtocolDecl *> protocols);<br class="">};<br class=""><br class="">+inline QualType *ObjCObjectType::getTypeArgStorage() {<br class="">+  return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);<br class="">+}<br class="">+<br class="">inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {<br class="">-  return reinterpret_cast<ObjCProtocolDecl**>(<br class="">-            static_cast<ObjCObjectTypeImpl*>(this) + 1);<br class="">+    return reinterpret_cast<ObjCProtocolDecl**>(<br class="">+             getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);<br class="">}<br class=""><br class="">/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for<br class="">@@ -4556,9 +4607,14 @@ public:<br class="">};<br class=""><br class="">inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {<br class="">-  if (const ObjCInterfaceType *T =<br class="">-        getBaseType()->getAs<ObjCInterfaceType>())<br class="">-    return T->getDecl();<br class="">+  QualType baseType = getBaseType();<br class="">+  while (const ObjCObjectType *ObjT = baseType->getAs<ObjCObjectType>()) {<br class="">+    if (const ObjCInterfaceType *T = dyn_cast<ObjCInterfaceType>(ObjT))<br class="">+      return T->getDecl();<br class="">+<br class="">+    baseType = ObjT->getBaseType();<br class="">+  }<br class="">+<br class="">  return nullptr;<br class="">}<br class=""><br class="">@@ -4653,6 +4709,31 @@ public:<br class="">    return getObjectType()->isObjCQualifiedClass();<br class="">  }<br class=""><br class="">+  /// Whether this type is specialized, meaning that it has type arguments.<br class="">+  bool isSpecialized() const { return getObjectType()->isSpecialized(); }<br class="">+<br class="">+  /// Whether this type is specialized, meaning that it has type arguments.<br class="">+  bool isSpecializedAsWritten() const {<span class="Apple-converted-space"> </span><br class="">+    return getObjectType()->isSpecializedAsWritten();<span class="Apple-converted-space"> </span><br class="">+  }<br class="">+  <br class="">+  /// Whether this type is unspecialized, meaning that is has no type arguments.<br class="">+  bool isUnspecialized() const { return getObjectType()->isUnspecialized(); }<br class="">+<br class="">+  /// Determine whether this object type is "unspecialized" as<br class="">+  /// written, meaning that it has no type arguments.<br class="">+  bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }<br class="">+<br class="">+  /// Retrieve the type arguments for this type.<br class="">+  ArrayRef<QualType> getTypeArgs() const {<span class="Apple-converted-space"> </span><br class="">+    return getObjectType()->getTypeArgs();<span class="Apple-converted-space"> </span><br class="">+  }<br class="">+<br class="">+  /// Retrieve the type arguments for this type.<br class="">+  ArrayRef<QualType> getTypeArgsAsWritten() const {<span class="Apple-converted-space"> </span><br class="">+    return getObjectType()->getTypeArgsAsWritten();<span class="Apple-converted-space"> </span><br class="">+  }<br class="">+<br class="">  /// An iterator over the qualifiers on the object type.  Provided<br class="">  /// for convenience.  This will always iterate over the full set of<br class="">  /// protocols on a type, not just those provided directly.<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/TypeLoc.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/TypeLoc.h (original)<br class="">+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Jul  6 22:57:35 2015<br class="">@@ -799,9 +799,11 @@ public:<br class="">};<br class=""><br class=""><br class="">-struct ObjCProtocolListLocInfo {<br class="">-  SourceLocation LAngleLoc;<br class="">-  SourceLocation RAngleLoc;<br class="">+struct ObjCObjectTypeLocInfo {<br class="">+  SourceLocation TypeArgsLAngleLoc;<br class="">+  SourceLocation TypeArgsRAngleLoc;<br class="">+  SourceLocation ProtocolLAngleLoc;<br class="">+  SourceLocation ProtocolRAngleLoc;<br class="">  bool HasBaseTypeAsWritten;<br class="">};<br class=""><br class="">@@ -813,25 +815,59 @@ struct ObjCProtocolListLocInfo {<br class="">class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,<br class="">                                                 ObjCObjectTypeLoc,<br class="">                                                 ObjCObjectType,<br class="">-                                                 ObjCProtocolListLocInfo> {<br class="">-  // SourceLocations are stored after Info, one for each Protocol.<br class="">+                                                 ObjCObjectTypeLocInfo> {<br class="">+  // TypeSourceInfo*'s are stored after Info, one for each type argument.<br class="">+  TypeSourceInfo **getTypeArgLocArray() const {<br class="">+    return (TypeSourceInfo**)this->getExtraLocalData();<br class="">+  }<br class="">+<br class="">+  // SourceLocations are stored after the type argument information, one for<span class="Apple-converted-space"> </span><br class="">+  // each Protocol.<br class="">  SourceLocation *getProtocolLocArray() const {<br class="">-    return (SourceLocation*) this->getExtraLocalData();<br class="">+    return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());<br class="">  }<br class=""><br class="">public:<br class="">-  SourceLocation getLAngleLoc() const {<br class="">-    return this->getLocalData()->LAngleLoc;<br class="">+  SourceLocation getTypeArgsLAngleLoc() const {<br class="">+    return this->getLocalData()->TypeArgsLAngleLoc;<br class="">+  }<br class="">+  void setTypeArgsLAngleLoc(SourceLocation Loc) {<br class="">+    this->getLocalData()->TypeArgsLAngleLoc = Loc;<br class="">+  }<br class="">+<br class="">+  SourceLocation getTypeArgsRAngleLoc() const {<br class="">+    return this->getLocalData()->TypeArgsRAngleLoc;<br class="">+  }<br class="">+  void setTypeArgsRAngleLoc(SourceLocation Loc) {<br class="">+    this->getLocalData()->TypeArgsRAngleLoc = Loc;<br class="">  }<br class="">-  void setLAngleLoc(SourceLocation Loc) {<br class="">-    this->getLocalData()->LAngleLoc = Loc;<br class="">+<br class="">+  unsigned getNumTypeArgs() const {<br class="">+    return this->getTypePtr()->getTypeArgsAsWritten().size();<br class="">  }<br class=""><br class="">-  SourceLocation getRAngleLoc() const {<br class="">-    return this->getLocalData()->RAngleLoc;<br class="">+  TypeSourceInfo *getTypeArgTInfo(unsigned i) const {<br class="">+    assert(i < getNumTypeArgs() && "Index is out of bounds!");<br class="">+    return getTypeArgLocArray()[i];<br class="">  }<br class="">-  void setRAngleLoc(SourceLocation Loc) {<br class="">-    this->getLocalData()->RAngleLoc = Loc;<br class="">+<br class="">+  void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {<br class="">+    assert(i < getNumTypeArgs() && "Index is out of bounds!");<br class="">+    getTypeArgLocArray()[i] = TInfo;<br class="">+  }<br class="">+<br class="">+  SourceLocation getProtocolLAngleLoc() const {<br class="">+    return this->getLocalData()->ProtocolLAngleLoc;<br class="">+  }<br class="">+  void setProtocolLAngleLoc(SourceLocation Loc) {<br class="">+    this->getLocalData()->ProtocolLAngleLoc = Loc;<br class="">+  }<br class="">+<br class="">+  SourceLocation getProtocolRAngleLoc() const {<br class="">+    return this->getLocalData()->ProtocolRAngleLoc;<br class="">+  }<br class="">+  void setProtocolRAngleLoc(SourceLocation Loc) {<br class="">+    this->getLocalData()->ProtocolRAngleLoc = Loc;<br class="">  }<br class=""><br class="">  unsigned getNumProtocols() const {<br class="">@@ -865,23 +901,26 @@ public:<br class="">  }<br class=""><br class="">  SourceRange getLocalSourceRange() const {<br class="">-    return SourceRange(getLAngleLoc(), getRAngleLoc());<br class="">+    SourceLocation start = getTypeArgsLAngleLoc();<br class="">+    if (start.isInvalid())<br class="">+      start = getProtocolLAngleLoc();<br class="">+    SourceLocation end = getProtocolRAngleLoc();<br class="">+    if (end.isInvalid())<br class="">+      end = getTypeArgsRAngleLoc();<br class="">+    return SourceRange(start, end);<br class="">  }<br class=""><br class="">-  void initializeLocal(ASTContext &Context, SourceLocation Loc) {<br class="">-    setHasBaseTypeAsWritten(true);<br class="">-    setLAngleLoc(Loc);<br class="">-    setRAngleLoc(Loc);<br class="">-    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)<br class="">-      setProtocolLoc(i, Loc);<br class="">-  }<br class="">+  void initializeLocal(ASTContext &Context, SourceLocation Loc);<br class=""><br class="">  unsigned getExtraLocalDataSize() const {<br class="">-    return this->getNumProtocols() * sizeof(SourceLocation);<br class="">+    return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)<br class="">+         + this->getNumProtocols() * sizeof(SourceLocation);<br class="">  }<br class=""><br class="">  unsigned getExtraLocalDataAlignment() const {<br class="">-    return llvm::alignOf<SourceLocation>();<br class="">+    static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),<br class="">+                  "not enough alignment for tail-allocated data");<br class="">+    return llvm::alignOf<TypeSourceInfo *>();<br class="">  }<br class=""><br class="">  QualType getInnerType() const {<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)<br class="">+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Jul  6 22:57:35 2015<br class="">@@ -1022,12 +1022,11 @@ let CategoryName = "Generics Issue" in {<br class="">def err_objc_expected_type_parameter : Error<<br class="">  "expected type parameter name">;<br class=""><br class="">-def err_objc_parameterized_class_without_base : Error<<br class="">-  "parameterized Objective-C class %0 must have a superclass">;<br class="">-<br class="">def err_objc_parameterized_implementation : Error<<br class="">  "@implementation cannot have type parameters">;<br class=""><br class="">+def err_objc_type_args_after_protocols : Error<<br class="">+  "protocol qualifiers must precede type arguments">;<br class="">}<br class=""><br class="">} // end of Parser diagnostics<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br class="">+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jul  6 22:57:35 2015<br class="">@@ -7780,6 +7780,36 @@ def err_objc_parameterized_forward_class<br class="">def err_objc_parameterized_forward_class_first : Error<<br class="">  "class %0 previously declared with type parameters">;<br class=""><br class="">+def err_objc_type_arg_missing_star : Error<<br class="">+  "type argument %0 must be a pointer (requires a '*')">;<br class="">+<br class="">+def err_objc_type_arg_missing : Error<<br class="">+  "no type or protocol named %0">;<br class="">+<br class="">+def err_objc_protocol_suggest : Error<<br class="">+  "no protocol named %0: did you mean %1?">;<br class="">+<br class="">+def err_objc_type_args_and_protocols : Error<<br class="">+  "angle brackets contain both a %select{type|protocol}0 (%1) and a "<br class="">+  "%select{protocol|type}0 (%2)">;<br class="">+<br class="">+def err_objc_type_args_non_class : Error<<br class="">+  "type arguments cannot be applied to non-class type %0">;<br class="">+<br class="">+def err_objc_type_args_non_parameterized_class : Error<<br class="">+  "type arguments cannot be applied to non-parameterized class %0">;<br class="">+<br class="">+def err_objc_type_args_specialized_class : Error<<br class="">+  "type arguments cannot be applied to already-specialized class type %0">;<br class="">+<br class="">+def err_objc_type_args_wrong_arity : Error<<br class="">+  "too %select{many|few}0 type arguments for class %1 (have %2, expected %3)">;<br class="">}<br class=""><br class="">+def err_objc_type_arg_not_id_compatible : Error<<br class="">+  "type argument %0 is neither an Objective-C object nor a block type">;<br class="">+<br class="">+def err_objc_type_arg_does_not_match_bound : Error<<br class="">+  "type argument %0 does not satisy the bound (%1) of type parameter %2">;<br class="">+<br class="">} // end of sema component.<br class=""><br class="">Modified: cfe/trunk/include/clang/Parse/Parser.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Parse/Parser.h (original)<br class="">+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jul  6 22:57:35 2015<br class="">@@ -1269,6 +1269,8 @@ private:<br class="">                                   SourceLocation &LAngleLoc,<br class="">                                   SourceLocation &EndProtoLoc);<br class="">  bool ParseObjCProtocolQualifiers(DeclSpec &DS);<br class="">+  void ParseObjCTypeArgsOrProtocolQualifiers(DeclSpec &DS,<br class="">+                                             bool warnOnIncompleteProtocols);<br class="">  void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,<br class="">                                  Decl *CDecl);<br class="">  DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,<br class=""><br class="">Modified: cfe/trunk/include/clang/Sema/DeclSpec.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)<br class="">+++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon Jul  6 22:57:35 2015<br class="">@@ -373,6 +373,14 @@ private:<br class="">  // Scope specifier for the type spec, if applicable.<br class="">  CXXScopeSpec TypeScope;<br class=""><br class="">+  /// List of Objective-C type arguments, e.g., in \c NSArray<NSView *>.<br class="">+  ArrayRef<ParsedType> ObjCTypeArgs;<br class="">+<br class="">+  /// Location of the '<' that starts a list of Objective-C type arguments.<br class="">+  SourceLocation ObjCTypeArgsLAngleLoc;<br class="">+  /// Location of the '>' that ends a list of Objective-C type arguments.<br class="">+  SourceLocation ObjCTypeArgsRAngleLoc;<br class="">+<br class="">  // List of protocol qualifiers for objective-c classes.  Used for<br class="">  // protocol-qualified interfaces "NString<foo>" and protocol-qualified id<br class="">  // "id<foo>".<br class="">@@ -449,6 +457,7 @@ public:<br class="">      ObjCQualifiers(nullptr) {<br class="">  }<br class="">  ~DeclSpec() {<br class="">+    delete [] ObjCTypeArgs.data();<br class="">    delete [] ProtocolQualifiers;<br class="">    delete [] ProtocolLocs;<br class="">  }<br class="">@@ -751,6 +760,25 @@ public:<br class="">    Attrs.takeAllFrom(attrs);<br class="">  }<br class=""><br class="">+  /// Determine whether the declaration specifiers contain Objective-C<br class="">+  /// type arguments.<br class="">+  bool hasObjCTypeArgs() const { return !ObjCTypeArgs.empty(); }<br class="">+<br class="">+  ArrayRef<ParsedType> getObjCTypeArgs() const { return ObjCTypeArgs; }<br class="">+  SourceLocation getObjCTypeArgsLAngleLoc() const {<br class="">+    return ObjCTypeArgsLAngleLoc;<br class="">+  }<br class="">+  SourceLocation getObjCTypeArgsRAngleLoc() const {<br class="">+    return ObjCTypeArgsRAngleLoc;<br class="">+  }<br class="">+  SourceRange getObjCTypeArgsRange() const {<br class="">+    return SourceRange(ObjCTypeArgsLAngleLoc, ObjCTypeArgsRAngleLoc);<br class="">+  }<br class="">+<br class="">+  void setObjCTypeArgs(SourceLocation lAngleLoc,<br class="">+                       ArrayRef<ParsedType> args,<br class="">+                       SourceLocation rAngleLoc);<br class="">+<br class="">  typedef Decl * const *ProtocolQualifierListTy;<br class="">  ProtocolQualifierListTy getProtocolQualifiers() const {<br class="">    return ProtocolQualifiers;<br class=""><br class="">Modified: cfe/trunk/include/clang/Sema/Sema.h<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Sema/Sema.h (original)<br class="">+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul  6 22:57:35 2015<br class="">@@ -7098,17 +7098,30 @@ public:<br class="">                                            SourceLocation rAngleLoc);<br class="">  void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList);<br class=""><br class="">-  Decl *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,<br class="">+  Decl *ActOnStartClassInterface(Scope *S,<br class="">+                                 SourceLocation AtInterfaceLoc,<br class="">                                 IdentifierInfo *ClassName,<br class="">                                 SourceLocation ClassLoc,<br class="">                                 ObjCTypeParamList *typeParamList,<br class="">                                 IdentifierInfo *SuperName,<br class="">                                 SourceLocation SuperLoc,<br class="">+                                 ArrayRef<ParsedType> SuperTypeArgs,<br class="">+                                 SourceRange SuperTypeArgsRange,<br class="">                                 Decl * const *ProtoRefs,<br class="">                                 unsigned NumProtoRefs,<br class="">                                 const SourceLocation *ProtoLocs,<br class="">                                 SourceLocation EndProtoLoc,<br class="">                                 AttributeList *AttrList);<br class="">+    <br class="">+  void ActOnSuperClassOfClassInterface(Scope *S,<br class="">+                                       SourceLocation AtInterfaceLoc,<br class="">+                                       ObjCInterfaceDecl *IDecl,<br class="">+                                       IdentifierInfo *ClassName,<br class="">+                                       SourceLocation ClassLoc,<br class="">+                                       IdentifierInfo *SuperName,<br class="">+                                       SourceLocation SuperLoc,<br class="">+                                       ArrayRef<ParsedType> SuperTypeArgs,<br class="">+                                       SourceRange SuperTypeArgsRange);<br class=""><br class="">  void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,<br class="">                               IdentifierInfo *SuperName,<br class="">@@ -7174,6 +7187,19 @@ public:<br class="">                               unsigned NumProtocols,<br class="">                               SmallVectorImpl<Decl *> &Protocols);<br class=""><br class="">+  /// Given a list of identifiers (and their locations), resolve the<br class="">+  /// names to either Objective-C protocol qualifiers or type<br class="">+  /// arguments, as appropriate. The result will be attached to the<br class="">+  /// given declaration specifiers.<br class="">+  void actOnObjCTypeArgsOrProtocolQualifiers(<br class="">+         Scope *S,<br class="">+         DeclSpec &DS,<br class="">+         SourceLocation lAngleLoc,<br class="">+         ArrayRef<IdentifierInfo *> identifiers,<br class="">+         ArrayRef<SourceLocation> identifierLocs,<br class="">+         SourceLocation rAngleLoc,<br class="">+         bool warnOnIncompleteProtocols);<br class="">+<br class="">  /// Ensure attributes are consistent with type.<br class="">  /// \param [in, out] Attributes The attributes to check; they will<br class="">  /// be modified to be consistent with \p PropertyTy.<br class=""><br class="">Modified: cfe/trunk/lib/AST/ASTContext.cpp<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br class="">+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -3618,45 +3618,85 @@ static void SortAndUniqueProtocols(ObjCP<br class="">QualType ASTContext::getObjCObjectType(QualType BaseType,<br class="">                                       ObjCProtocolDecl * const *Protocols,<br class="">                                       unsigned NumProtocols) const {<br class="">-  // If the base type is an interface and there aren't any protocols<br class="">-  // to add, then the interface type will do just fine.<br class="">-  if (!NumProtocols && isa<ObjCInterfaceType>(BaseType))<br class="">-    return BaseType;<br class="">+  return getObjCObjectType(BaseType, { },<br class="">+                           llvm::makeArrayRef(Protocols, NumProtocols));<br class="">+}<br class="">+<br class="">+QualType ASTContext::getObjCObjectType(<br class="">+           QualType baseType,<br class="">+           ArrayRef<QualType> typeArgs,<br class="">+           ArrayRef<ObjCProtocolDecl *> protocols) const {<br class="">+  // If the base type is an interface and there aren't any protocols or<br class="">+  // type arguments to add, then the interface type will do just fine.<br class="">+  if (typeArgs.empty() && protocols.empty() && isa<ObjCInterfaceType>(baseType))<br class="">+    return baseType;<br class=""><br class="">  // Look in the folding set for an existing type.<br class="">  llvm::FoldingSetNodeID ID;<br class="">-  ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);<br class="">+  ObjCObjectTypeImpl::Profile(ID, baseType, typeArgs, protocols);<br class="">  void *InsertPos = nullptr;<br class="">  if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))<br class="">    return QualType(QT, 0);<br class=""><br class="">-  // Build the canonical type, which has the canonical base type and<br class="">-  // a sorted-and-uniqued list of protocols.<br class="">-  QualType Canonical;<br class="">-  bool ProtocolsSorted = areSortedAndUniqued(Protocols, NumProtocols);<br class="">-  if (!ProtocolsSorted || !BaseType.isCanonical()) {<br class="">-    if (!ProtocolsSorted) {<br class="">-      SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols,<br class="">-                                                     Protocols + NumProtocols);<br class="">-      unsigned UniqueCount = NumProtocols;<br class="">-<br class="">-      SortAndUniqueProtocols(&Sorted[0], UniqueCount);<br class="">-      Canonical = getObjCObjectType(getCanonicalType(BaseType),<br class="">-                                    &Sorted[0], UniqueCount);<br class="">+  // Determine the type arguments to be used for canonicalization,<br class="">+  // which may be explicitly specified here or written on the base<br class="">+  // type.<br class="">+  ArrayRef<QualType> effectiveTypeArgs = typeArgs;<br class="">+  if (effectiveTypeArgs.empty()) {<br class="">+    if (auto baseObject = baseType->getAs<ObjCObjectType>())<br class="">+      effectiveTypeArgs = baseObject->getTypeArgs();<br class="">+  }<br class="">+<br class="">+  // Build the canonical type, which has the canonical base type and a<br class="">+  // sorted-and-uniqued list of protocols and the type arguments<br class="">+  // canonicalized.<br class="">+  QualType canonical;<br class="">+  bool typeArgsAreCanonical = std::all_of(effectiveTypeArgs.begin(),<br class="">+                                          effectiveTypeArgs.end(),<br class="">+                                          [&](QualType type) {<br class="">+                                            return type.isCanonical();<br class="">+                                          });<br class="">+  bool protocolsSorted = areSortedAndUniqued(protocols.data(),<br class="">+                                             protocols.size());<br class="">+  if (!typeArgsAreCanonical || !protocolsSorted || !baseType.isCanonical()) {<br class="">+    // Determine the canonical type arguments.<br class="">+    ArrayRef<QualType> canonTypeArgs;<br class="">+    SmallVector<QualType, 4> canonTypeArgsVec;<br class="">+    if (!typeArgsAreCanonical) {<br class="">+      canonTypeArgsVec.reserve(effectiveTypeArgs.size());<br class="">+      for (auto typeArg : effectiveTypeArgs)<br class="">+        canonTypeArgsVec.push_back(getCanonicalType(typeArg));<br class="">+      canonTypeArgs = canonTypeArgsVec;<br class="">    } else {<br class="">-      Canonical = getObjCObjectType(getCanonicalType(BaseType),<br class="">-                                    Protocols, NumProtocols);<br class="">+      canonTypeArgs = effectiveTypeArgs;<br class="">    }<br class=""><br class="">+    ArrayRef<ObjCProtocolDecl *> canonProtocols;<br class="">+    SmallVector<ObjCProtocolDecl*, 8> canonProtocolsVec;<br class="">+    if (!protocolsSorted) {<br class="">+      canonProtocolsVec.insert(canonProtocolsVec.begin(),<br class="">+                               protocols.begin(),<span class="Apple-converted-space"> </span><br class="">+                               protocols.end());<br class="">+      unsigned uniqueCount = protocols.size();<br class="">+      SortAndUniqueProtocols(&canonProtocolsVec[0], uniqueCount);<br class="">+      canonProtocols = llvm::makeArrayRef(&canonProtocolsVec[0], uniqueCount);<br class="">+    } else {<br class="">+      canonProtocols = protocols;<br class="">+    }<br class="">+<br class="">+    canonical = getObjCObjectType(getCanonicalType(baseType), canonTypeArgs,<br class="">+                                  canonProtocols);<br class="">+<br class="">    // Regenerate InsertPos.<br class="">    ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos);<br class="">  }<br class=""><br class="">-  unsigned Size = sizeof(ObjCObjectTypeImpl);<br class="">-  Size += NumProtocols * sizeof(ObjCProtocolDecl *);<br class="">-  void *Mem = Allocate(Size, TypeAlignment);<br class="">+  unsigned size = sizeof(ObjCObjectTypeImpl);<br class="">+  size += typeArgs.size() * sizeof(QualType);<br class="">+  size += protocols.size() * sizeof(ObjCProtocolDecl *);<br class="">+  void *mem = Allocate(size, TypeAlignment);<br class="">  ObjCObjectTypeImpl *T =<br class="">-    new (Mem) ObjCObjectTypeImpl(Canonical, BaseType, Protocols, NumProtocols);<br class="">+    new (mem) ObjCObjectTypeImpl(canonical, baseType, typeArgs, protocols);<br class=""><br class="">  Types.push_back(T);<br class="">  ObjCObjectTypes.InsertNode(T, InsertPos);<br class="">@@ -5921,7 +5961,7 @@ void ASTContext::getObjCEncodingForTypeQ<br class=""><br class="">TypedefDecl *ASTContext::getObjCIdDecl() const {<br class="">  if (!ObjCIdDecl) {<br class="">-    QualType T = getObjCObjectType(ObjCBuiltinIdTy, nullptr, 0);<br class="">+    QualType T = getObjCObjectType(ObjCBuiltinIdTy, { }, { });<br class="">    T = getObjCObjectPointerType(T);<br class="">    ObjCIdDecl = buildImplicitTypedef(T, "id");<br class="">  }<br class="">@@ -5938,7 +5978,7 @@ TypedefDecl *ASTContext::getObjCSelDecl(<br class=""><br class="">TypedefDecl *ASTContext::getObjCClassDecl() const {<br class="">  if (!ObjCClassDecl) {<br class="">-    QualType T = getObjCObjectType(ObjCBuiltinClassTy, nullptr, 0);<br class="">+    QualType T = getObjCObjectType(ObjCBuiltinClassTy, { }, { });<br class="">    T = getObjCObjectPointerType(T);<br class="">    ObjCClassDecl = buildImplicitTypedef(T, "Class");<br class="">  }<br class=""><br class="">Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp<br class="">URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=241542&r1=241541&r2=241542&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)<br class="">+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -125,12 +125,22 @@ break; \<br class="">  if (const PointerType *Ty = QT->getAs<PointerType>()) {<br class="">    QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(),<br class="">                                        ShouldAKA));<br class="">+  } else if (const auto *Ty = QT->getAs<ObjCObjectPointerType>()) {<br class="">+    QT = Context.getObjCObjectPointerType(Desugar(Context, Ty->getPointeeType(),<br class="">+                                                  ShouldAKA));<br class="">  } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {<br class="">    QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(),<br class="">                                                ShouldAKA));<br class="">  } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) {<br class="">    QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(),<br class="">                                                ShouldAKA));<br class="">+  } else if (const auto *Ty = QT->getAs<ObjCObjectType>()) {<br class="">+    if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">According to ubsan, ShouldAKA is evaluated uninitialized here. In fact,</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">only one of the two non-recursive callers bother initializing it, but</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">until now we never read the value within Desugar.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I've gone ahead and fixed this in r241705. Please take a look.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">+      QualType BaseType = Desugar(Context, Ty->getBaseType(), ShouldAKA);<br class="">+      QT = Context.getObjCObjectType(BaseType, Ty->getTypeArgsAsWritten(),<br class="">+                                     llvm::makeArrayRef(Ty->qual_begin(),<br class="">+                                                        Ty->getNumProtocols()));<br class="">+    }<br class="">  }<br class=""><br class="">  return QC.apply(Context, QT);<br class=""><br class="">Modified: cfe/trunk/lib/AST/ASTImporter.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_ASTImporter.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=n2AC0ADY_0lQF-dJwEsPN0FR5jrVgSTFgTpU133WFmU&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/ASTImporter.cpp (original)<br class="">+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -1844,6 +1844,16 @@ QualType ASTNodeImporter::VisitObjCObjec<br class="">  if (ToBaseType.isNull())<br class="">    return QualType();<br class=""><br class="">+  SmallVector<QualType, 4> TypeArgs;<br class="">+  for (auto TypeArg : T->getTypeArgs()) {<br class="">+    QualType ImportedTypeArg = Importer.Import(TypeArg);<br class="">+    if (ImportedTypeArg.isNull())<br class="">+      return QualType();<br class="">+<br class="">+    TypeArgs.push_back(ImportedTypeArg);<br class="">+  }<br class="">+<br class="">+<br class="">  SmallVector<ObjCProtocolDecl *, 4> Protocols;<br class="">  for (auto *P : T->quals()) {<br class="">    ObjCProtocolDecl *Protocol<br class="">@@ -1853,9 +1863,8 @@ QualType ASTNodeImporter::VisitObjCObjec<br class="">    Protocols.push_back(Protocol);<br class="">  }<br class=""><br class="">-  return Importer.getToContext().getObjCObjectType(ToBaseType,<br class="">-                                                   Protocols.data(),<br class="">-                                                   Protocols.size());<br class="">+  return Importer.getToContext().getObjCObjectType(ToBaseType, TypeArgs,<br class="">+                                                   Protocols);<br class="">}<br class=""><br class="">QualType<br class="">@@ -3694,13 +3703,11 @@ bool ASTNodeImporter::ImportDefinition(O<br class=""><br class="">  // If this class has a superclass, import it.<br class="">  if (From->getSuperClass()) {<br class="">-    ObjCInterfaceDecl *Super = cast_or_null<ObjCInterfaceDecl>(<br class="">-                                 Importer.Import(From->getSuperClass()));<br class="">-    if (!Super)<br class="">+    TypeSourceInfo *SuperTInfo = Importer.Import(From->getSuperClassTInfo());<br class="">+    if (!SuperTInfo)<br class="">      return true;<br class="">-    <br class="">-    To->setSuperClass(Super);<br class="">-    To->setSuperClassLoc(Importer.Import(From->getSuperClassLoc()));<br class="">+<br class="">+    To->setSuperClass(SuperTInfo);<br class="">  }<br class=""><br class="">  // Import protocols<br class="">@@ -5367,7 +5374,7 @@ TypeSourceInfo *ASTImporter::Import(Type<br class="">    return nullptr;<br class=""><br class="">  return ToContext.getTrivialTypeSourceInfo(T,<span class="Apple-converted-space"> </span><br class="">-                        FromTSI->getTypeLoc().getLocStart());<br class="">+           Import(FromTSI->getTypeLoc().getLocStart()));<br class="">}<br class=""><br class="">Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) {<br class=""><br class="">Modified: cfe/trunk/lib/AST/DeclObjC.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_DeclObjC.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=XU3iGhIDtlPIfBO2RqAjSTtSPqZZ1mD0CO8yqToVx7w&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/DeclObjC.cpp (original)<br class="">+++ cfe/trunk/lib/AST/DeclObjC.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -259,6 +259,33 @@ ObjCTypeParamList *ObjCInterfaceDecl::ge<br class="">  return nullptr;<br class="">}<br class=""><br class="">+ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const {<br class="">+  // FIXME: Should make sure no callers ever do this.<br class="">+  if (!hasDefinition())<br class="">+    return nullptr;<br class="">+    <br class="">+  if (data().ExternallyCompleted)<br class="">+    LoadExternalDefinition();<br class="">+<br class="">+  if (const ObjCObjectType *superType = getSuperClassType()) {<br class="">+    if (ObjCInterfaceDecl *superDecl = superType->getInterface()) {<br class="">+      if (ObjCInterfaceDecl *superDef = superDecl->getDefinition())<br class="">+        return superDef;<br class="">+<br class="">+      return superDecl;<br class="">+    }<br class="">+  }<br class="">+<br class="">+  return nullptr;<br class="">+}<br class="">+<br class="">+SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {<br class="">+  if (TypeSourceInfo *superTInfo = getSuperClassTInfo())<br class="">+    return superTInfo->getTypeLoc().getLocStart();<br class="">+  <br class="">+  return SourceLocation();<br class="">+}<br class="">+<br class="">/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property<br class="">/// with name 'PropertyId' in the primary class; including those in protocols<br class="">/// (direct or indirect) used by the primary class.<br class=""><br class="">Modified: cfe/trunk/lib/AST/Type.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_Type.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=1GL3DNOTGXR3UzCMLDo2WKzozNUpID5TKELjhY58nZY&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/Type.cpp (original)<br class="">+++ cfe/trunk/lib/AST/Type.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -467,19 +467,56 @@ const RecordType *Type::getAsUnionType()<br class="">}<br class=""><br class="">ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,<br class="">-                               ObjCProtocolDecl * const *Protocols,<br class="">-                               unsigned NumProtocols)<br class="">+                               ArrayRef<QualType> typeArgs,<br class="">+                               ArrayRef<ObjCProtocolDecl *> protocols)<br class="">  : Type(ObjCObject, Canonical, false, false, false, false),<br class="">    BaseType(Base)<span class="Apple-converted-space"> </span><br class="">{<br class="">-  ObjCObjectTypeBits.NumProtocols = NumProtocols;<br class="">-  assert(getNumProtocols() == NumProtocols &&<br class="">+  ObjCObjectTypeBits.NumTypeArgs = typeArgs.size();<br class="">+  assert(getTypeArgsAsWritten().size() == typeArgs.size() &&<br class="">+         "bitfield overflow in type argument count");<br class="">+  ObjCObjectTypeBits.NumProtocols = protocols.size();<br class="">+  assert(getNumProtocols() == protocols.size() &&<br class="">         "bitfield overflow in protocol count");<br class="">-  if (NumProtocols)<br class="">-    memcpy(getProtocolStorage(), Protocols,<br class="">-           NumProtocols * sizeof(ObjCProtocolDecl*));<br class="">+  if (!typeArgs.empty())<br class="">+    memcpy(getTypeArgStorage(), typeArgs.data(),<br class="">+           typeArgs.size() * sizeof(QualType));<br class="">+  if (!protocols.empty())<br class="">+    memcpy(getProtocolStorage(), protocols.data(),<br class="">+           protocols.size() * sizeof(ObjCProtocolDecl*));<br class="">}<br class=""><br class="">+bool ObjCObjectType::isSpecialized() const {<span class="Apple-converted-space"> </span><br class="">+  // If we have type arguments written here, the type is specialized.<br class="">+  if (ObjCObjectTypeBits.NumTypeArgs > 0)<br class="">+    return true;<br class="">+<br class="">+  if (!qual_empty()) {<br class="">+    // Otherwise, check whether the base type is specialized.<br class="">+    if (auto objcObject = getBaseType()->getAs<ObjCObjectType>())<br class="">+      return objcObject->isSpecialized();<br class="">+  }<br class="">+<br class="">+  // Not specialized.<br class="">+  return false;<br class="">+}<br class="">+<br class="">+ArrayRef<QualType> ObjCObjectType::getTypeArgs() const {<br class="">+  // We have type arguments written on this type.<br class="">+  if (isSpecializedAsWritten())<br class="">+    return getTypeArgsAsWritten();<br class="">+<br class="">+  if (!qual_empty()) {<br class="">+    // Look at the base type, which might have type arguments.<br class="">+    if (auto objcObject = getBaseType()->getAs<ObjCObjectType>())<br class="">+      return objcObject->getTypeArgs();<br class="">+  }<br class="">+<br class="">+  // No type arguments.<br class="">+  return { };<br class="">+}<br class="">+<br class="">+<br class="">const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const {<br class="">  // There is no sugar for ObjCObjectType's, just return the canonical<br class="">  // type pointer if it is the right class.  There is no typedef information to<br class="">@@ -2076,15 +2113,20 @@ QualifierCollector::apply(const ASTConte<br class=""><br class="">void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID,<br class="">                                 QualType BaseType,<br class="">-                                 ObjCProtocolDecl * const *Protocols,<br class="">-                                 unsigned NumProtocols) {<br class="">+                                 ArrayRef<QualType> typeArgs,<br class="">+                                 ArrayRef<ObjCProtocolDecl *> protocols) {<br class="">  ID.AddPointer(BaseType.getAsOpaquePtr());<br class="">-  for (unsigned i = 0; i != NumProtocols; i++)<br class="">-    ID.AddPointer(Protocols[i]);<br class="">+  ID.AddInteger(typeArgs.size());<br class="">+  for (auto typeArg : typeArgs)<br class="">+    ID.AddPointer(typeArg.getAsOpaquePtr());<br class="">+  ID.AddInteger(protocols.size());<br class="">+  for (auto proto : protocols)<br class="">+    ID.AddPointer(proto);<br class="">}<br class=""><br class="">void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {<br class="">-  Profile(ID, getBaseType(), qual_begin(), getNumProtocols());<br class="">+  Profile(ID, getBaseType(), getTypeArgs(),<span class="Apple-converted-space"> </span><br class="">+          llvm::makeArrayRef(qual_begin(), getNumProtocols()));<br class="">}<br class=""><br class="">namespace {<br class="">@@ -2495,6 +2537,39 @@ Optional<NullabilityKind> AttributedType<br class="">  return None;<br class="">}<br class=""><br class="">+bool Type::isBlockCompatibleObjCPointerType(ASTContext &ctx) const {<br class="">+  const ObjCObjectPointerType *objcPtr = getAs<ObjCObjectPointerType>();<br class="">+  if (!objcPtr)<br class="">+    return false;<br class="">+<br class="">+  if (objcPtr->isObjCIdType()) {<br class="">+    // id is always okay.<br class="">+    return true;<br class="">+  }<br class="">+<br class="">+  // Blocks are NSObjects.<br class="">+  if (ObjCInterfaceDecl *iface = objcPtr->getInterfaceDecl()) {<br class="">+    if (iface->getIdentifier() != ctx.getNSObjectName())<br class="">+      return false;<br class="">+<br class="">+    // Continue to check qualifiers, below.<br class="">+  } else if (objcPtr->isObjCQualifiedIdType()) {<br class="">+    // Continue to check qualifiers, below.<br class="">+  } else {<br class="">+    return false;<br class="">+  }<br class="">+<br class="">+  // Check protocol qualifiers.<br class="">+  for (ObjCProtocolDecl *proto : objcPtr->quals()) {<br class="">+    // Blocks conform to NSObject and NSCopying.<br class="">+    if (proto->getIdentifier() != ctx.getNSObjectName() &&<br class="">+        proto->getIdentifier() != ctx.getNSCopyingName())<br class="">+      return false;<br class="">+  }<br class="">+<br class="">+  return true;<br class="">+}<br class="">+<br class="">Qualifiers::ObjCLifetime Type::getObjCARCImplicitLifetime() const {<br class="">  if (isObjCARCImplicitlyUnretainedType())<br class="">    return Qualifiers::OCL_ExplicitNone;<br class=""><br class="">Modified: cfe/trunk/lib/AST/TypeLoc.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_TypeLoc.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=IfTP9T4Y6L0KpGg3QceB-PQv6ENhdmq3ojUze1u5EXg&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/TypeLoc.cpp (original)<br class="">+++ cfe/trunk/lib/AST/TypeLoc.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -312,6 +312,22 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLo<br class="">  return TL;<br class="">}<br class=""><br class="">+void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,<span class="Apple-converted-space"> </span><br class="">+                                        SourceLocation Loc) {<br class="">+  setHasBaseTypeAsWritten(true);<br class="">+  setTypeArgsLAngleLoc(Loc);<br class="">+  setTypeArgsRAngleLoc(Loc);<br class="">+  for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {<br class="">+    setTypeArgTInfo(i,<span class="Apple-converted-space"> </span><br class="">+                   Context.getTrivialTypeSourceInfo(<br class="">+                     getTypePtr()->getTypeArgsAsWritten()[i], Loc));<br class="">+  }<br class="">+  setProtocolLAngleLoc(Loc);<br class="">+  setProtocolRAngleLoc(Loc);<br class="">+  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)<br class="">+    setProtocolLoc(i, Loc);<br class="">+}<br class="">+<br class="">void TypeOfTypeLoc::initializeLocal(ASTContext &Context,<br class="">                                       SourceLocation Loc) {<br class="">  TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo><br class=""><br class="">Modified: cfe/trunk/lib/AST/TypePrinter.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_TypePrinter.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=H0S2ebpTK_bGXyzeR0Ppvu5A-9V1eVJmIN2x0XxbOE0&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/TypePrinter.cpp (original)<br class="">+++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -1310,59 +1310,56 @@ void TypePrinter::printObjCInterfaceAfte<br class=""><br class="">void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,<br class="">                                        raw_ostream &OS) {<br class="">-  if (T->qual_empty())<br class="">+  if (T->qual_empty() && T->isUnspecializedAsWritten())<br class="">    return printBefore(T->getBaseType(), OS);<br class=""><br class="">  print(T->getBaseType(), OS, StringRef());<br class="">-  OS << '<';<br class="">-  bool isFirst = true;<br class="">-  for (const auto *I : T->quals()) {<br class="">-    if (isFirst)<br class="">-      isFirst = false;<br class="">-    else<br class="">-      OS << ',';<br class="">-    OS << I->getName();<br class="">+<br class="">+  if (T->isSpecializedAsWritten()) {<br class="">+    bool isFirst = true;<br class="">+    OS << '<';<br class="">+    for (auto typeArg : T->getTypeArgsAsWritten()) {<br class="">+      if (isFirst)<br class="">+        isFirst = false;<br class="">+      else<br class="">+        OS << ",";<br class="">+<br class="">+      print(typeArg, OS, StringRef());<br class="">+    }<br class="">+    OS << '>';<br class="">+  }<br class="">+<br class="">+  if (!T->qual_empty()) {<br class="">+    bool isFirst = true;<br class="">+    OS << '<';<br class="">+    for (const auto *I : T->quals()) {<br class="">+      if (isFirst)<br class="">+        isFirst = false;<br class="">+      else<br class="">+        OS << ',';<br class="">+      OS << I->getName();<br class="">+    }<br class="">+    OS << '>';<br class="">  }<br class="">-  OS << '>';<br class="">+<br class="">  spaceBeforePlaceHolder(OS);<br class="">}<br class="">void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,<br class="">                                        raw_ostream &OS) {<br class="">-  if (T->qual_empty())<br class="">+  if (T->qual_empty() && T->isUnspecializedAsWritten())<br class="">    return printAfter(T->getBaseType(), OS);<br class="">}<br class=""><br class="">void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,<span class="Apple-converted-space"> </span><br class="">                                               raw_ostream &OS) {<br class="">-  T->getPointeeType().getLocalQualifiers().print(OS, Policy,<br class="">-                                                /*appendSpaceIfNonEmpty=*/true);<br class="">+  printBefore(T->getPointeeType(), OS);<br class=""><br class="">-  assert(!T->isObjCSelType());<br class="">-<br class="">-  if (T->isObjCIdType() || T->isObjCQualifiedIdType())<br class="">-    OS << "id";<br class="">-  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())<br class="">-    OS << "Class";<br class="">-  else<br class="">-    OS << T->getInterfaceDecl()->getName();<br class="">-  <br class="">-  if (!T->qual_empty()) {<br class="">-    OS << '<';<br class="">-    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),<span class="Apple-converted-space"> </span><br class="">-                                              E = T->qual_end();<br class="">-         I != E; ++I) {<br class="">-      OS << (*I)->getName();<br class="">-      if (I+1 != E)<br class="">-        OS << ',';<br class="">-    }<br class="">-    OS << '>';<br class="">-  }<br class="">-  <br class="">+  // If we need to print the pointer, print it now.<br class="">  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&<br class="">      !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {<br class="">-    OS << " *"; // Don't forget the implicit pointer.<br class="">-  } else {<br class="">-    spaceBeforePlaceHolder(OS);<br class="">+    if (HasEmptyPlaceHolder)<br class="">+      OS << ' ';<br class="">+    OS << '*';<br class="">  }<br class="">}<br class="">void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,<span class="Apple-converted-space"> </span><br class=""><br class="">Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Parse_ParseDecl.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=BAwJZDS8vN-ag2HMhyaYKF_0JXRaQCt1Ddkc9jkHcS0&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -2886,11 +2886,26 @@ void Parser::ParseDeclarationSpecifiers(<br class="">      DS.SetRangeEnd(Tok.getAnnotationEndLoc());<br class="">      ConsumeToken(); // The typename<br class=""><br class="">-      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'<br class="">-      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an<br class="">-      // Objective-C interface.<br class="">-      if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less) && getLangOpts().ObjC1)<br class="">-        ParseObjCProtocolQualifiers(DS);<br class="">+      // Objective-C supports type arguments and protocol references<br class="">+      // following an Objective-C object pointer type. Handle either<br class="">+      // one of them.<br class="">+      if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less) && getLangOpts().ObjC1) {<br class="">+        ParseObjCTypeArgsOrProtocolQualifiers(<br class="">+          DS, /*warnOnIncompleteProtocols=*/false);<br class="">+<br class="">+        // An Objective-C object pointer followed by type arguments<br class="">+        // can then be followed again by a set of protocol references, e.g.,<br class="">+        // \c NSArray<NSView><NSTextDelegate><br class="">+        if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less)) {<br class="">+          if (DS.getProtocolQualifiers()) {<br class="">+            Diag(Tok, diag::err_objc_type_args_after_protocols)<br class="">+              << SourceRange(DS.getProtocolLAngleLoc(), DS.getLocEnd());<br class="">+            SkipUntil(tok::greater, tok::greatergreater);<br class="">+          } else {<br class="">+            ParseObjCProtocolQualifiers(DS);<br class="">+          }<br class="">+        }<br class="">+      }<br class=""><br class="">      continue;<br class="">    }<br class="">@@ -2997,11 +3012,26 @@ void Parser::ParseDeclarationSpecifiers(<br class="">      DS.SetRangeEnd(Tok.getLocation());<br class="">      ConsumeToken(); // The identifier<br class=""><br class="">-      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'<br class="">-      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an<br class="">-      // Objective-C interface.<br class="">-      if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less) && getLangOpts().ObjC1)<br class="">-        ParseObjCProtocolQualifiers(DS);<br class="">+      // Objective-C supports type arguments and protocol references<br class="">+      // following an Objective-C object pointer type. Handle either<br class="">+      // one of them.<br class="">+      if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less) && getLangOpts().ObjC1) {<br class="">+        ParseObjCTypeArgsOrProtocolQualifiers(<br class="">+          DS, /*warnOnIncompleteProtocols=*/false);<br class="">+<br class="">+        // An Objective-C object pointer followed by type arguments<br class="">+        // can then be followed again by a set of protocol references, e.g.,<br class="">+        // \c NSArray<NSView><NSTextDelegate><br class="">+        if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less)) {<br class="">+          if (DS.getProtocolQualifiers()) {<br class="">+            Diag(Tok, diag::err_objc_type_args_after_protocols)<br class="">+              << SourceRange(DS.getProtocolLAngleLoc(), DS.getLocEnd());<br class="">+            SkipUntil(tok::greater, tok::greatergreater);<br class="">+          } else {<br class="">+            ParseObjCProtocolQualifiers(DS);<br class="">+          }<br class="">+        }<br class="">+      }<br class=""><br class="">      // Need to support trailing type qualifiers (e.g. "id<p> const").<br class="">      // If a type specifier follows, it will be diagnosed elsewhere.<br class=""><br class="">Modified: cfe/trunk/lib/Parse/ParseObjc.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Parse_ParseObjc.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=vEGsy8kcDpYoS1BpVa_2nVT2jgPBq-h0eH_cz9tyzBE&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)<br class="">+++ cfe/trunk/lib/Parse/ParseObjc.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -179,7 +179,7 @@ void Parser::CheckNestedObjCContexts(Sou<br class="">///     @end<br class="">///<br class="">///   objc-superclass:<br class="">-///     ':' identifier<br class="">+///     ':' identifier objc-type-arguments[opt]<br class="">///<br class="">///   objc-class-interface-attributes:<br class="">///     __attribute__((visibility("default")))<br class="">@@ -293,6 +293,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclar<br class="">  // Parse a class interface.<br class="">  IdentifierInfo *superClassId = nullptr;<br class="">  SourceLocation superClassLoc;<br class="">+  DeclSpec superClassDS(AttrFactory);<br class=""><br class="">  if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::colon)) { // a super class is specified.<br class="">    ConsumeToken();<br class="">@@ -311,18 +312,12 @@ Decl *Parser::ParseObjCAtInterfaceDeclar<br class="">    }<br class="">    superClassId = Tok.getIdentifierInfo();<br class="">    superClassLoc = ConsumeToken();<br class="">-  } else if (typeParameterList) {<br class="">-    // An objc-type-parameter-list is ambiguous with an objc-protocol-refs<br class="">-    // in an @interface without a specified superclass, so such classes<br class="">-    // are ill-formed. We have determined that we have an<br class="">-    // objc-type-parameter-list but no superclass, so complain and record<br class="">-    // as if we inherited from NSObject.<br class="">-    SourceLocation insertLoc = PP.getLocForEndOfToken(PrevTokLocation);<br class="">-    Diag(insertLoc, diag::err_objc_parameterized_class_without_base)<br class="">-      << nameId<br class="">-      << FixItHint::CreateInsertion(insertLoc, " : NSObject");<br class="">-    superClassId = PP.getIdentifierInfo("NSObject");<br class="">-    superClassLoc = Tok.getLocation();<br class="">+<br class="">+    // Type arguments for the superclass or protocol conformances.<br class="">+    if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less)) {<br class="">+      ParseObjCTypeArgsOrProtocolQualifiers(superClassDS,<br class="">+                                            /*warnOnIncompleteProtocols=*/true);<br class="">+    }<br class="">  }<br class=""><br class="">  // Next, we need to check for any protocol references.<br class="">@@ -338,6 +333,16 @@ Decl *Parser::ParseObjCAtInterfaceDeclar<br class="">                                    /*ForObjCContainer=*/true,<br class="">                                    &ProtocolIdents[0], ProtocolIdents.size(),<br class="">                                    ProtocolRefs);<br class="">+  } else if (auto protocols = superClassDS.getProtocolQualifiers()) {<br class="">+    // We already parsed the protocols named when we thought we had a<br class="">+    // type argument list (for a specialized superclass). Treat them<br class="">+    // as actual protocol references.<br class="">+    unsigned numProtocols = superClassDS.getNumProtocolQualifiers();<br class="">+    ProtocolRefs.append(protocols, protocols + numProtocols);<br class="">+    ProtocolLocs.append(superClassDS.getProtocolLocs(),<br class="">+                        superClassDS.getProtocolLocs() + numProtocols);<br class="">+    LAngleLoc = superClassDS.getProtocolLAngleLoc();<br class="">+    EndProtoLoc = superClassDS.getLocEnd();<br class="">  } else if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less) &&<br class="">             ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true,<br class="">                                         LAngleLoc, EndProtoLoc)) {<br class="">@@ -348,8 +353,11 @@ Decl *Parser::ParseObjCAtInterfaceDeclar<br class="">    Actions.ActOnTypedefedProtocols(ProtocolRefs, superClassId, superClassLoc);<br class=""><br class="">  Decl *ClsType =<br class="">-    Actions.ActOnStartClassInterface(AtLoc, nameId, nameLoc, typeParameterList,<br class="">-                                     superClassId, superClassLoc,<br class="">+    Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc,<span class="Apple-converted-space"> </span><br class="">+                                     typeParameterList, superClassId,<span class="Apple-converted-space"> </span><br class="">+                                     superClassLoc,<span class="Apple-converted-space"> </span><br class="">+                                     superClassDS.getObjCTypeArgs(),<br class="">+                                     superClassDS.getObjCTypeArgsRange(),<br class="">                                     ProtocolRefs.data(), ProtocolRefs.size(),<br class="">                                     ProtocolLocs.data(),<br class="">                                     EndProtoLoc, attrs.getList());<br class="">@@ -1554,8 +1562,7 @@ bool Parser::ParseObjCProtocolQualifiers<br class="">  SmallVector<Decl *, 8> ProtocolDecl;<br class="">  SmallVector<SourceLocation, 8> ProtocolLocs;<br class="">  bool Result = ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,<br class="">-                                            false,<br class="">-                                            LAngleLoc, EndProtoLoc);<br class="">+                                            false, LAngleLoc, EndProtoLoc);<br class="">  DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),<br class="">                           ProtocolLocs.data(), LAngleLoc);<br class="">  if (EndProtoLoc.isValid())<br class="">@@ -1563,6 +1570,111 @@ bool Parser::ParseObjCProtocolQualifiers<br class="">  return Result;<br class="">}<br class=""><br class="">+/// Parse Objective-C type arguments or protocol qualifiers.<br class="">+///<br class="">+///   objc-type-arguments:<br class="">+///     '<' type-name (',' type-name)* '>'<br class="">+///<br class="">+void Parser::ParseObjCTypeArgsOrProtocolQualifiers(<br class="">+       DeclSpec &DS,<br class="">+       bool warnOnIncompleteProtocols) {<br class="">+  assert(<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::less) && "Not at the start of type args or protocols");<br class="">+  SourceLocation lAngleLoc = ConsumeToken();<br class="">+<br class="">+  // Whether all of the elements we've parsed thus far are single<br class="">+  // identifiers, which might be types or might be protocols.<br class="">+  bool allSingleIdentifiers = true;<br class="">+  SmallVector<IdentifierInfo *, 4> identifiers;<br class="">+  SmallVector<SourceLocation, 4> identifierLocs;<br class="">+<br class="">+  // Parse a list of comma-separated identifiers, bailing out if we<br class="">+  // see something different.<br class="">+  do {<br class="">+    // Parse a single identifier.<br class="">+    if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::identifier) &&<br class="">+        (NextToken().is(tok::comma) ||<br class="">+         NextToken().is(tok::greater) ||<br class="">+         NextToken().is(tok::greatergreater))) {<br class="">+      identifiers.push_back(Tok.getIdentifierInfo());<br class="">+      identifierLocs.push_back(ConsumeToken());<br class="">+      continue;<br class="">+    }<br class="">+<br class="">+    if (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__Tok.is&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=yTMFvVS_Ttkp1ReBjn6-sYjbf9C_z7062ygGlcJvFpM&e=" class="">Tok.is</a>(tok::code_completion)) {<br class="">+      // FIXME: Also include types here.<br class="">+      SmallVector<IdentifierLocPair, 4> identifierLocPairs;<br class="">+      for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {<br class="">+        identifierLocPairs.push_back(IdentifierLocPair(identifiers[i],<span class="Apple-converted-space"> </span><br class="">+                                                       identifierLocs[i]));<br class="">+      }<br class="">+<br class="">+      Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs.data(),<br class="">+                                                 identifierLocPairs.size());<br class="">+      cutOffParsing();<br class="">+      return;<br class="">+    }<br class="">+<br class="">+    allSingleIdentifiers = false;<br class="">+    break;<br class="">+  } while (TryConsumeToken(tok::comma));<br class="">+<br class="">+  // If we parsed an identifier list, semantic analysis sorts out<br class="">+  // whether it refers to protocols or to type arguments.<br class="">+  if (allSingleIdentifiers) {<br class="">+    // Parse the closing '>'.<br class="">+    SourceLocation rAngleLoc;<br class="">+    (void)ParseGreaterThanInTemplateList(rAngleLoc, /*ConsumeLastToken=*/true,<br class="">+                                         /*ObjCGenericList=*/true);<br class="">+<br class="">+    // Let Sema figure out what we parsed.<br class="">+    Actions.actOnObjCTypeArgsOrProtocolQualifiers(getCurScope(),<br class="">+                                                  DS,<br class="">+                                                  lAngleLoc,<br class="">+                                                  identifiers,<br class="">+                                                  identifierLocs,<br class="">+                                                  rAngleLoc,<br class="">+                                                  warnOnIncompleteProtocols);<br class="">+    return;<br class="">+  }<br class="">+<br class="">+  // We syntactically matched a type argument, so commit to parsing<br class="">+  // type arguments.<br class="">+  SmallVector<ParsedType, 4> typeArgs;<br class="">+<br class="">+  // Convert the identifiers into type arguments.<br class="">+  bool invalid = false;<br class="">+  for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {<br class="">+    ParsedType typeArg<br class="">+      = Actions.getTypeName(*identifiers[i], identifierLocs[i], getCurScope());<br class="">+    if (typeArg) {<br class="">+      typeArgs.push_back(typeArg);<br class="">+    } else {<br class="">+      invalid = true;<br class="">+    }<br class="">+  }<br class="">+<br class="">+  // Continue parsing type-names.<br class="">+  do {<br class="">+    TypeResult typeArg = ParseTypeName();<br class="">+    if (typeArg.isUsable()) {<br class="">+      typeArgs.push_back(typeArg.get());<br class="">+    } else {<br class="">+      invalid = true;<br class="">+    }<br class="">+  } while (TryConsumeToken(tok::comma));<br class="">+<br class="">+  // Parse the closing '>'.<br class="">+  SourceLocation rAngleLoc;<br class="">+  (void)ParseGreaterThanInTemplateList(rAngleLoc, /*ConsumeLastToken=*/true,<br class="">+                                       /*ObjCGenericList=*/true);<br class="">+<br class="">+  if (invalid)<br class="">+    return;<br class="">+<br class="">+  // Update the DeclSpec appropriately.<br class="">+  DS.setObjCTypeArgs(lAngleLoc, typeArgs, rAngleLoc);<br class="">+}<br class="">+<br class="">void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,<br class="">                                 BalancedDelimiterTracker &T,<br class="">                                 SmallVectorImpl<Decl *> &AllIvarDecls,<br class=""><br class="">Modified: cfe/trunk/lib/Parse/ParseTentative.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Parse_ParseTentative.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=1C0MKif15s8_dQFJHt9HQu5kqCkzy9_dmAqtoroCyYw&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)<br class="">+++ cfe/trunk/lib/Parse/ParseTentative.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -1384,7 +1384,7 @@ Parser::isCXXDeclarationSpecifier(Parser<br class="">  case_typename:<br class="">    // In Objective-C, we might have a protocol-qualified type.<br class="">    if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {<br class="">-      // Tentatively parse the<span class="Apple-converted-space"> </span><br class="">+      // Tentatively parse the protocol qualifiers.<br class="">      TentativeParsingAction PA(*this);<br class="">      ConsumeToken(); // The type token<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/Sema/DeclSpec.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Sema_DeclSpec.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=6tFZh3J_Ltfq4GbfGpvRAeJRozr9zRN_-rIevMvwk5w&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/DeclSpec.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -893,6 +893,7 @@ bool DeclSpec::SetConstexprSpec(SourceLo<br class="">  return false;<br class="">}<br class=""><br class="">+<br class="">bool DeclSpec::SetConceptSpec(SourceLocation Loc, const char *&PrevSpec,<br class="">                              unsigned &DiagID) {<br class="">  if (Concept_specified) {<br class="">@@ -905,6 +906,16 @@ bool DeclSpec::SetConceptSpec(SourceLoca<br class="">  return false;<br class="">}<br class=""><br class="">+void DeclSpec::setObjCTypeArgs(SourceLocation lAngleLoc,<br class="">+                               ArrayRef<ParsedType> args,<br class="">+                               SourceLocation rAngleLoc) {<br class="">+  ParsedType *argsCopy = new ParsedType[args.size()];<br class="">+  memcpy(argsCopy, args.data(), args.size() * sizeof(ParsedType));<br class="">+  ObjCTypeArgs = llvm::makeArrayRef(argsCopy, args.size());<br class="">+  ObjCTypeArgsLAngleLoc = lAngleLoc;<br class="">+  ObjCTypeArgsRAngleLoc = rAngleLoc;<br class="">+}<br class="">+<br class="">void DeclSpec::setProtocolQualifiers(Decl * const *Protos,<br class="">                                     unsigned NP,<br class="">                                     SourceLocation *ProtoLocs,<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Sema_SemaDeclObjC.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=5HMhz0-kID5PuRqCNZBHMP_g2Ek101AW-wP_zDnbqhs&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -464,6 +464,142 @@ static void diagnoseUseOfProtocols(Sema<br class="">  }<br class="">}<br class=""><br class="">+void Sema::<br class="">+ActOnSuperClassOfClassInterface(Scope *S,<br class="">+                                SourceLocation AtInterfaceLoc,<br class="">+                                ObjCInterfaceDecl *IDecl,<br class="">+                                IdentifierInfo *ClassName,<br class="">+                                SourceLocation ClassLoc,<br class="">+                                IdentifierInfo *SuperName,<br class="">+                                SourceLocation SuperLoc,<br class="">+                                ArrayRef<ParsedType> SuperTypeArgs,<br class="">+                                SourceRange SuperTypeArgsRange) {<br class="">+  // Check if a different kind of symbol declared in this scope.<br class="">+  NamedDecl *PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,<br class="">+                                         LookupOrdinaryName);<br class="">+<br class="">+  if (!PrevDecl) {<br class="">+    // Try to correct for a typo in the superclass name without correcting<br class="">+    // to the class we're defining.<br class="">+    if (TypoCorrection Corrected = CorrectTypo(<br class="">+            DeclarationNameInfo(SuperName, SuperLoc),<br class="">+            LookupOrdinaryName, TUScope,<br class="">+            NULL, llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl),<br class="">+            CTK_ErrorRecovery)) {<br class="">+      diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)<br class="">+                   << SuperName << ClassName);<br class="">+      PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();<br class="">+    }<br class="">+  }<br class="">+<br class="">+  if (declaresSameEntity(PrevDecl, IDecl)) {<br class="">+    Diag(SuperLoc, diag::err_recursive_superclass)<br class="">+      << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);<br class="">+    IDecl->setEndOfDefinitionLoc(ClassLoc);<br class="">+  } else {<br class="">+    ObjCInterfaceDecl *SuperClassDecl =<br class="">+    dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);<br class="">+    QualType SuperClassType;<br class="">+<br class="">+    // Diagnose classes that inherit from deprecated classes.<br class="">+    if (SuperClassDecl) {<br class="">+      (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);<br class="">+      SuperClassType = Context.getObjCInterfaceType(SuperClassDecl);<br class="">+    }<br class="">+<br class="">+    if (PrevDecl && SuperClassDecl == 0) {<br class="">+      // The previous declaration was not a class decl. Check if we have a<br class="">+      // typedef. If we do, get the underlying class type.<br class="">+      if (const TypedefNameDecl *TDecl =<br class="">+          dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {<br class="">+        QualType T = TDecl->getUnderlyingType();<br class="">+        if (T->isObjCObjectType()) {<br class="">+          if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {<br class="">+            SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);<br class="">+            SuperClassType = Context.getTypeDeclType(TDecl);<br class="">+<br class="">+            // This handles the following case:<br class="">+            // @interface NewI @end<br class="">+            // typedef NewI DeprI __attribute__((deprecated("blah")))<br class="">+            // @interface SI : DeprI /* warn here */ @end<br class="">+            (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc);<br class="">+          }<br class="">+        }<br class="">+      }<br class="">+<br class="">+      // This handles the following case:<br class="">+      //<br class="">+      // typedef int SuperClass;<br class="">+      // @interface MyClass : SuperClass {} @end<br class="">+      //<br class="">+      if (!SuperClassDecl) {<br class="">+        Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;<br class="">+        Diag(PrevDecl->getLocation(), diag::note_previous_definition);<br class="">+      }<br class="">+    }<br class="">+<br class="">+    if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {<br class="">+      if (!SuperClassDecl)<br class="">+        Diag(SuperLoc, diag::err_undef_superclass)<br class="">+          << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);<br class="">+      else if (RequireCompleteType(SuperLoc,<br class="">+                                   SuperClassType,<br class="">+                                   diag::err_forward_superclass,<br class="">+                                   SuperClassDecl->getDeclName(),<br class="">+                                   ClassName,<br class="">+                                   SourceRange(AtInterfaceLoc, ClassLoc))) {<br class="">+        SuperClassDecl = 0;<br class="">+        SuperClassType = QualType();<br class="">+      }<br class="">+    }<br class="">+<br class="">+    if (SuperClassType.isNull()) {<br class="">+      assert(!SuperClassDecl && "Failed to set SuperClassType?");<br class="">+      return;<br class="">+    }<br class="">+<br class="">+    // Handle type arguments on the superclass.<br class="">+    TypeSourceInfo *SuperClassTInfo = nullptr;<br class="">+    if (!SuperTypeArgs.empty()) {<br class="">+      // Form declaration specifiers naming this superclass type with<br class="">+      // type arguments.<br class="">+      AttributeFactory attrFactory;<br class="">+      DeclSpec DS(attrFactory);<br class="">+      const char* prevSpec; // unused<br class="">+      unsigned diagID; // unused<br class="">+      TypeSourceInfo *parsedTSInfo<br class="">+        = Context.getTrivialTypeSourceInfo(SuperClassType, SuperLoc);<br class="">+      ParsedType parsedType = CreateParsedType(SuperClassType, parsedTSInfo);<br class="">+<br class="">+      DS.SetTypeSpecType(DeclSpec::TST_typename, SuperLoc, prevSpec, diagID,<br class="">+                         parsedType, Context.getPrintingPolicy());<br class="">+      DS.SetRangeStart(SuperLoc);<br class="">+      DS.SetRangeEnd(SuperLoc);<br class="">+      DS.setObjCTypeArgs(SuperTypeArgsRange.getBegin(),<br class="">+                         SuperTypeArgs,<br class="">+                         SuperTypeArgsRange.getEnd());<br class="">+<br class="">+      // Form the declarator.<br class="">+      Declarator D(DS, Declarator::TypeNameContext);<br class="">+     <br class="">+      TypeResult fullSuperClassType = ActOnTypeName(S, D);<br class="">+      if (!fullSuperClassType.isUsable())<br class="">+        return;<br class="">+<br class="">+      SuperClassType = GetTypeFromParser(fullSuperClassType.get(),<span class="Apple-converted-space"> </span><br class="">+                                         &SuperClassTInfo);<br class="">+    }<br class="">+<br class="">+    if (!SuperClassTInfo) {<br class="">+      SuperClassTInfo = Context.getTrivialTypeSourceInfo(SuperClassType,<span class="Apple-converted-space"> </span><br class="">+                                                         SuperLoc);<br class="">+    }<br class="">+<br class="">+    IDecl->setSuperClass(SuperClassTInfo);<br class="">+    IDecl->setEndOfDefinitionLoc(SuperClassTInfo->getTypeLoc().getLocEnd());<br class="">+  }<br class="">+}<br class="">+<br class="">DeclResult Sema::actOnObjCTypeParam(Scope *S, IdentifierInfo *paramName,<br class="">                                    SourceLocation paramLoc,<br class="">                                    SourceLocation colonLoc,<br class="">@@ -499,7 +635,7 @@ DeclResult Sema::actOnObjCTypeParam(Scop<br class="">      // Form the new type source information.<br class="">      typeBoundInfo = builder.getTypeSourceInfo(Context, typeBound);<br class="">    } else {<br class="">-      // Not a<br class="">+      // Not a valid type bound.<br class="">      Diag(typeBoundInfo->getTypeLoc().getBeginLoc(),<br class="">           diag::err_objc_type_param_bound_nonobject)<br class="">        << typeBound << paramName;<br class="">@@ -669,10 +805,12 @@ static bool checkTypeParamListConsistenc<br class="">}<br class=""><br class="">Decl *Sema::<br class="">-ActOnStartClassInterface(SourceLocation AtInterfaceLoc,<br class="">+ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,<br class="">                         IdentifierInfo *ClassName, SourceLocation ClassLoc,<br class="">                         ObjCTypeParamList *typeParamList,<br class="">                         IdentifierInfo *SuperName, SourceLocation SuperLoc,<br class="">+                         ArrayRef<ParsedType> SuperTypeArgs,<br class="">+                         SourceRange SuperTypeArgsRange,<br class="">                         Decl * const *ProtoRefs, unsigned NumProtoRefs,<br class="">                         const SourceLocation *ProtoLocs,<span class="Apple-converted-space"> </span><br class="">                         SourceLocation EndProtoLoc, AttributeList *AttrList) {<br class="">@@ -767,84 +905,13 @@ ActOnStartClassInterface(SourceLocation<br class="">    IDecl->startDefinition();<br class=""><br class="">  if (SuperName) {<br class="">-    // Check if a different kind of symbol declared in this scope.<br class="">-    PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,<br class="">-                                LookupOrdinaryName);<br class="">-<br class="">-    if (!PrevDecl) {<br class="">-      // Try to correct for a typo in the superclass name without correcting<br class="">-      // to the class we're defining.<br class="">-      if (TypoCorrection Corrected =<br class="">-              CorrectTypo(DeclarationNameInfo(SuperName, SuperLoc),<br class="">-                          LookupOrdinaryName, TUScope, nullptr,<br class="">-                          llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl),<br class="">-                          CTK_ErrorRecovery)) {<br class="">-        diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)<br class="">-                                    << SuperName << ClassName);<br class="">-        PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();<br class="">-      }<br class="">-    }<br class="">-<br class="">-    if (declaresSameEntity(PrevDecl, IDecl)) {<br class="">-      Diag(SuperLoc, diag::err_recursive_superclass)<br class="">-        << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);<br class="">-      IDecl->setEndOfDefinitionLoc(ClassLoc);<br class="">-    } else {<br class="">-      ObjCInterfaceDecl *SuperClassDecl =<br class="">-                                dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);<br class="">-<br class="">-      // Diagnose availability in the context of the @interface.<br class="">-      ContextRAII SavedContext(*this, IDecl);<br class="">-      // Diagnose classes that inherit from deprecated classes.<br class="">-      if (SuperClassDecl)<br class="">-        (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);<br class="">-<br class="">-      if (PrevDecl && !SuperClassDecl) {<br class="">-        // The previous declaration was not a class decl. Check if we have a<br class="">-        // typedef. If we do, get the underlying class type.<br class="">-        if (const TypedefNameDecl *TDecl =<br class="">-              dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {<br class="">-          QualType T = TDecl->getUnderlyingType();<br class="">-          if (T->isObjCObjectType()) {<br class="">-            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {<br class="">-              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);<br class="">-              // This handles the following case:<br class="">-              // @interface NewI @end<br class="">-              // typedef NewI DeprI __attribute__((deprecated("blah")))<br class="">-              // @interface SI : DeprI /* warn here */ @end<br class="">-              (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc);<br class="">-            }<br class="">-          }<br class="">-        }<br class="">-<br class="">-        // This handles the following case:<br class="">-        //<br class="">-        // typedef int SuperClass;<br class="">-        // @interface MyClass : SuperClass {} @end<br class="">-        //<br class="">-        if (!SuperClassDecl) {<br class="">-          Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;<br class="">-          Diag(PrevDecl->getLocation(), diag::note_previous_definition);<br class="">-        }<br class="">-      }<br class="">+    // Diagnose availability in the context of the @interface.<br class="">+    ContextRAII SavedContext(*this, IDecl);<br class=""><br class="">-      if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {<br class="">-        if (!SuperClassDecl)<br class="">-          Diag(SuperLoc, diag::err_undef_superclass)<br class="">-            << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);<br class="">-        else if (RequireCompleteType(SuperLoc,<span class="Apple-converted-space"> </span><br class="">-                                  Context.getObjCInterfaceType(SuperClassDecl),<br class="">-                                     diag::err_forward_superclass,<br class="">-                                     SuperClassDecl->getDeclName(),<br class="">-                                     ClassName,<br class="">-                                     SourceRange(AtInterfaceLoc, ClassLoc))) {<br class="">-          SuperClassDecl = nullptr;<br class="">-        }<br class="">-      }<br class="">-      IDecl->setSuperClass(SuperClassDecl);<br class="">-      IDecl->setSuperClassLoc(SuperLoc);<br class="">-      IDecl->setEndOfDefinitionLoc(SuperLoc);<br class="">-    }<br class="">+    ActOnSuperClassOfClassInterface(S, AtInterfaceLoc, IDecl,<span class="Apple-converted-space"> </span><br class="">+                                    ClassName, ClassLoc,<span class="Apple-converted-space"> </span><br class="">+                                    SuperName, SuperLoc, SuperTypeArgs,<span class="Apple-converted-space"> </span><br class="">+                                    SuperTypeArgsRange);<br class="">  } else { // we have a root class.<br class="">    IDecl->setEndOfDefinitionLoc(ClassLoc);<br class="">  }<br class="">@@ -1091,6 +1158,325 @@ Sema::FindProtocolDeclaration(bool WarnO<br class="">  }<br class="">}<br class=""><br class="">+// Callback to only accept typo corrections that are either<br class="">+// Objective-C protocols or valid Objective-C type arguments.<br class="">+class ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback {<br class="">+  ASTContext &Context;<br class="">+  Sema::LookupNameKind LookupKind;<br class="">+ public:<br class="">+  ObjCTypeArgOrProtocolValidatorCCC(ASTContext &context,<br class="">+                                    Sema::LookupNameKind lookupKind)<br class="">+    : Context(context), LookupKind(lookupKind) { }<br class="">+<br class="">+  bool ValidateCandidate(const TypoCorrection &candidate) override {<br class="">+    // If we're allowed to find protocols and we have a protocol, accept it.<br class="">+    if (LookupKind != Sema::LookupOrdinaryName) {<br class="">+      if (candidate.getCorrectionDeclAs<ObjCProtocolDecl>())<br class="">+        return true;<br class="">+    }<br class="">+<br class="">+    // If we're allowed to find type names and we have one, accept it.<br class="">+    if (LookupKind != Sema::LookupObjCProtocolName) {<br class="">+      // If we have a type declaration, we might accept this result.<br class="">+      if (auto typeDecl = candidate.getCorrectionDeclAs<TypeDecl>()) {<br class="">+        // If we found a tag declaration outside of C++, skip it. This<br class="">+        // can happy because we look for any name when there is no<br class="">+        // bias to protocol or type names.<br class="">+        if (isa<RecordDecl>(typeDecl) && !Context.getLangOpts().CPlusPlus)<br class="">+          return false;<br class="">+<br class="">+        // Make sure the type is something we would accept as a type<br class="">+        // argument.<br class="">+        auto type = Context.getTypeDeclType(typeDecl);<br class="">+        if (type->isObjCObjectPointerType() ||<br class="">+            type->isBlockPointerType() ||<br class="">+            type->isDependentType() ||<br class="">+            type->isObjCObjectType())<br class="">+          return true;<br class="">+<br class="">+        return false;<br class="">+      }<br class="">+<br class="">+      // If we have an Objective-C class type, accept it; there will<br class="">+      // be another fix to add the '*'.<br class="">+      if (candidate.getCorrectionDeclAs<ObjCInterfaceDecl>())<br class="">+        return true;<br class="">+<br class="">+      return false;<br class="">+    }<br class="">+<br class="">+    return false;<br class="">+  }<br class="">+};<br class="">+<br class="">+void Sema::actOnObjCTypeArgsOrProtocolQualifiers(<br class="">+       Scope *S,<br class="">+       DeclSpec &DS,<br class="">+       SourceLocation lAngleLoc,<br class="">+       ArrayRef<IdentifierInfo *> identifiers,<br class="">+       ArrayRef<SourceLocation> identifierLocs,<br class="">+       SourceLocation rAngleLoc,<br class="">+       bool warnOnIncompleteProtocols) {<br class="">+  // Local function that updates the declaration specifiers with<br class="">+  // protocol information.<br class="">+  SmallVector<ObjCProtocolDecl *, 4> protocols;<br class="">+  unsigned numProtocolsResolved = 0;<br class="">+  auto resolvedAsProtocols = [&] {<br class="">+    assert(numProtocolsResolved == identifiers.size() && "Unresolved protocols");<br class="">+    <br class="">+    for (unsigned i = 0, n = protocols.size(); i != n; ++i) {<br class="">+      ObjCProtocolDecl *&proto = protocols[i];<br class="">+      // For an objc container, delay protocol reference checking until after we<br class="">+      // can set the objc decl as the availability context, otherwise check now.<br class="">+      if (!warnOnIncompleteProtocols) {<br class="">+        (void)DiagnoseUseOfDecl(proto, identifierLocs[i]);<br class="">+      }<br class="">+<br class="">+      // If this is a forward protocol declaration, get its definition.<br class="">+      if (!proto->isThisDeclarationADefinition() && proto->getDefinition())<br class="">+        proto = proto->getDefinition();<br class="">+<br class="">+      // If this is a forward declaration and we are supposed to warn in this<br class="">+      // case, do it.<br class="">+      // FIXME: Recover nicely in the hidden case.<br class="">+      ObjCProtocolDecl *forwardDecl = nullptr;<br class="">+      if (warnOnIncompleteProtocols &&<br class="">+          NestedProtocolHasNoDefinition(proto, forwardDecl)) {<br class="">+        Diag(identifierLocs[i], diag::warn_undef_protocolref)<br class="">+          << proto->getDeclName();<br class="">+        Diag(forwardDecl->getLocation(), diag::note_protocol_decl_undefined)<br class="">+          << forwardDecl;<br class="">+      }<br class="">+    }<br class="">+<br class="">+    DS.setProtocolQualifiers((Decl * const *)(protocols.data()),<br class="">+                             protocols.size(),<br class="">+                             const_cast<SourceLocation *>(identifierLocs.data()),<br class="">+                             lAngleLoc);<br class="">+    if (rAngleLoc.isValid())<br class="">+      DS.SetRangeEnd(rAngleLoc);<br class="">+  };<br class="">+<br class="">+  // Attempt to resolve all of the identifiers as protocols.<br class="">+  for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {<br class="">+    ObjCProtocolDecl *proto = LookupProtocol(identifiers[i], identifierLocs[i]);<br class="">+    protocols.push_back(proto);<br class="">+    if (proto)<br class="">+      ++numProtocolsResolved;<br class="">+  }<br class="">+<br class="">+  // If all of the names were protocols, these were protocol qualifiers.<br class="">+  if (numProtocolsResolved == identifiers.size())<br class="">+    return resolvedAsProtocols();<br class="">+<br class="">+  // Attempt to resolve all of the identifiers as type names or<br class="">+  // Objective-C class names. The latter is technically ill-formed,<br class="">+  // but is probably something like \c NSArray<NSView *> missing the<br class="">+  // \c*.<br class="">+  typedef llvm::PointerUnion<TypeDecl *, ObjCInterfaceDecl *> TypeOrClassDecl;<br class="">+  SmallVector<TypeOrClassDecl, 4> typeDecls;<br class="">+  unsigned numTypeDeclsResolved = 0;<br class="">+  for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {<br class="">+    NamedDecl *decl = LookupSingleName(S, identifiers[i], identifierLocs[i],<br class="">+                                       LookupOrdinaryName);<br class="">+    if (!decl) {<br class="">+      typeDecls.push_back(TypeOrClassDecl());<br class="">+      continue;<br class="">+    }<br class="">+<br class="">+    if (auto typeDecl = dyn_cast<TypeDecl>(decl)) {<br class="">+      typeDecls.push_back(typeDecl);<br class="">+      ++numTypeDeclsResolved;<br class="">+      continue;<br class="">+    }<br class="">+<br class="">+    if (auto objcClass = dyn_cast<ObjCInterfaceDecl>(decl)) {<br class="">+      typeDecls.push_back(objcClass);<br class="">+      ++numTypeDeclsResolved;<br class="">+      continue;<br class="">+    }<br class="">+<br class="">+    typeDecls.push_back(TypeOrClassDecl());<br class="">+  }<br class="">+<br class="">+  AttributeFactory attrFactory;<br class="">+<br class="">+  // Local function that forms a reference to the given type or<br class="">+  // Objective-C class declaration.<br class="">+  auto resolveTypeReference = [&](TypeOrClassDecl typeDecl, SourceLocation loc)<span class="Apple-converted-space"> </span><br class="">+                                -> TypeResult {<br class="">+    // Form declaration specifiers. They simply refer to the type.<br class="">+    DeclSpec DS(attrFactory);<br class="">+    const char* prevSpec; // unused<br class="">+    unsigned diagID; // unused<br class="">+    QualType type;<br class="">+    if (auto *actualTypeDecl = typeDecl.dyn_cast<TypeDecl *>())<br class="">+      type = Context.getTypeDeclType(actualTypeDecl);<br class="">+    else<br class="">+      type = Context.getObjCInterfaceType(typeDecl.get<ObjCInterfaceDecl *>());<br class="">+    TypeSourceInfo *parsedTSInfo = Context.getTrivialTypeSourceInfo(type, loc);<br class="">+    ParsedType parsedType = CreateParsedType(type, parsedTSInfo);<br class="">+    DS.SetTypeSpecType(DeclSpec::TST_typename, loc, prevSpec, diagID,<br class="">+                       parsedType, Context.getPrintingPolicy());<br class="">+    // Use the identifier location for the type source range.<br class="">+    DS.SetRangeStart(loc);<br class="">+    DS.SetRangeEnd(loc);<br class="">+<br class="">+    // Form the declarator.<br class="">+    Declarator D(DS, Declarator::TypeNameContext);<br class="">+<br class="">+    // If we have a typedef of an Objective-C class type that is missing a '*',<br class="">+    // add the '*'.<br class="">+    if (type->getAs<ObjCInterfaceType>()) {<br class="">+      SourceLocation starLoc = PP.getLocForEndOfToken(loc);<br class="">+      ParsedAttributes parsedAttrs(attrFactory);<br class="">+      D.AddTypeInfo(DeclaratorChunk::getPointer(/*typeQuals=*/0, starLoc,<br class="">+                                                SourceLocation(),<br class="">+                                                SourceLocation(),<br class="">+                                                SourceLocation(),<br class="">+                                                SourceLocation()),<br class="">+                    parsedAttrs,<br class="">+                    starLoc);<br class="">+<br class="">+      // Diagnose the missing '*'.<br class="">+      Diag(loc, diag::err_objc_type_arg_missing_star)<br class="">+        << type<br class="">+        << FixItHint::CreateInsertion(starLoc, " *");<br class="">+    }<br class="">+<br class="">+    // Convert this to a type.<br class="">+    return ActOnTypeName(S, D);<br class="">+  };<br class="">+<br class="">+  // Local function that updates the declaration specifiers with<br class="">+  // type argument information.<br class="">+  auto resolvedAsTypeDecls = [&] {<br class="">+    assert(numTypeDeclsResolved == identifiers.size() && "Unresolved type decl");<br class="">+    // Map type declarations to type arguments.<br class="">+    SmallVector<ParsedType, 4> typeArgs;<br class="">+    for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {<br class="">+      // Map type reference to a type.<br class="">+      TypeResult type = resolveTypeReference(typeDecls[i], identifierLocs[i]);<br class="">+      if (!type.isUsable())<br class="">+        return;<br class="">+<br class="">+      typeArgs.push_back(type.get());<br class="">+    }<br class="">+<br class="">+    // Record the Objective-C type arguments.<br class="">+    DS.setObjCTypeArgs(lAngleLoc, typeArgs, rAngleLoc);<br class="">+  };<br class="">+<br class="">+  // If all of the identifiers can be resolved as type names or<br class="">+  // Objective-C class names, we have type arguments.<br class="">+  if (numTypeDeclsResolved == identifiers.size())<br class="">+    return resolvedAsTypeDecls();<br class="">+<br class="">+  // Error recovery: some names weren't found, or we have a mix of<br class="">+  // type and protocol names. Go resolve all of the unresolved names<br class="">+  // and complain if we can't find a consistent answer.<br class="">+  LookupNameKind lookupKind = LookupAnyName;<br class="">+  for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {<br class="">+    // If we already have a protocol or type. Check whether it is the<br class="">+    // right thing.<br class="">+    if (protocols[i] || typeDecls[i]) {<br class="">+      // If we haven't figured out whether we want types or protocols<br class="">+      // yet, try to figure it out from this name.<br class="">+      if (lookupKind == LookupAnyName) {<br class="">+        // If this name refers to both a protocol and a type (e.g., \c<br class="">+        // NSObject), don't conclude anything yet.<br class="">+        if (protocols[i] && typeDecls[i])<br class="">+          continue;<br class="">+<br class="">+        // Otherwise, let this name decide whether we'll be correcting<br class="">+        // toward types or protocols.<br class="">+        lookupKind = protocols[i] ? LookupObjCProtocolName<br class="">+                                  : LookupOrdinaryName;<br class="">+        continue;<br class="">+      }<br class="">+<br class="">+      // If we want protocols and we have a protocol, there's nothing<br class="">+      // more to do.<br class="">+      if (lookupKind == LookupObjCProtocolName && protocols[i])<br class="">+        continue;<br class="">+<br class="">+      // If we want types and we have a type declaration, there's<br class="">+      // nothing more to do.<br class="">+      if (lookupKind == LookupOrdinaryName && typeDecls[i])<br class="">+        continue;<br class="">+<br class="">+      // We have a conflict: some names refer to protocols and others<br class="">+      // refer to types.<br class="">+      Diag(identifierLocs[i], diag::err_objc_type_args_and_protocols)<br class="">+        << (protocols[i] != nullptr)<br class="">+        << identifiers[i]<br class="">+        << identifiers[0]<br class="">+        << SourceRange(identifierLocs[0]);<br class="">+<br class="">+      return;<br class="">+    }<br class="">+<br class="">+    // Perform typo correction on the name.<br class="">+    TypoCorrection corrected = CorrectTypo(<br class="">+        DeclarationNameInfo(identifiers[i], identifierLocs[i]), lookupKind, S,<br class="">+        nullptr,<br class="">+        llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(Context,<br class="">+                                                             lookupKind),<br class="">+        CTK_ErrorRecovery);<br class="">+    if (corrected) {<br class="">+      // Did we find a protocol?<br class="">+      if (auto proto = corrected.getCorrectionDeclAs<ObjCProtocolDecl>()) {<br class="">+        diagnoseTypo(corrected,<br class="">+                     PDiag(diag::err_undeclared_protocol_suggest)<br class="">+                       << identifiers[i]);<br class="">+        lookupKind = LookupObjCProtocolName;<br class="">+        protocols[i] = proto;<br class="">+        ++numProtocolsResolved;<br class="">+        continue;<br class="">+      }<br class="">+<br class="">+      // Did we find a type?<br class="">+      if (auto typeDecl = corrected.getCorrectionDeclAs<TypeDecl>()) {<br class="">+        diagnoseTypo(corrected,<br class="">+                     PDiag(diag::err_unknown_typename_suggest)<br class="">+                       << identifiers[i]);<br class="">+        lookupKind = LookupOrdinaryName;<br class="">+        typeDecls[i] = typeDecl;<br class="">+        ++numTypeDeclsResolved;<br class="">+        continue;<br class="">+      }<br class="">+<br class="">+      // Did we find an Objective-C class?<br class="">+      if (auto objcClass = corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {<br class="">+        diagnoseTypo(corrected,<br class="">+                     PDiag(diag::err_unknown_type_or_class_name_suggest)<br class="">+                       << identifiers[i] << true);<br class="">+        lookupKind = LookupOrdinaryName;<br class="">+        typeDecls[i] = objcClass;<br class="">+        ++numTypeDeclsResolved;<br class="">+        continue;<br class="">+      }<br class="">+    }<br class="">+<br class="">+    // We couldn't find anything.<br class="">+    Diag(identifierLocs[i],<br class="">+         (lookupKind == LookupAnyName ? diag::err_objc_type_arg_missing<br class="">+          : lookupKind == LookupObjCProtocolName ? diag::err_undeclared_protocol<br class="">+          : diag::err_unknown_typename))<br class="">+      << identifiers[i];<br class="">+    return;<br class="">+  }<br class="">+<br class="">+  // If all of the names were (corrected to) protocols, these were<br class="">+  // protocol qualifiers.<br class="">+  if (numProtocolsResolved == identifiers.size())<br class="">+    return resolvedAsProtocols();<br class="">+<br class="">+  // Otherwise, all of the names were (corrected to) types.<br class="">+  assert(numTypeDeclsResolved == identifiers.size() && "Not all types?");<br class="">+  return resolvedAsTypeDecls();<br class="">+}<br class="">+<br class="">/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of<br class="">/// a class method in its extension.<br class="">///<br class="">@@ -1374,8 +1760,9 @@ Decl *Sema::ActOnStartClassImplementatio<br class="">                                      true);<br class="">    IDecl->startDefinition();<br class="">    if (SDecl) {<br class="">-      IDecl->setSuperClass(SDecl);<br class="">-      IDecl->setSuperClassLoc(SuperClassLoc);<br class="">+      IDecl->setSuperClass(Context.getTrivialTypeSourceInfo(<br class="">+                             Context.getObjCInterfaceType(SDecl),<br class="">+                             SuperClassLoc));<br class="">      IDecl->setEndOfDefinitionLoc(SuperClassLoc);<br class="">    } else {<br class="">      IDecl->setEndOfDefinitionLoc(ClassLoc);<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Sema_SemaExpr.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=PjI9LyaSz1GxLJ2A0lfF3CKgBDPy6x4edzfDQYSHXJw&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -5826,36 +5826,6 @@ static QualType checkConditionalPointerC<br class="">  return ResultTy;<br class="">}<br class=""><br class="">-/// \brief Returns true if QT is quelified-id and implements 'NSObject' and/or<br class="">-/// 'NSCopying' protocols (and nothing else); or QT is an NSObject and optionally<br class="">-/// implements 'NSObject' and/or NSCopying' protocols (and nothing else).<br class="">-static bool isObjCPtrBlockCompatible(Sema &S, ASTContext &C, QualType QT) {<br class="">-  if (QT->isObjCIdType())<br class="">-    return true;<br class="">-  <br class="">-  const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();<br class="">-  if (!OPT)<br class="">-    return false;<br class="">-<br class="">-  if (ObjCInterfaceDecl *ID = OPT->getInterfaceDecl())<br class="">-    if (ID->getIdentifier() != &C.Idents.get("NSObject"))<br class="">-      return false;<br class="">-  <br class="">-  ObjCProtocolDecl* PNSCopying =<br class="">-    S.LookupProtocol(&C.Idents.get("NSCopying"), SourceLocation());<br class="">-  ObjCProtocolDecl* PNSObject =<br class="">-    S.LookupProtocol(&C.Idents.get("NSObject"), SourceLocation());<br class="">-<br class="">-  for (auto *Proto : OPT->quals()) {<br class="">-    if ((PNSCopying && declaresSameEntity(Proto, PNSCopying)) ||<br class="">-        (PNSObject && declaresSameEntity(Proto, PNSObject)))<br class="">-      ;<br class="">-    else<br class="">-      return false;<br class="">-  }<br class="">-  return true;<br class="">-}<br class="">-<br class="">/// \brief Return the resulting type when the operands are both block pointers.<br class="">static QualType checkConditionalBlockPointerCompatibility(Sema &S,<br class="">                                                          ExprResult &LHS,<br class="">@@ -7008,8 +6978,8 @@ Sema::CheckAssignmentConstraints(QualTyp<br class="">    }<br class=""><br class="">    // Only under strict condition T^ is compatible with an Objective-C pointer.<br class="">-    if (RHSType->isBlockPointerType() &&<br class="">-        isObjCPtrBlockCompatible(*this, Context, LHSType)) {<br class="">+    if (RHSType->isBlockPointerType() &&<span class="Apple-converted-space"> </span><br class="">+        LHSType->isBlockCompatibleObjCPointerType(Context)) {<br class="">      maybeExtendBlockObject(*this, RHS);<br class="">      Kind = CK_BlockPointerToObjCPointerCast;<br class="">      return Compatible;<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Sema_SemaExprObjC.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=DrgL_Fs6uSt4a5Y5wVLx2doG6SouL1aHfHBss32sLYE&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -959,8 +959,10 @@ ExprResult Sema::BuildObjCDictionaryLite<br class="">              LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {<br class="">            ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};<br class="">            QIDNSCopying =<span class="Apple-converted-space"> </span><br class="">-              Context.getObjCObjectType(Context.ObjCBuiltinIdTy,<br class="">-                                        (ObjCProtocolDecl**) PQ,1);<br class="">+              Context.getObjCObjectType(Context.ObjCBuiltinIdTy, { },<br class="">+                                        llvm::makeArrayRef(<br class="">+                                          (ObjCProtocolDecl**) PQ,<br class="">+                                          1));<br class="">            QIDNSCopying = Context.getObjCObjectPointerType(QIDNSCopying);<br class="">          }<br class="">        }<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaType.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Sema_SemaType.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=nmk77CvM1vVjbm3YspxFjmdJE-zJHQkRCdT1utd181E&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -738,6 +738,160 @@ static void diagnoseAndRemoveTypeQualifi<br class="">  }<br class="">}<br class=""><br class="">+/// Apply Objective-C type arguments to the given type.<br class="">+static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type,<br class="">+                                  ArrayRef<ParsedType> typeArgs,<br class="">+                                  SourceRange typeArgsRange) {<br class="">+  // We can only apply type arguments to an Objective-C class type.<br class="">+  const auto *objcObjectType = type->getAs<ObjCObjectType>();<br class="">+  if (!objcObjectType || !objcObjectType->getInterface()) {<br class="">+    S.Diag(loc, diag::err_objc_type_args_non_class)<br class="">+      << type<br class="">+      << typeArgsRange;<br class="">+    return type;<br class="">+  }<br class="">+<br class="">+  // The class type must be parameterized.<br class="">+  ObjCInterfaceDecl *objcClass = objcObjectType->getInterface();<br class="">+  ObjCTypeParamList *typeParams = objcClass->getTypeParamList();<br class="">+  if (!typeParams) {<br class="">+    S.Diag(loc, diag::err_objc_type_args_non_parameterized_class)<br class="">+      << objcClass->getDeclName()<br class="">+      << FixItHint::CreateRemoval(typeArgsRange);<br class="">+    return type;<br class="">+  }<br class="">+<br class="">+  // The type must not already be specialized.<br class="">+  if (objcObjectType->isSpecialized()) {<br class="">+    S.Diag(loc, diag::err_objc_type_args_specialized_class)<br class="">+      << type<br class="">+      << FixItHint::CreateRemoval(typeArgsRange);<br class="">+    return type;<br class="">+  }<br class="">+<br class="">+  // Make sure that we have the right number of type arguments.<br class="">+  if (typeArgs.size() != typeParams->size()) {<br class="">+    S.Diag(loc, diag::err_objc_type_args_wrong_arity)<br class="">+      << (typeArgs.size() < typeParams->size())<br class="">+      << objcClass->getDeclName()<br class="">+      << (unsigned)typeArgs.size()<br class="">+      << (unsigned)typeParams->size();<br class="">+    S.Diag(objcClass->getLocation(), diag::note_previous_decl)<br class="">+      << objcClass;<br class="">+    return type;<br class="">+  }<br class="">+<br class="">+  // Check the type arguments.<br class="">+  SmallVector<QualType, 4> finalTypeArgs;<br class="">+  for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) {<br class="">+    TypeSourceInfo *typeArgInfo = nullptr;<br class="">+    QualType typeArg = S.GetTypeFromParser(typeArgs[i], &typeArgInfo);<br class="">+    finalTypeArgs.push_back(typeArg);<br class="">+<br class="">+    // Objective-C object pointer types must be substitutable for the bounds.<br class="">+    if (const auto *typeArgObjC = typeArg->getAs<ObjCObjectPointerType>()) {<br class="">+      // Retrieve the bound.<br class="">+      ObjCTypeParamDecl *typeParam = typeParams->begin()[i];<br class="">+      QualType bound = typeParam->getUnderlyingType();<br class="">+      const auto *boundObjC = bound->getAs<ObjCObjectPointerType>();<br class="">+<br class="">+      // Determine whether the type argument is substitutable for the bound.<br class="">+      if (typeArgObjC->isObjCIdType()) {<br class="">+        // When the type argument is 'id', the only acceptable type<br class="">+        // parameter bound is 'id'.<br class="">+        if (boundObjC->isObjCIdType())<br class="">+          continue;<br class="">+      } else if (S.Context.canAssignObjCInterfaces(boundObjC, typeArgObjC)) {<br class="">+        // Otherwise, we follow the assignability rules.<br class="">+        continue;<br class="">+      }<br class="">+<br class="">+      // Diagnose the mismatch.<br class="">+      S.Diag(typeArgInfo->getTypeLoc().getLocStart(),<br class="">+             diag::err_objc_type_arg_does_not_match_bound)<br class="">+        << typeArg << bound << typeParam->getDeclName();<br class="">+      S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)<br class="">+        << typeParam->getDeclName();<br class="">+<br class="">+      return type;<br class="">+    }<br class="">+<br class="">+    // Block pointer types are permitted for unqualified 'id' bounds.<br class="">+    if (typeArg->isBlockPointerType()) {<br class="">+      // Retrieve the bound.<br class="">+      ObjCTypeParamDecl *typeParam = typeParams->begin()[i];<br class="">+      QualType bound = typeParam->getUnderlyingType();<br class="">+      if (bound->isBlockCompatibleObjCPointerType(S.Context))<br class="">+        continue;<br class="">+<br class="">+      // Diagnose the mismatch.<br class="">+      S.Diag(typeArgInfo->getTypeLoc().getLocStart(),<br class="">+             diag::err_objc_type_arg_does_not_match_bound)<br class="">+        << typeArg << bound << typeParam->getDeclName();<br class="">+      S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)<br class="">+        << typeParam->getDeclName();<br class="">+<br class="">+      return type;<br class="">+    }<br class="">+<br class="">+    // Dependent types will be checked at instantiation time.<br class="">+    if (typeArg->isDependentType()) {<br class="">+      continue;<br class="">+    }<br class="">+<br class="">+    // Diagnose non-id-compatible type arguments.<br class="">+    S.Diag(typeArgInfo->getTypeLoc().getLocStart(),<br class="">+           diag::err_objc_type_arg_not_id_compatible)<br class="">+      << typeArg<br class="">+      << typeArgInfo->getTypeLoc().getSourceRange();<br class="">+    return type;<br class="">+  }<br class="">+<br class="">+  // Success. Form the specialized type.<br class="">+  return S.Context.getObjCObjectType(type, finalTypeArgs, { });<br class="">+}<br class="">+<br class="">+/// Apply Objective-C protocol qualifiers to the given type.<br class="">+static QualType applyObjCProtocolQualifiers(<br class="">+                  Sema &S, SourceLocation loc, SourceRange range, QualType type,<br class="">+                  ArrayRef<ObjCProtocolDecl *> protocols,<br class="">+                  const SourceLocation *protocolLocs) {<br class="">+  ASTContext &ctx = S.Context;<br class="">+  if (const ObjCObjectType *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){<br class="">+    // FIXME: Check for protocols to which the class type is already<br class="">+    // known to conform.<br class="">+<br class="">+    return ctx.getObjCObjectType(objT->getBaseType(),<br class="">+                                 objT->getTypeArgsAsWritten(),<br class="">+                                 protocols);<br class="">+  }<br class="">+<br class="">+  if (type->isObjCObjectType()) {<br class="">+    // Silently overwrite any existing protocol qualifiers.<br class="">+    // TODO: determine whether that's the right thing to do.<br class="">+<br class="">+    // FIXME: Check for protocols to which the class type is already<br class="">+    // known to conform.<br class="">+    return ctx.getObjCObjectType(type, { }, protocols);<br class="">+  }<br class="">+<br class="">+  // id<protocol-list><br class="">+  if (type->isObjCIdType()) {<br class="">+    type = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, { }, protocols);<br class="">+    return ctx.getObjCObjectPointerType(type);<br class="">+  }<br class="">+<br class="">+  // Class<protocol-list><br class="">+  if (type->isObjCClassType()) {<br class="">+    type = ctx.getObjCObjectType(ctx.ObjCBuiltinClassTy, { }, protocols);<br class="">+    return ctx.getObjCObjectPointerType(type);<br class="">+  }<br class="">+<br class="">+  S.Diag(loc, diag::err_invalid_protocol_qualifiers)<br class="">+    << range;<br class="">+  return type;<br class="">+}<br class="">+<br class="">/// \brief Convert the specified declspec to the appropriate type<br class="">/// object.<br class="">/// \param state Specifies the declarator containing the declaration specifier<br class="">@@ -803,9 +957,10 @@ static QualType ConvertDeclSpecToType(Ty<br class="">  case DeclSpec::TST_unspecified:<br class="">    // "<proto1,proto2>" is an objc qualified ID with a missing id.<br class="">    if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {<br class="">-      Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy,<br class="">-                                         (ObjCProtocolDecl*const*)PQ,<br class="">-                                         DS.getNumProtocolQualifiers());<br class="">+      Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy, { },<br class="">+                                         llvm::makeArrayRef(<br class="">+                                           (ObjCProtocolDecl*const*)PQ,<br class="">+                                           DS.getNumProtocolQualifiers()));<br class="">      Result = Context.getObjCObjectPointerType(Result);<br class="">      break;<br class="">    }<br class="">@@ -967,37 +1122,8 @@ static QualType ConvertDeclSpecToType(Ty<br class="">           DS.getTypeSpecSign() == 0 &&<br class="">           "Can't handle qualifiers on typedef names yet!");<br class="">    Result = S.GetTypeFromParser(DS.getRepAsType());<br class="">-    if (Result.isNull())<br class="">+    if (Result.isNull()) {<br class="">      declarator.setInvalidType(true);<br class="">-    else if (DeclSpec::ProtocolQualifierListTy PQ<br class="">-               = DS.getProtocolQualifiers()) {<br class="">-      if (const ObjCObjectType *ObjT = Result->getAs<ObjCObjectType>()) {<br class="">-        // Silently drop any existing protocol qualifiers.<br class="">-        // TODO: determine whether that's the right thing to do.<br class="">-        if (ObjT->getNumProtocols())<br class="">-          Result = ObjT->getBaseType();<br class="">-<br class="">-        if (DS.getNumProtocolQualifiers())<br class="">-          Result = Context.getObjCObjectType(Result,<br class="">-                                             (ObjCProtocolDecl*const*) PQ,<br class="">-                                             DS.getNumProtocolQualifiers());<br class="">-      } else if (Result->isObjCIdType()) {<br class="">-        // id<protocol-list><br class="">-        Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy,<br class="">-                                           (ObjCProtocolDecl*const*) PQ,<br class="">-                                           DS.getNumProtocolQualifiers());<br class="">-        Result = Context.getObjCObjectPointerType(Result);<br class="">-      } else if (Result->isObjCClassType()) {<br class="">-        // Class<protocol-list><br class="">-        Result = Context.getObjCObjectType(Context.ObjCBuiltinClassTy,<br class="">-                                           (ObjCProtocolDecl*const*) PQ,<br class="">-                                           DS.getNumProtocolQualifiers());<br class="">-        Result = Context.getObjCObjectPointerType(Result);<br class="">-      } else {<br class="">-        S.Diag(DeclLoc, diag::err_invalid_protocol_qualifiers)<br class="">-          << DS.getSourceRange();<br class="">-        declarator.setInvalidType(true);<br class="">-      }<br class="">    } else if (S.getLangOpts().OpenCL) {<br class="">      if (const AtomicType *AT = Result->getAs<AtomicType>()) {<br class="">        const BuiltinType *BT = AT->getValueType()->getAs<BuiltinType>();<br class="">@@ -1022,6 +1148,21 @@ static QualType ConvertDeclSpecToType(Ty<br class="">          declarator.setInvalidType(true);<br class="">        }<br class="">      }<br class="">+    } else {<br class="">+      // Apply Objective-C type arguments.<br class="">+      if (DS.hasObjCTypeArgs()) {<br class="">+        Result = applyObjCTypeArgs(S, DeclLoc, Result, DS.getObjCTypeArgs(),<br class="">+                                   DS.getObjCTypeArgsRange());<br class="">+      }<br class="">+<br class="">+      // Apply Objective-C protocol qualifiers.<br class="">+      if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {<br class="">+        Result = applyObjCProtocolQualifiers(<br class="">+                   S, DeclLoc, DS.getSourceRange(), Result,<br class="">+                   llvm::makeArrayRef((ObjCProtocolDecl * const *)PQ,<br class="">+                                      DS.getNumProtocolQualifiers()),<br class="">+                   DS.getProtocolLocs());<br class="">+      }<br class="">    }<br class=""><br class="">    // TypeQuals handled by caller.<br class="">@@ -4138,18 +4279,33 @@ namespace {<br class="">        Visit(TL.getBaseLoc());<br class="">      }<br class=""><br class="">+      // Type arguments.<br class="">+      if (TL.getNumTypeArgs() > 0) {<br class="">+        assert(TL.getNumTypeArgs() == DS.getObjCTypeArgs().size());<br class="">+        TL.setTypeArgsLAngleLoc(DS.getObjCTypeArgsLAngleLoc());<br class="">+        TL.setTypeArgsRAngleLoc(DS.getObjCTypeArgsRAngleLoc());<br class="">+        for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {<br class="">+          TypeSourceInfo *typeArgInfo = nullptr;<br class="">+          (void)Sema::GetTypeFromParser(DS.getObjCTypeArgs()[i], &typeArgInfo);<br class="">+          TL.setTypeArgTInfo(i, typeArgInfo);<br class="">+        }<br class="">+      } else {<br class="">+        TL.setTypeArgsLAngleLoc(SourceLocation());<br class="">+        TL.setTypeArgsRAngleLoc(SourceLocation());<br class="">+      }<br class="">+<br class="">      // Protocol qualifiers.<br class="">      if (DS.getProtocolQualifiers()) {<br class="">        assert(TL.getNumProtocols() > 0);<br class="">        assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());<br class="">-        TL.setLAngleLoc(DS.getProtocolLAngleLoc());<br class="">-        TL.setRAngleLoc(DS.getSourceRange().getEnd());<br class="">+        TL.setProtocolLAngleLoc(DS.getProtocolLAngleLoc());<br class="">+        TL.setProtocolRAngleLoc(DS.getSourceRange().getEnd());<br class="">        for (unsigned i = 0, e = DS.getNumProtocolQualifiers(); i != e; ++i)<br class="">          TL.setProtocolLoc(i, DS.getProtocolLocs()[i]);<br class="">      } else {<br class="">        assert(TL.getNumProtocols() == 0);<br class="">-        TL.setLAngleLoc(SourceLocation());<br class="">-        TL.setRAngleLoc(SourceLocation());<br class="">+        TL.setProtocolLAngleLoc(SourceLocation());<br class="">+        TL.setProtocolRAngleLoc(SourceLocation());<br class="">      }<br class="">    }<br class="">    void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ASTReader.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=0DQx_wxEk_IL_tDbUIjVf0CfU20jZ210L_3kRVMT8Gs&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -5263,11 +5263,15 @@ QualType ASTReader::readTypeRecord(unsig<br class="">  case TYPE_OBJC_OBJECT: {<br class="">    unsigned Idx = 0;<br class="">    QualType Base = readType(*Loc.F, Record, Idx);<br class="">+    unsigned NumTypeArgs = Record[Idx++];<br class="">+    SmallVector<QualType, 4> TypeArgs;<br class="">+    for (unsigned I = 0; I != NumTypeArgs; ++I)<br class="">+      TypeArgs.push_back(readType(*Loc.F, Record, Idx));<br class="">    unsigned NumProtos = Record[Idx++];<br class="">    SmallVector<ObjCProtocolDecl*, 4> Protos;<br class="">    for (unsigned I = 0; I != NumProtos; ++I)<br class="">      Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));<br class="">-    return Context.getObjCObjectType(Base, Protos.data(), NumProtos);<br class="">+    return Context.getObjCObjectType(Base, TypeArgs, Protos);<br class="">  }<br class=""><br class="">  case TYPE_OBJC_OBJECT_POINTER: {<br class="">@@ -5646,8 +5650,12 @@ void TypeLocReader::VisitObjCInterfaceTy<br class="">}<br class="">void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {<br class="">  TL.setHasBaseTypeAsWritten(Record[Idx++]);<br class="">-  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));<br class="">-  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));<br class="">+  TL.setTypeArgsLAngleLoc(ReadSourceLocation(Record, Idx));<br class="">+  TL.setTypeArgsRAngleLoc(ReadSourceLocation(Record, Idx));<br class="">+  for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)<br class="">+    TL.setTypeArgTInfo(i, Reader.GetTypeSourceInfo(F, Record, Idx));<br class="">+  TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));<br class="">+  TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));<br class="">  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)<br class="">    TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));<br class="">}<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ASTReaderDecl.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=hWpT2VdHyu0CPDDKuRDml_FPdfvGFkheRH1vp9LLrXc&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -953,8 +953,7 @@ void ASTDeclReader::VisitObjCInterfaceDe<br class="">    ObjCInterfaceDecl::DefinitionData &Data = ID->data();<br class=""><br class="">    // Read the superclass.<br class="">-    Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);<br class="">-    Data.SuperClassLoc = ReadSourceLocation(Record, Idx);<br class="">+    Data.SuperClassTInfo = GetTypeSourceInfo(Record, Idx);<br class=""><br class="">    Data.EndLoc = ReadSourceLocation(Record, Idx);<br class="">    Data.HasDesignatedInitializers = Record[Idx++];<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ASTWriter.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=LhNjGoGANsb4alQba4jz15oIGInxy7_A09w1nBiJQi0&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -421,6 +421,9 @@ void ASTTypeWriter::VisitObjCInterfaceTy<br class=""><br class="">void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {<br class="">  Writer.AddTypeRef(T->getBaseType(), Record);<br class="">+  Record.push_back(T->getTypeArgs().size());<br class="">+  for (auto TypeArg : T->getTypeArgs())<br class="">+    Writer.AddTypeRef(TypeArg, Record);<br class="">  Record.push_back(T->getNumProtocols());<br class="">  for (const auto *I : T->quals())<br class="">    Writer.AddDeclRef(I, Record);<br class="">@@ -648,8 +651,12 @@ void TypeLocWriter::VisitObjCInterfaceTy<br class="">}<br class="">void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {<br class="">  Record.push_back(TL.hasBaseTypeAsWritten());<br class="">-  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);<br class="">-  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);<br class="">+  Writer.AddSourceLocation(TL.getTypeArgsLAngleLoc(), Record);<br class="">+  Writer.AddSourceLocation(TL.getTypeArgsRAngleLoc(), Record);<br class="">+  for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)<br class="">+    Writer.AddTypeSourceInfo(TL.getTypeArgTInfo(i), Record);<br class="">+  Writer.AddSourceLocation(TL.getProtocolLAngleLoc(), Record);<br class="">+  Writer.AddSourceLocation(TL.getProtocolRAngleLoc(), Record);<br class="">  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)<br class="">    Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);<br class="">}<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Serialization_ASTWriterDecl.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=5Hqq4fpGChQ0rXjl_Db6k8DzTVGtXlUBTPzf7CK_phI&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -604,8 +604,7 @@ void ASTDeclWriter::VisitObjCInterfaceDe<br class="">    // Write the DefinitionData<br class="">    ObjCInterfaceDecl::DefinitionData &Data = D->data();<br class=""><br class="">-    Writer.AddDeclRef(D->getSuperClass(), Record);<br class="">-    Writer.AddSourceLocation(D->getSuperClassLoc(), Record);<br class="">+    Writer.AddTypeSourceInfo(D->getSuperClassTInfo(), Record);<br class="">    Writer.AddSourceLocation(D->getEndOfDefinitionLoc(), Record);<br class="">    Record.push_back(Data.HasDesignatedInitializers);<br class=""><br class=""><br class="">Added: cfe/trunk/test/Index/annotate-parameterized-classes.m<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_Index_annotate-2Dparameterized-2Dclasses.m-3Frev-3D241542-26view-3Dauto&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=BsVzvL0hII97s9fHZVMC1MnPbu_qPB7fgh0f0agAZD0&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-parameterized-classes.m?rev=241542&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/Index/annotate-parameterized-classes.m (added)<br class="">+++ cfe/trunk/test/Index/annotate-parameterized-classes.m Mon Jul  6 22:57:35 2015<br class="">@@ -0,0 +1,42 @@<br class="">+@protocol NSObject<br class="">+@end<br class="">+<br class="">+@interface NSObject<br class="">+@end<br class="">+<br class="">+@interface A<T : id, U : NSObject *> : NSObject<br class="">+@end<br class="">+<br class="">+@interface A<T : id, U : NSObject *> (Cat1)<br class="">+@end<br class="">+<br class="">+typedef A<id<NSObject>, NSObject *> ASpecialization1;<br class="">+<br class="">+@interface B<T : id, U : NSObject *> : A<T, U><br class="">+@end<br class="">+<br class="">+// RUN: c-index-test -test-annotate-tokens=%s:7:1:9:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-INTERFACE-DECL %s<br class="">+// CHECK-INTERFACE-DECL: Identifier: "T" [7:14 - 7:15] TemplateTypeParameter=T:7:14<br class="">+// FIXME: Should be a type reference<br class="">+// CHECK-INTERFACE-DECL: Identifier: "id" [7:18 - 7:20] TemplateTypeParameter=T:7:14<br class="">+// CHECK-INTERFACE-DECL: Identifier: "U" [7:22 - 7:23] TemplateTypeParameter=U:7:22<br class="">+// FIXME: Should be a class reference<br class="">+// CHECK-INTERFACE-DECL: Identifier: "NSObject" [7:26 - 7:34] TemplateTypeParameter=U:7:22<br class="">+<br class="">+// RUN: c-index-test -test-annotate-tokens=%s:10:1:12:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-CATEGORY-DECL %s<br class="">+// CHECK-CATEGORY-DECL: Identifier: "T" [10:14 - 10:15] TemplateTypeParameter=T:10:14<span class="Apple-converted-space"> </span><br class="">+// FIXME: Should be a type reference<br class="">+// CHECK-CATEGORY-DECL: Identifier: "id" [10:18 - 10:20] TemplateTypeParameter=T:10:14<br class="">+// CHECK-CATEGORY-DECL: Identifier: "U" [10:22 - 10:23] TemplateTypeParameter=U:10:22<br class="">+// FIXME: Should be a class reference<br class="">+// CHECK-CATEGORY-DECL: Identifier: "NSObject" [10:26 - 10:34] TemplateTypeParameter=U:10:22<br class="">+<br class="">+// RUN: c-index-test -test-annotate-tokens=%s:13:1:14:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-SPECIALIZATION %s<br class="">+// CHECK-SPECIALIZATION: Identifier: "id" [13:11 - 13:13] TypeRef=id:0:0<br class="">+// CHECK-SPECIALIZATION: Identifier: "NSObject" [13:14 - 13:22] ObjCProtocolRef=NSObject:1:11<br class="">+// CHECK-SPECIALIZATION: Identifier: "NSObject" [13:25 - 13:33] ObjCClassRef=NSObject:4:12<br class="">+<br class="">+// RUN: c-index-test -test-annotate-tokens=%s:15:1:16:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-SUPER %s<br class="">+// CHECK-SUPER: Identifier: "A" [15:40 - 15:41] ObjCSuperClassRef=A:7:12<br class="">+// CHECK-SUPER: Identifier: "T" [15:42 - 15:43] TypeRef=T:15:14<br class="">+// CHECK-SUPER: Identifier: "U" [15:45 - 15:46] TypeRef=U:15:22<br class=""><br class="">Modified: cfe/trunk/test/Index/complete-method-decls.m<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_Index_complete-2Dmethod-2Ddecls.m-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=4QpbhJ50CIVi_8MnrKq_ASuYUA945f_PDBEwNgFF-fc&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-method-decls.m?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/Index/complete-method-decls.m (original)<br class="">+++ cfe/trunk/test/Index/complete-method-decls.m Mon Jul  6 22:57:35 2015<br class="">@@ -208,8 +208,7 @@ typedef A *MyObjectRef;<br class=""><br class="">// RUN: c-index-test -code-completion-at=%s:85:2 %s | FileCheck -check-prefix=CHECK-CLASSTY %s<br class="">// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text Class<P1>}{RightParen )}{TypedText meth}<br class="">-// FIXME: It should be "MyObject <P1> *""<br class="">-// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text A<P1> *}{RightParen )}{TypedText meth2}<br class="">+// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text MyObject<P1> *}{RightParen )}{TypedText meth2}<br class="">// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text MyObjectRef}{RightParen )}{TypedText meth3}<br class=""><br class="">// RUN: c-index-test -code-completion-at=%s:93:2 %s | FileCheck -check-prefix=CHECK-NULLABILITY %s<br class=""><br class="">Modified: cfe/trunk/test/PCH/objc_parameterized_classes.m<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_PCH_objc-5Fparameterized-5Fclasses.m-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=dV_nE1NotQDeIwU9z00Ztkxg7ToytghdYSoB5U_wMHk&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_parameterized_classes.m?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/PCH/objc_parameterized_classes.m (original)<br class="">+++ cfe/trunk/test/PCH/objc_parameterized_classes.m Mon Jul  6 22:57:35 2015<br class="">@@ -19,6 +19,8 @@ __attribute__((objc_root_class))<br class="">@interface PC1<T, U : NSObject *> (Cat1)<br class="">@end<br class=""><br class="">+typedef PC1<id, NSObject *> PC1Specialization1;<br class="">+<br class="">#else<br class=""><br class="">@interface PC1<T : NSObject *, // expected-error{{type bound 'NSObject *' for type parameter 'T' conflicts with implicit bound 'id}}<br class="">@@ -27,4 +29,6 @@ __attribute__((objc_root_class))<br class=""> // expected-note@15{{type parameter 'U' declared here}}<br class="">@end<br class=""><br class="">+typedef PC1Specialization1<id, NSObject *> PC1Specialization2; // expected-error{{type arguments cannot be applied to already-specialized class type 'PC1Specialization1' (aka 'PC1<id,NSObject *>')}}<br class="">+<br class="">#endif<br class=""><br class="">Modified: cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_Parser_objcxx11-2Dprotocol-2Din-2Dtemplate.mm-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=G9FgyntMk2Z4xHKQ_0QWTZ7UBquJQmNxe8MgKpqK884&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm (original)<br class="">+++ cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm Mon Jul  6 22:57:35 2015<br class="">@@ -4,12 +4,7 @@<br class="">template<class T> class vector {};<br class="">@protocol P @end<br class=""><br class="">-#if __cplusplus >= 201103L<br class="">-  // expected-no-diagnostics<br class="">-#else<br class="">-  // expected-error@14{{a space is required between consecutive right angle brackets}}<br class="">-  // expected-error@15{{a space is required between consecutive right angle brackets}}<br class="">-#endif<br class="">+// expected-no-diagnostics<br class=""><br class="">vector<id<P>> v;<br class="">vector<vector<id<P>>> v2;<br class=""><br class="">Modified: cfe/trunk/test/SemaObjC/interface-1.m<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_SemaObjC_interface-2D1.m-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=ARH7dN5fJMs7r2I18GIDykWQzZ4rfvfYiL-XTJa3jR4&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/interface-1.m?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/SemaObjC/interface-1.m (original)<br class="">+++ cfe/trunk/test/SemaObjC/interface-1.m Mon Jul  6 22:57:35 2015<br class="">@@ -3,7 +3,7 @@<br class=""><br class="">@interface NSWhatever :<br class="">NSObject     // expected-error {{cannot find interface declaration for 'NSObject'}}<br class="">-<NSCopying>  // expected-error {{cannot find protocol declaration for 'NSCopying'}}<br class="">+<NSCopying>  // expected-error {{no type or protocol named 'NSCopying'}}<br class="">@end<br class=""><br class=""><br class=""><br class="">Modified: cfe/trunk/test/SemaObjC/parameterized_classes.m<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_SemaObjC_parameterized-5Fclasses.m-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=whOplcaw4bkCD5A5CmDw-ba_NCxq-OMZL49SSY3iAbQ&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/parameterized_classes.m?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/SemaObjC/parameterized_classes.m (original)<br class="">+++ cfe/trunk/test/SemaObjC/parameterized_classes.m Mon Jul  6 22:57:35 2015<br class="">@@ -1,13 +1,16 @@<br class="">-// RUN: %clang_cc1 %s -verify<br class="">+// RUN: %clang_cc1 -fblocks %s -verify<br class=""><br class="">-@protocol NSObject<br class="">+@protocol NSObject // expected-note{{'NSObject' declared here}}<br class="">+@end<br class="">+<br class="">+@protocol NSCopying // expected-note{{'NSCopying' declared here}}<br class="">@end<br class=""><br class="">__attribute__((objc_root_class))<br class="">@interface NSObject <NSObject> // expected-note{{'NSObject' defined here}}<br class="">@end<br class=""><br class="">-@interface NSString : NSObject<br class="">+@interface NSString : NSObject <NSCopying><br class="">@end<br class=""><br class="">// --------------------------------------------------------------------------<br class="">@@ -15,13 +18,14 @@ __attribute__((objc_root_class))<br class="">// --------------------------------------------------------------------------<br class=""><br class="">// Parse type parameters with a bound<br class="">-@interface PC1<T, U : NSObject*> : NSObject<br class="">+@interface PC1<T, U : NSObject*> : NSObject // expected-note{{'PC1' declared here}}<br class="">// expected-note@-1{{type parameter 'T' declared here}}<br class="">// expected-note@-2{{type parameter 'U' declared here}}<br class="">+// expected-note@-3{{type parameter 'U' declared here}}<br class="">@end<br class=""><br class="">// Parse a type parameter with a bound that terminates in '>>'.<br class="">-@interface PC2<T : id<NSObject>> : NSObject // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}<br class="">+@interface PC2<T : id<NSObject>> : NSObject<br class="">@end<br class=""><br class="">// Parse multiple type parameters.<br class="">@@ -29,11 +33,11 @@ __attribute__((objc_root_class))<br class="">@end<br class=""><br class="">// Parse multiple type parameters--grammatically ambiguous with protocol refs.<br class="">-@interface PC4<T, U, V> : NSObject<br class="">+@interface PC4<T, U, V> : NSObject // expected-note 2{{'PC4' declared here}}<br class="">@end<br class=""><br class="">// Parse a type parameter list without a superclass.<br class="">-@interface PC5<T : id> // expected-error{{parameterized Objective-C class 'PC5' must have a superclass}}<br class="">+@interface PC5<T : id><br class="">@end<br class=""><br class="">// Parse a type parameter with name conflicts.<br class="">@@ -92,6 +96,7 @@ __attribute__((objc_root_class))<br class=""><br class="">// Parameterized forward declaration a class that is not parameterized.<br class="">@class NSObject<T>; // expected-error{{forward declaration of non-parameterized class 'NSObject' cannot have type parameters}}<br class="">+// expected-note@-1{{'NSObject' declared here}}<br class=""><br class="">// Parameterized forward declaration preceding the definition (that is<br class="">// not parameterized).<br class="">@@ -190,3 +195,131 @@ void test_PC20_unspecialized(PC20 *pc20)<br class="">  ip = [pc20 extMethod: 0]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'X' (aka 'id')}}<br class="">  [pc20 extMethod: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'Y' (aka 'NSObject *')}}<br class="">}<br class="">+<br class="">+// --------------------------------------------------------------------------<br class="">+// Parsing type arguments.<br class="">+// --------------------------------------------------------------------------<br class="">+<br class="">+typedef NSString * ObjCStringRef; // expected-note{{'ObjCStringRef' declared here}}<br class="">+<br class="">+// Type arguments with a mix of identifiers and type-names.<br class="">+typedef PC4<id, NSObject *, NSString *> typeArgs1;<br class="">+<br class="">+// Type arguments with only identifiers.<br class="">+typedef PC4<id, id, id> typeArgs2;<br class="">+<br class="">+// Type arguments with only identifiers; one is ambiguous (resolved as<br class="">+// types).<br class="">+typedef PC4<NSObject, id, id> typeArgs3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}}<br class="">+<br class="">+// Type arguments with only identifiers; one is ambiguous (resolved as<br class="">+// protocol qualifiers).<br class="">+typedef PC4<NSObject, NSCopying> protocolQuals1;<br class="">+<br class="">+// Type arguments and protocol qualifiers.<br class="">+typedef PC4<id, NSObject *, id><NSObject, NSCopying> typeArgsAndProtocolQuals1;<br class="">+<br class="">+// Type arguments and protocol qualifiers in the wrong order.<br class="">+typedef PC4<NSObject, NSCopying><id, NSObject *, id> typeArgsAndProtocolQuals2; // expected-error{{protocol qualifiers must precede type arguments}}<br class="">+<br class="">+// Type arguments and protocol qualifiers (identifiers).<br class="">+typedef PC4<id, NSObject, id><NSObject, NSCopying> typeArgsAndProtocolQuals3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}}<br class="">+<br class="">+// Typo correction: protocol bias.<br class="">+typedef PC4<NSCopying, NSObjec> protocolQuals2; // expected-error{{cannot find protocol declaration for 'NSObjec'; did you mean 'NSObject'?}}<br class="">+<br class="">+// Typo correction: type bias.<br class="">+typedef PC4<id, id, NSObjec> typeArgs4; // expected-error{{unknown class name 'NSObjec'; did you mean 'NSObject'?}}<br class="">+// expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}}<br class="">+<br class="">+// Typo correction: bias set by correction itself to a protocol.<br class="">+typedef PC4<NSObject, NSObject, NSCopyin> protocolQuals3; // expected-error{{cannot find protocol declaration for 'NSCopyin'; did you mean 'NSCopying'?}}<br class="">+<br class="">+// Typo correction: bias set by correction itself to a type.<br class="">+typedef PC4<NSObject, NSObject, ObjCStringref> typeArgs5; // expected-error{{unknown type name 'ObjCStringref'; did you mean 'ObjCStringRef'?}}<br class="">+// expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}}<br class="">+// expected-error@-2{{type argument 'NSObject' must be a pointer (requires a '*')}}<br class="">+<br class="">+// Type/protocol conflict.<br class="">+typedef PC4<NSCopying, ObjCStringRef> typeArgsProtocolQualsConflict1; // expected-error{{angle brackets contain both a type ('ObjCStringRef') and a protocol ('NSCopying')}}<br class="">+<br class="">+// Handling the '>>' in type argument lists.<br class="">+typedef PC4<id<NSCopying>, NSObject *, id<NSObject>> typeArgs6;<br class="">+<br class="">+// --------------------------------------------------------------------------<br class="">+// Checking type arguments.<br class="">+// --------------------------------------------------------------------------<br class="">+<br class="">+@interface PC15<T : id, U : NSObject *, V : id<NSCopying>> : NSObject<br class="">+// expected-note@-1{{type parameter 'V' declared here}}<br class="">+// expected-note@-2{{type parameter 'V' declared here}}<br class="">+// expected-note@-3{{type parameter 'U' declared here}}<br class="">+@end<br class="">+<br class="">+typedef PC4<NSString *> tooFewTypeArgs1; // expected-error{{too few type arguments for class 'PC4' (have 1, expected 3)}}<br class="">+<br class="">+typedef PC4<NSString *, NSString *, NSString *, NSString *> tooManyTypeArgs1; // expected-error{{too many type arguments for class 'PC4' (have 4, expected 3)}}<br class="">+<br class="">+typedef PC15<int (^)(int, int), // block pointers as 'id'<br class="">+             NSString *, // subclass<br class="">+             NSString *> typeArgs7; // class that conforms to the protocol<br class="">+<br class="">+typedef PC15<NSObject *, NSObject *, id<NSCopying>> typeArgs8;<br class="">+<br class="">+typedef PC15<NSObject *, NSObject *,<br class="">+             NSObject *> typeArgs8b; // expected-error{{type argument 'NSObject *' does not satisy the bound ('id<NSCopying>') of type parameter 'V'}}<br class="">+<br class="">+typedef PC15<id,<br class="">+             id,  // expected-error{{type argument 'id' does not satisy the bound ('NSObject *') of type parameter 'U'}}<br class="">+             id> typeArgs9;<br class="">+<br class="">+typedef PC15<id, NSObject *,<br class="">+             id> typeArgs10; // expected-error{{type argument 'id' does not satisy the bound ('id<NSCopying>') of type parameter 'V'}}<br class="">+<br class="">+typedef PC15<id,<br class="">+             int (^)(int, int), // okay<br class="">+             id<NSCopying, NSObject>> typeArgs11;<br class="">+<br class="">+typedef PC15<id, NSString *, int (^)(int, int)> typeArgs12; // okay<br class="">+<br class="">+typedef NSObject<id, id> typeArgs13; // expected-error{{type arguments cannot be applied to non-parameterized class 'NSObject'}}<br class="">+<br class="">+typedef id<id, id> typeArgs14; // expected-error{{type arguments cannot be applied to non-class type 'id'}}<br class="">+<br class="">+typedef PC1<NSObject *, NSString *> typeArgs15;<br class="">+<br class="">+typedef PC1<NSObject *, NSString *><NSCopying> typeArgsAndProtocolQuals4;<br class="">+<br class="">+typedef typeArgs15<NSCopying> typeArgsAndProtocolQuals5;<br class="">+<br class="">+typedef typeArgs15<NSObject *, NSString *> typeArgs16; // expected-error{{type arguments cannot be applied to already-specialized class type 'typeArgs15' (aka 'PC1<NSObject *,NSString *>')}}<br class="">+<br class="">+typedef typeArgs15<NSObject> typeArgsAndProtocolQuals6;<br class="">+<br class="">+void testSpecializedTypePrinting() {<br class="">+  int *ip;<br class="">+<br class="">+  ip = (typeArgs15*)0; // expected-warning{{'typeArgs15 *' (aka 'PC1<NSObject *,NSString *> *')}}<br class="">+  ip = (typeArgsAndProtocolQuals4*)0; // expected-warning{{'typeArgsAndProtocolQuals4 *' (aka 'PC1<NSObject *,NSString *><NSCopying> *')}}<br class="">+  ip = (typeArgsAndProtocolQuals5*)0; // expected-warning{{'typeArgsAndProtocolQuals5 *' (aka 'typeArgs15<NSCopying> *')}}<br class="">+  ip = (typeArgsAndProtocolQuals6)0; // expected-error{{used type 'typeArgsAndProtocolQuals6' (aka 'typeArgs15<NSObject>')}}<br class="">+  ip = (typeArgsAndProtocolQuals6*)0;// expected-warning{{'typeArgsAndProtocolQuals6 *' (aka 'typeArgs15<NSObject> *')}}<br class="">+}<br class="">+<br class="">+// --------------------------------------------------------------------------<br class="">+// Specialized superclasses<br class="">+// --------------------------------------------------------------------------<br class="">+@interface PC21<T : NSObject *> : PC1<T, T><br class="">+@end<br class="">+<br class="">+@interface PC22<T : NSObject *> : PC1<T> // expected-error{{too few type arguments for class 'PC1' (have 1, expected 2)}}<br class="">+@end<br class="">+<br class="">+@interface PC23<T : NSObject *> : PC1<T, U> // expected-error{{unknown type name 'U'}}<br class="">+@end<br class="">+<br class="">+@interface PC24<T> : PC1<T, T> // expected-error{{type argument 'T' (aka 'id') does not satisy the bound ('NSObject *') of type parameter 'U'}}<br class="">+@end<br class="">+<br class="">+@interface NSFoo : PC1<NSObject *, NSObject *> // okay<br class="">+@end<br class=""><br class="">Added: cfe/trunk/test/SemaObjCXX/parameterized_classes.mm<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_SemaObjCXX_parameterized-5Fclasses.mm-3Frev-3D241542-26view-3Dauto&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=zf5lyfwSyl16i5QtpoV5FUiNNNPUZQ7_wELtgtJT64E&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/parameterized_classes.mm?rev=241542&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/SemaObjCXX/parameterized_classes.mm (added)<br class="">+++ cfe/trunk/test/SemaObjCXX/parameterized_classes.mm Mon Jul  6 22:57:35 2015<br class="">@@ -0,0 +1,26 @@<br class="">+// RUN: %clang_cc1 -std=c++11 %s -verify<br class="">+<br class="">+// expected-no-diagnostics<br class="">+@protocol NSObject<br class="">+@end<br class="">+<br class="">+@protocol NSCopying<br class="">+@end<br class="">+<br class="">+__attribute__((objc_root_class))<br class="">+@interface NSObject <NSObject><br class="">+@end<br class="">+<br class="">+@interface NSString : NSObject<br class="">+@end<br class="">+<br class="">+// --------------------------------------------------------------------------<br class="">+// Parsing parameterized classes.<br class="">+// --------------------------------------------------------------------------<br class="">+@interface PC1<T, U, V> : NSObject<br class="">+@end<br class="">+<br class="">+// --------------------------------------------------------------------------<br class="">+// Parsing type arguments.<br class="">+// --------------------------------------------------------------------------<br class="">+typedef PC1<::NSString *, NSString *, id<NSCopying>> typeArgs1;<br class=""><br class="">Modified: cfe/trunk/tools/libclang/CIndex.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_tools_libclang_CIndex.cpp-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=8sFoxxElo2rtHAF3IrrqLQujWqW5PUhpmUzpFrHhUoE&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br class="">+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jul  6 22:57:35 2015<br class="">@@ -1021,6 +1021,9 @@ bool CursorVisitor::VisitObjCCategoryDec<br class="">                                   TU)))<br class="">    return true;<br class=""><br class="">+  if (VisitObjCTypeParamList(ND->getTypeParamList()))<br class="">+    return true;<br class="">+<br class="">  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();<br class="">  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),<br class="">         E = ND->protocol_end(); I != E; ++I, ++PL)<br class="">@@ -1080,12 +1083,37 @@ bool CursorVisitor::VisitObjCPropertyDec<br class="">  return false;<br class="">}<br class=""><br class="">+bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {<br class="">+  if (!typeParamList)<br class="">+    return false;<br class="">+<br class="">+  for (auto *typeParam : *typeParamList) {<br class="">+    // Visit the type parameter.<br class="">+    if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))<br class="">+      return true;<br class="">+<br class="">+    // Visit the bound, if it's explicit.<br class="">+    if (typeParam->hasExplicitBound()) {<br class="">+      if (auto TInfo = typeParam->getTypeSourceInfo()) {<br class="">+        if (Visit(TInfo->getTypeLoc()))<br class="">+          return true;<br class="">+      }<br class="">+    }<br class="">+  }<br class="">+<br class="">+  return false;<br class="">+}<br class="">+<br class="">bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {<br class="">  if (!D->isThisDeclarationADefinition()) {<br class="">    // Forward declaration is treated like a reference.<br class="">    return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));<br class="">  }<br class=""><br class="">+  // Objective-C type parameters.<br class="">+  if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))<br class="">+    return true;<br class="">+<br class="">  // Issue callbacks for super class.<br class="">  if (D->getSuperClass() &&<br class="">      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),<br class="">@@ -1093,6 +1121,10 @@ bool CursorVisitor::VisitObjCInterfaceDe<br class="">                                        TU)))<br class="">    return true;<br class=""><br class="">+  if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())<br class="">+    if (Visit(SuperClassTInfo->getTypeLoc()))<br class="">+      return true;<br class="">+<br class="">  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();<br class="">  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),<br class="">         E = D->protocol_end(); I != E; ++I, ++PL)<br class="">@@ -1486,6 +1518,11 @@ bool CursorVisitor::VisitObjCObjectTypeL<br class="">  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))<br class="">    return true;<br class=""><br class="">+  for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {<br class="">+    if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))<br class="">+      return true;<br class="">+  }<br class="">+<br class="">  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {<br class="">    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),<br class="">                                        TU)))<br class="">@@ -4411,7 +4448,12 @@ static enum CXChildVisitResult GetCursor<br class="">    *BestCursor = getTypeRefedCallExprCursor(*BestCursor);<br class="">    return CXChildVisit_Recurse;<br class="">  }<br class="">-  <br class="">+<br class="">+  // If we already have an Objective-C superclass reference, don't<br class="">+  // update it further.<br class="">+  if (BestCursor->kind == CXCursor_ObjCSuperClassRef)<br class="">+    return CXChildVisit_Break;<br class="">+<br class="">  *BestCursor = cursor;<br class="">  return CXChildVisit_Recurse;<br class="">}<br class=""><br class="">Modified: cfe/trunk/tools/libclang/CursorVisitor.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_tools_libclang_CursorVisitor.h-3Frev-3D241542-26r1-3D241541-26r2-3D241542-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=oCJwtqxwHCbr4AKCzvgeHCHna8AAan9IEjId5RQyfmc&s=tA16pOaWgs9v4TnWKtAU9UhF_Mddo0-lvZX7_YkcyK8&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CursorVisitor.h?rev=241542&r1=241541&r2=241542&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/tools/libclang/CursorVisitor.h (original)<br class="">+++ cfe/trunk/tools/libclang/CursorVisitor.h Mon Jul  6 22:57:35 2015<br class="">@@ -222,6 +222,7 @@ public:<br class="">  bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);<br class="">  bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);<br class="">  bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);<br class="">+  bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList);<br class="">  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);<br class="">  bool VisitObjCImplDecl(ObjCImplDecl *D);<br class="">  bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@cs.uiuc.edu" class="">cfe-commits@cs.uiuc.edu</a><br class="">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</blockquote></div></blockquote></div><br class=""></div></body></html>