<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>